Lines Matching +full:pci +full:- +full:dev

1 /*-
2 * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
36 * PCI-specific implementation for the BHNDB bridge driver.
38 * Provides support for bridging from a PCI parent bus to a BHND-compatible
39 * bus (e.g. bcma or siba) via a Broadcom PCI core configured in end-point
42 * This driver handles all initial generic host-level PCI interactions with a
43 * PCI/PCIe bridge core operating in endpoint mode. Once the bridged bhnd(4)
44 * bus has been enumerated, this driver works in tandem with a core-specific
45 * bhnd_pci_hostb driver to manage the PCI core.
56 #include <dev/pci/pcireg.h>
57 #include <dev/pci/pcivar.h>
59 #include <dev/bhnd/bhnd.h>
60 #include <dev/bhnd/bhndreg.h>
62 #include <dev/bhnd/bhnd_erom.h>
63 #include <dev/bhnd/bhnd_eromvar.h>
65 #include <dev/bhnd/siba/sibareg.h>
67 #include <dev/bhnd/cores/pci/bhnd_pcireg.h>
83 static bhnd_devclass_t bhndb_expected_pci_devclass(device_t dev);
84 static bool bhndb_is_pcie_attached(device_t dev);
86 static int bhndb_enable_pci_clocks(device_t dev);
87 static int bhndb_disable_pci_clocks(device_t dev);
89 static int bhndb_pci_compat_setregwin(device_t dev,
92 static int bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
107 device_t dev, bhnd_devclass_t pci_devclass);
138 BHNDB_PCI_CORE(PCI, bhndb_pci_quirks),
161 device_t dev; /**< bridge device */ member
162 device_t pci_dev; /**< parent PCI device */
164 struct bhnd_core_info hostb_core; /**< PCI bridge core info */
169 struct bhnd_core_info *cores; /**< erom-owned core table */
183 /* Backplane interrupt flags must be routed via siba-specific
185 * PCI configuration register is unsupported. */
190 /* All PCI core revisions require the SRSH work-around */
196 /* All PCIe-G1 core revisions require the SRSH work-around */
214 if (bhnd_core_matches(ci, &entry->match)) in bhndb_pci_find_core()
238 if ((qtable = entry->quirks) == NULL) in bhndb_pci_get_core_quirks()
244 if (!bhnd_chip_matches(cid, &q->chip_desc)) in bhndb_pci_get_core_quirks()
247 if (!bhnd_core_matches(ci, &q->core_desc)) in bhndb_pci_get_core_quirks()
250 quirks |= q->quirks; in bhndb_pci_get_core_quirks()
259 * Verifies that the parent is a PCI/PCIe device.
262 bhndb_pci_probe(device_t dev) in bhndb_pci_probe() argument
268 devclass_t pci, bus_devclass; in bhndb_pci_probe() local
273 /* Our parent must be a PCI/PCIe device. */ in bhndb_pci_probe()
274 pci = devclass_find("pci"); in bhndb_pci_probe()
275 parent = device_get_parent(dev); in bhndb_pci_probe()
280 /* The bus device class may inherit from 'pci' */ in bhndb_pci_probe()
285 if (bus_devclass == pci) in bhndb_pci_probe()
289 if (bus_devclass != pci) in bhndb_pci_probe()
293 if ((error = bhndb_enable_pci_clocks(dev))) in bhndb_pci_probe()
297 hostb_devclass = bhndb_expected_pci_devclass(dev); in bhndb_pci_probe()
298 if ((error = bhndb_pci_probe_alloc(&probe, dev, hostb_devclass))) in bhndb_pci_probe()
302 if ((entry = bhndb_pci_find_core(&probe->hostb_core)) == NULL) { in bhndb_pci_probe()
307 device_set_desc(dev, "PCI-BHND bridge"); in bhndb_pci_probe()
309 /* fall-through */ in bhndb_pci_probe()
316 bhndb_disable_pci_clocks(dev); in bhndb_pci_probe()
331 if (pci_msi_count(sc->parent) < BHNDB_PCI_MSI_COUNT) in bhndb_pci_alloc_msi()
336 if ((error = pci_alloc_msi(sc->parent, &count))) { in bhndb_pci_alloc_msi()
337 device_printf(sc->dev, "failed to allocate MSI interrupts: " in bhndb_pci_alloc_msi()
344 pci_release_msi(sc->parent); in bhndb_pci_alloc_msi()
353 bhndb_pci_attach(device_t dev) in bhndb_pci_attach() argument
364 sc = device_get_softc(dev); in bhndb_pci_attach()
365 sc->dev = dev; in bhndb_pci_attach()
366 sc->parent = device_get_parent(dev); in bhndb_pci_attach()
367 sc->pci_devclass = bhndb_expected_pci_devclass(dev); in bhndb_pci_attach()
368 sc->pci_quirks = 0; in bhndb_pci_attach()
369 sc->set_regwin = NULL; in bhndb_pci_attach()
376 /* Enable PCI bus mastering */ in bhndb_pci_attach()
377 pci_enable_busmaster(sc->parent); in bhndb_pci_attach()
380 if ((error = bhndb_enable_pci_clocks(sc->dev))) in bhndb_pci_attach()
384 error = bhndb_pci_probe_alloc(&probe, dev, sc->pci_devclass); in bhndb_pci_attach()
388 sc->pci_quirks = bhndb_pci_get_core_quirks(&probe->cid, in bhndb_pci_attach()
389 &probe->hostb_core); in bhndb_pci_attach()
392 if (probe->cid.chip_type == BHND_CHIPTYPE_SIBA) { in bhndb_pci_attach()
393 sc->set_regwin = bhndb_pci_compat_setregwin; in bhndb_pci_attach()
395 sc->set_regwin = bhndb_pci_fast_setregwin; in bhndb_pci_attach()
399 * Fix up our PCI base address in the SPROM shadow, if necessary. in bhndb_pci_attach()
402 * that map the PCI core. in bhndb_pci_attach()
407 /* Set up PCI interrupt handling */ in bhndb_pci_attach()
408 if (bhndb_pci_alloc_msi(sc, &sc->msi_count) == 0) { in bhndb_pci_attach()
412 device_printf(dev, "Using MSI interrupts on %s\n", in bhndb_pci_attach()
413 device_get_nameunit(sc->parent)); in bhndb_pci_attach()
415 sc->msi_count = 0; in bhndb_pci_attach()
418 device_printf(dev, "Using INTx interrupts on %s\n", in bhndb_pci_attach()
419 device_get_nameunit(sc->parent)); in bhndb_pci_attach()
422 sc->isrc = bhndb_alloc_intr_isrc(sc->parent, irq_rid, 0, RM_MAX_END, 1, in bhndb_pci_attach()
424 if (sc->isrc == NULL) { in bhndb_pci_attach()
425 device_printf(sc->dev, "failed to allocate interrupt " in bhndb_pci_attach()
438 cid = probe->cid; in bhndb_pci_attach()
439 erom_class = probe->erom_class; in bhndb_pci_attach()
440 hostb_core = probe->hostb_core; in bhndb_pci_attach()
452 error = bhndb_attach(dev, &cid, cores, ncores, &hostb_core, erom_class); in bhndb_pci_attach()
461 bus_attach_children(dev); in bhndb_pci_attach()
468 device_delete_children(dev); in bhndb_pci_attach()
470 if (sc->isrc != NULL) in bhndb_pci_attach()
471 bhndb_free_intr_isrc(sc->isrc); in bhndb_pci_attach()
473 if (sc->msi_count > 0) in bhndb_pci_attach()
474 pci_release_msi(sc->parent); in bhndb_pci_attach()
482 bhndb_disable_pci_clocks(sc->dev); in bhndb_pci_attach()
484 pci_disable_busmaster(sc->parent); in bhndb_pci_attach()
492 bhndb_pci_detach(device_t dev) in bhndb_pci_detach() argument
497 sc = device_get_softc(dev); in bhndb_pci_detach()
500 if ((error = bus_generic_detach(dev))) in bhndb_pci_detach()
504 if ((error = bhndb_generic_detach(dev))) in bhndb_pci_detach()
508 if ((error = bhndb_disable_pci_clocks(sc->dev))) in bhndb_pci_detach()
512 bhndb_free_intr_isrc(sc->isrc); in bhndb_pci_detach()
515 if (sc->msi_count > 0) in bhndb_pci_detach()
516 pci_release_msi(sc->parent); in bhndb_pci_detach()
518 /* Disable PCI bus mastering */ in bhndb_pci_detach()
519 pci_disable_busmaster(sc->parent); in bhndb_pci_detach()
542 device_printf(sc->dev, "found SPROM (%ju bytes)\n", in bhndb_pci_add_children()
548 child = BUS_ADD_CHILD(sc->dev, in bhndb_pci_add_children()
549 BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY, "bhnd_nvram", -1); in bhndb_pci_add_children()
551 device_printf(sc->dev, "failed to add sprom device\n"); in bhndb_pci_add_children()
558 dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE; in bhndb_pci_add_children()
563 device_printf(sc->dev, in bhndb_pci_add_children()
579 bres = sc->bhndb.bus_res; in bhndb_pci_sprom_regwin()
580 cfg = bres->cfg; in bhndb_pci_sprom_regwin()
582 sprom_win = bhndb_regwin_find_type(cfg->register_windows, in bhndb_pci_sprom_regwin()
599 r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, sprom_win); in bhndb_pci_sprom_addr()
602 return (rman_get_start(r) + sprom_win->win_offset); in bhndb_pci_sprom_addr()
619 sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4); in bhndb_pci_sprom_size()
638 device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl); in bhndb_pci_sprom_size()
645 sprom_sz = MIN(sprom_sz, sprom_win->win_size); in bhndb_pci_sprom_size()
651 * Return the host resource providing a static mapping of the PCI core's
654 * @param sc bhndb PCI driver state.
655 * @param offset The required readable offset within the PCI core
658 * @param[out] res On success, the host resource containing our PCI
663 * @retval ENXIO if a valid static register window mapping the PCI core
674 win = bhndb_regwin_find_core(sc->bhndb.bus_res->cfg->register_windows, in bhndb_pci_get_core_regs()
675 sc->pci_devclass, 0, BHND_PORT_DEVICE, 0, 0, offset, size); in bhndb_pci_get_core_regs()
677 device_printf(sc->dev, "missing PCI core register window\n"); in bhndb_pci_get_core_regs()
682 r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, win); in bhndb_pci_get_core_regs()
684 device_printf(sc->dev, "missing PCI core register resource\n"); in bhndb_pci_get_core_regs()
688 KASSERT(offset >= win->d.core.offset, ("offset %#jx outside of " in bhndb_pci_get_core_regs()
692 *res_offset = win->win_offset + (offset - win->d.core.offset); in bhndb_pci_get_core_regs()
698 * Write a 1, 2, or 4 byte data item to the PCI core's registers at @p offset.
700 * @param sc bhndb PCI driver state.
715 panic("no PCI register window mapping %#jx+%#x: %d", in bhndb_pci_write_core()
735 * Read a 1, 2, or 4 byte data item from the PCI core's registers
738 * @param sc bhndb PCI driver state.
751 panic("no PCI register window mapping %#jx+%#x: %d", in bhndb_pci_read_core()
768 * Fix-up power on defaults for SPROM-less devices.
770 * On SPROM-less devices, the PCI(e) cores will be initialized with their their
771 * Power-on-Reset defaults; this can leave the BHND_PCI_SRSH_PI value pointing
772 * to the wrong backplane address. This value is used by the PCI core when
774 * map the PCI core's register block, and backplane address space.
776 * When translating accesses via these BAR0 regions, the PCI bridge determines
777 * the base address of the PCI core by concatenating:
781 * 15:12 value of BHND_PCI_SRSH_PI from the PCI core's SPROM shadow
782 * 11:0 bits [11:0] of the PCI bus address
784 * For example, on a PCI_V0 device, the following PCI core register offsets are
787 * [BAR0 offset] [description] [PCI core offset]
788 * 0x1000-0x17FF sprom shadow 0x800-0xFFF
789 * 0x1800-0x1DFF device registers 0x000-0x5FF
790 * 0x1E00+0x1FFF siba config registers 0xE00-0xFFF
792 * This function checks -- and if necessary, corrects -- the BHND_PCI_SRSH_PI
796 * that map the PCI core.
798 * Applies to all PCI and PCIe-G1 core revisions.
812 if ((sc->pci_quirks & BHNDB_PCI_QUIRK_SRSH_WAR) == 0) in bhndb_pci_srsh_pi_war()
815 /* Use an equality match descriptor to look up our PCI core's base in bhndb_pci_srsh_pi_war()
817 md = bhnd_core_get_match_desc(&probe->hostb_core); in bhndb_pci_srsh_pi_war()
818 error = bhnd_erom_lookup_core_addr(probe->erom, &md, BHND_PORT_DEVICE, in bhndb_pci_srsh_pi_war()
821 device_printf(sc->dev, "no base address found for the PCI host " in bhndb_pci_srsh_pi_war()
831 /* If it doesn't match PCI core's base address, update the SPROM in bhndb_pci_srsh_pi_war()
846 bhndb_pci_resume(device_t dev) in bhndb_pci_resume() argument
851 sc = device_get_softc(dev); in bhndb_pci_resume()
854 if ((error = bhndb_enable_pci_clocks(sc->dev))) in bhndb_pci_resume()
858 return (bhndb_generic_resume(dev)); in bhndb_pci_resume()
862 bhndb_pci_suspend(device_t dev) in bhndb_pci_suspend() argument
867 sc = device_get_softc(dev); in bhndb_pci_suspend()
870 if ((error = bhndb_disable_pci_clocks(sc->dev))) in bhndb_pci_suspend()
874 return (bhndb_generic_suspend(dev)); in bhndb_pci_suspend()
878 bhndb_pci_set_window_addr(device_t dev, const struct bhndb_regwin *rw, in bhndb_pci_set_window_addr() argument
881 struct bhndb_pci_softc *sc = device_get_softc(dev); in bhndb_pci_set_window_addr()
882 return (sc->set_regwin(sc->dev, sc->parent, rw, addr)); in bhndb_pci_set_window_addr()
886 * A siba(4) and bcma(4)-compatible bhndb_set_window_addr implementation.
888 * On siba(4) devices, it's possible that writing a PCI window register may
896 bhndb_pci_compat_setregwin(device_t dev, device_t pci_dev, in bhndb_pci_compat_setregwin() argument
902 if (rw->win_type != BHNDB_REGWIN_T_DYN) in bhndb_pci_compat_setregwin()
905 reg = rw->d.dyn.cfg_offset; in bhndb_pci_compat_setregwin()
907 if ((error = bhndb_pci_fast_setregwin(dev, pci_dev, rw, addr))) in bhndb_pci_compat_setregwin()
921 * A bcma(4)-only bhndb_set_window_addr implementation.
924 bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev, in bhndb_pci_fast_setregwin() argument
927 /* The PCI bridge core only supports 32-bit addressing, regardless in bhndb_pci_fast_setregwin()
928 * of the bus' support for 64-bit addressing */ in bhndb_pci_fast_setregwin()
932 switch (rw->win_type) { in bhndb_pci_fast_setregwin()
935 if (addr % rw->win_size != 0) in bhndb_pci_fast_setregwin()
938 pci_write_config(pci_dev, rw->d.dyn.cfg_offset, addr, 4); in bhndb_pci_fast_setregwin()
948 bhndb_pci_populate_board_info(device_t dev, device_t child, in bhndb_pci_populate_board_info() argument
953 sc = device_get_softc(dev); in bhndb_pci_populate_board_info()
957 * PCI subdevice to the SPROM-supplied boardtype. in bhndb_pci_populate_board_info()
963 * board-specific workarounds. in bhndb_pci_populate_board_info()
968 * explicit references to the SPROM-supplied boardtype(s) in our in bhndb_pci_populate_board_info()
971 if (pci_get_subvendor(sc->parent) == PCI_VENDOR_APPLE) { in bhndb_pci_populate_board_info()
972 switch (info->board_type) { in bhndb_pci_populate_board_info()
977 info->board_type = 0; /* allow override below */ in bhndb_pci_populate_board_info()
984 /* If NVRAM did not supply vendor/type/devid info, provide the PCI in bhndb_pci_populate_board_info()
986 if (info->board_vendor == 0) in bhndb_pci_populate_board_info()
987 info->board_vendor = pci_get_subvendor(sc->parent); in bhndb_pci_populate_board_info()
989 if (info->board_type == 0) in bhndb_pci_populate_board_info()
990 info->board_type = pci_get_subdevice(sc->parent); in bhndb_pci_populate_board_info()
992 if (info->board_devid == 0) in bhndb_pci_populate_board_info()
993 info->board_devid = pci_get_device(sc->parent); in bhndb_pci_populate_board_info()
999 * Examine the bridge device @p dev and return the expected host bridge
1002 * @param dev The bhndb bridge device
1005 bhndb_expected_pci_devclass(device_t dev) in bhndb_expected_pci_devclass() argument
1007 if (bhndb_is_pcie_attached(dev)) in bhndb_expected_pci_devclass()
1014 * Return true if the bridge device @p dev is attached via PCIe,
1017 * @param dev The bhndb bridge device
1020 bhndb_is_pcie_attached(device_t dev) in bhndb_is_pcie_attached() argument
1024 if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, &reg) == 0) in bhndb_is_pcie_attached()
1033 * Some PCI chipsets (BCM4306, possibly others) chips do not support
1034 * the idle low-power clock. Clocking must be bootstrapped at
1036 * PCI config space, and correspondingly, explicitly shutdown at
1042 * @param dev The bhndb bridge device
1045 bhndb_enable_pci_clocks(device_t dev) in bhndb_enable_pci_clocks() argument
1052 pci_dev = device_get_parent(dev); in bhndb_enable_pci_clocks()
1054 /* Only supported and required on PCI devices */ in bhndb_enable_pci_clocks()
1055 if (bhndb_is_pcie_attached(dev)) in bhndb_enable_pci_clocks()
1081 /* Clear any PCI 'sent target-abort' flag. */ in bhndb_enable_pci_clocks()
1095 * @param dev The bhndb bridge device
1098 bhndb_disable_pci_clocks(device_t dev) in bhndb_disable_pci_clocks() argument
1103 pci_dev = device_get_parent(dev); in bhndb_disable_pci_clocks()
1105 /* Only supported and required on PCI devices */ in bhndb_disable_pci_clocks()
1106 if (bhndb_is_pcie_attached(dev)) in bhndb_disable_pci_clocks()
1126 bhndb_pci_pwrctl_get_clksrc(device_t dev, device_t child, in bhndb_pci_pwrctl_get_clksrc() argument
1132 sc = device_get_softc(dev); in bhndb_pci_pwrctl_get_clksrc()
1134 /* Only supported on PCI devices */ in bhndb_pci_pwrctl_get_clksrc()
1135 if (bhndb_is_pcie_attached(sc->dev)) in bhndb_pci_pwrctl_get_clksrc()
1142 gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4); in bhndb_pci_pwrctl_get_clksrc()
1150 bhndb_pci_pwrctl_gate_clock(device_t dev, device_t child, in bhndb_pci_pwrctl_gate_clock() argument
1153 struct bhndb_pci_softc *sc = device_get_softc(dev); in bhndb_pci_pwrctl_gate_clock()
1155 /* Only supported on PCI devices */ in bhndb_pci_pwrctl_gate_clock()
1156 if (bhndb_is_pcie_attached(sc->dev)) in bhndb_pci_pwrctl_gate_clock()
1163 return (bhndb_disable_pci_clocks(sc->dev)); in bhndb_pci_pwrctl_gate_clock()
1167 bhndb_pci_pwrctl_ungate_clock(device_t dev, device_t child, in bhndb_pci_pwrctl_ungate_clock() argument
1170 struct bhndb_pci_softc *sc = device_get_softc(dev); in bhndb_pci_pwrctl_ungate_clock()
1172 /* Only supported on PCI devices */ in bhndb_pci_pwrctl_ungate_clock()
1173 if (bhndb_is_pcie_attached(sc->dev)) in bhndb_pci_pwrctl_ungate_clock()
1180 return (bhndb_enable_pci_clocks(sc->dev)); in bhndb_pci_pwrctl_ungate_clock()
1187 bhndb_pci_map_intr_isrc(device_t dev, struct resource *irq, in bhndb_pci_map_intr_isrc() argument
1190 struct bhndb_pci_softc *sc = device_get_softc(dev); in bhndb_pci_map_intr_isrc()
1193 *isrc = sc->isrc; in bhndb_pci_map_intr_isrc()
1197 /* siba-specific implementation of BHNDB_ROUTE_INTERRUPTS() */
1205 KASSERT(sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC, in bhndb_pci_route_siba_interrupts()
1212 if (ivec > (sizeof(sbintvec)*8) - 1 /* aka '31' */) { in bhndb_pci_route_siba_interrupts()
1214 device_printf(sc->dev, "cannot route interrupts to high " in bhndb_pci_route_siba_interrupts()
1232 bhndb_pci_route_interrupts(device_t dev, device_t child) in bhndb_pci_route_interrupts() argument
1239 sc = device_get_softc(dev); in bhndb_pci_route_interrupts()
1241 if (sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC) in bhndb_pci_route_interrupts()
1247 device_printf(dev, "cannot route interrupts to high core " in bhndb_pci_route_interrupts()
1255 intmask = pci_read_config(sc->parent, BHNDB_PCI_INT_MASK, 4); in bhndb_pci_route_interrupts()
1257 pci_write_config(sc->parent, BHNDB_PCI_INT_MASK, intmask, 4); in bhndb_pci_route_interrupts()
1265 * Using the generic PCI bridge hardware configuration, allocate, initialize
1272 * @param dev The bhndb_pci bridge device.
1276 * @retval non-zero if allocating the probe state fails, a regular
1284 bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe, device_t dev, in bhndb_pci_probe_alloc() argument
1294 parent_dev = device_get_parent(dev); in bhndb_pci_probe_alloc()
1298 p->dev = dev; in bhndb_pci_probe_alloc()
1299 p->pci_dev = parent_dev; in bhndb_pci_probe_alloc()
1304 p->m_win = NULL; in bhndb_pci_probe_alloc()
1305 p->m_res = NULL; in bhndb_pci_probe_alloc()
1306 p->m_valid = false; in bhndb_pci_probe_alloc()
1308 bhndb_pci_eio_init(&p->erom_io, p); in bhndb_pci_probe_alloc()
1309 eio = &p->erom_io.eio; in bhndb_pci_probe_alloc()
1312 hwcfg = BHNDB_BUS_GET_GENERIC_HWCFG(parent_dev, dev); in bhndb_pci_probe_alloc()
1313 hint = BHNDB_BUS_GET_CHIPID(parent_dev, dev); in bhndb_pci_probe_alloc()
1316 error = bhndb_alloc_host_resources(&p->hr, dev, parent_dev, hwcfg); in bhndb_pci_probe_alloc()
1318 p->hr = NULL; in bhndb_pci_probe_alloc()
1329 p->erom_class = bhnd_erom_probe_driver_classes( in bhndb_pci_probe_alloc()
1330 device_get_devclass(dev), eio, hint, &p->cid); in bhndb_pci_probe_alloc()
1331 if (p->erom_class == NULL) { in bhndb_pci_probe_alloc()
1332 device_printf(dev, "device enumeration unsupported; no " in bhndb_pci_probe_alloc()
1340 p->erom = bhnd_erom_alloc(p->erom_class, &p->cid, eio); in bhndb_pci_probe_alloc()
1341 if (p->erom == NULL) { in bhndb_pci_probe_alloc()
1342 device_printf(dev, "failed to allocate device enumeration " in bhndb_pci_probe_alloc()
1352 error = bhnd_erom_get_core_table(p->erom, &p->cores, &p->ncores); in bhndb_pci_probe_alloc()
1354 device_printf(p->dev, "error fetching core table: %d\n", in bhndb_pci_probe_alloc()
1357 p->cores = NULL; in bhndb_pci_probe_alloc()
1362 error = bhndb_find_hostb_core(p->cores, p->ncores, hostb_devclass, in bhndb_pci_probe_alloc()
1363 &p->hostb_core); in bhndb_pci_probe_alloc()
1365 device_printf(dev, "failed to identify the host bridge " in bhndb_pci_probe_alloc()
1376 KASSERT(p->erom == NULL, ("I/O instance will be freed by " in bhndb_pci_probe_alloc()
1382 if (p->erom != NULL) { in bhndb_pci_probe_alloc()
1383 if (p->cores != NULL) in bhndb_pci_probe_alloc()
1384 bhnd_erom_free_core_table(p->erom, p->cores); in bhndb_pci_probe_alloc()
1386 bhnd_erom_free(p->erom); in bhndb_pci_probe_alloc()
1388 KASSERT(p->cores == NULL, ("cannot free erom-owned core table " in bhndb_pci_probe_alloc()
1392 if (p->hr != NULL) in bhndb_pci_probe_alloc()
1393 bhndb_release_host_resources(p->hr); in bhndb_pci_probe_alloc()
1406 bhnd_erom_free_core_table(probe->erom, probe->cores); in bhndb_pci_probe_free()
1407 bhnd_erom_free(probe->erom); in bhndb_pci_probe_free()
1408 bhndb_release_host_resources(probe->hr); in bhndb_pci_probe_free()
1423 * @retval non-zero if enumerating the bridged bhnd(4) bus fails, a regular
1430 size_t len = sizeof(**cores) * probe->ncores; in bhndb_pci_probe_copy_core_table()
1433 memcpy(*cores, probe->cores, len); in bhndb_pci_probe_copy_core_table()
1435 *ncores = probe->ncores; in bhndb_pci_probe_copy_core_table()
1459 if (!probe->m_valid) in bhndb_pci_probe_has_mapping()
1462 KASSERT(probe->m_win != NULL, ("missing register window")); in bhndb_pci_probe_has_mapping()
1463 KASSERT(probe->m_res != NULL, ("missing regwin resource")); in bhndb_pci_probe_has_mapping()
1464 KASSERT(probe->m_win->win_type == BHNDB_REGWIN_T_DYN, in bhndb_pci_probe_has_mapping()
1465 ("unexpected window type %d", probe->m_win->win_type)); in bhndb_pci_probe_has_mapping()
1467 if (addr < probe->m_target) in bhndb_pci_probe_has_mapping()
1470 if (addr >= probe->m_target + probe->m_win->win_size) in bhndb_pci_probe_has_mapping()
1473 if ((probe->m_target + probe->m_win->win_size) - addr < size) in bhndb_pci_probe_has_mapping()
1492 * @retval non-zero if an error occurs adjusting the backing dynamic
1506 if (BHND_SIZE_MAX - offset < addr) { in bhndb_pci_probe_map()
1507 device_printf(probe->dev, "invalid offset %#jx+%#jx\n", addr, in bhndb_pci_probe_map()
1516 *res = probe->m_res; in bhndb_pci_probe_map()
1517 *res_offset = (addr - probe->m_target) + in bhndb_pci_probe_map()
1518 probe->m_win->win_offset; in bhndb_pci_probe_map()
1524 regwin_table = probe->hr->cfg->register_windows; in bhndb_pci_probe_map()
1528 device_printf(probe->dev, "unable to map %#jx+%#jx; no " in bhndb_pci_probe_map()
1535 regwin_res = bhndb_host_resource_for_regwin(probe->hr, regwin); in bhndb_pci_probe_map()
1537 device_printf(probe->dev, "unable to map %#jx+%#jx; no " in bhndb_pci_probe_map()
1542 /* Page-align the target address */ in bhndb_pci_probe_map()
1543 target = addr - (addr % regwin->win_size); in bhndb_pci_probe_map()
1546 error = bhndb_pci_compat_setregwin(probe->dev, probe->pci_dev, in bhndb_pci_probe_map()
1549 device_printf(probe->dev, "failed to configure dynamic " in bhndb_pci_probe_map()
1555 probe->m_win = regwin; in bhndb_pci_probe_map()
1556 probe->m_res = regwin_res; in bhndb_pci_probe_map()
1557 probe->m_addr = addr; in bhndb_pci_probe_map()
1558 probe->m_size = size; in bhndb_pci_probe_map()
1559 probe->m_target = target; in bhndb_pci_probe_map()
1560 probe->m_valid = true; in bhndb_pci_probe_map()
1563 *res_offset = (addr - target) + regwin->win_offset; in bhndb_pci_probe_map()
1594 device_printf(probe->dev, "error mapping %#jx+%#jx for " in bhndb_pci_probe_write()
1637 device_printf(probe->dev, "error mapping %#jx+%#jx for " in bhndb_pci_probe_read()
1656 * Initialize a new bhndb PCI bridge EROM I/O instance. All I/O will be
1668 pio->eio.map = bhndb_pci_eio_map; in bhndb_pci_eio_init()
1669 pio->eio.tell = bhndb_pci_eio_tell; in bhndb_pci_eio_init()
1670 pio->eio.read = bhndb_pci_eio_read; in bhndb_pci_eio_init()
1671 pio->eio.fini = NULL; in bhndb_pci_eio_init()
1673 pio->mapped = false; in bhndb_pci_eio_init()
1674 pio->addr = 0; in bhndb_pci_eio_init()
1675 pio->size = 0; in bhndb_pci_eio_init()
1676 pio->probe = probe; in bhndb_pci_eio_init()
1686 if (BHND_ADDR_MAX - addr < size) in bhndb_pci_eio_map()
1689 pio->addr = addr; in bhndb_pci_eio_map()
1690 pio->size = size; in bhndb_pci_eio_map()
1691 pio->mapped = true; in bhndb_pci_eio_map()
1703 if (!pio->mapped) in bhndb_pci_eio_tell()
1706 *addr = pio->addr; in bhndb_pci_eio_tell()
1707 *size = pio->size; in bhndb_pci_eio_tell()
1719 if (!pio->mapped) in bhndb_pci_eio_read()
1723 if (offset > pio->size || in bhndb_pci_eio_read()
1724 width > pio->size || in bhndb_pci_eio_read()
1725 pio->size - offset < width) in bhndb_pci_eio_read()
1730 return (bhndb_pci_probe_read(pio->probe, pio->addr, offset, width)); in bhndb_pci_eio_read()
1760 MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);