Lines Matching +full:mem +full:- +full:io

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
147 "Clear firmware-assigned resources for PCI-PCI bridge I/O windows.");
151 * sub-allocated from one of our window resource managers.
158 if (rman_is_region_manager(r, &sc->io.rman)) in pcib_get_resource_window()
159 return (&sc->io); in pcib_get_resource_window()
164 rman_is_region_manager(r, &sc->pmem.rman)) in pcib_get_resource_window()
165 return (&sc->pmem); in pcib_get_resource_window()
166 if (rman_is_region_manager(r, &sc->mem.rman)) in pcib_get_resource_window()
167 return (&sc->mem); in pcib_get_resource_window()
174 * Is a resource from a child device sub-allocated from one of our
182 return (rman_is_region_manager(r, &sc->bus.rman)); in pcib_is_resource_managed()
190 return (pw->valid && pw->base < pw->limit); in pcib_is_window_open()
203 PCI_ENABLE_IO(device_get_parent(sc->dev), sc->dev, type); in pcib_activate_window()
212 dev = sc->dev; in pcib_write_windows()
213 if (sc->io.valid && mask & WIN_IO) { in pcib_write_windows()
217 sc->io.base >> 16, 2); in pcib_write_windows()
219 sc->io.limit >> 16, 2); in pcib_write_windows()
221 pci_write_config(dev, PCIR_IOBASEL_1, sc->io.base >> 8, 1); in pcib_write_windows()
222 pci_write_config(dev, PCIR_IOLIMITL_1, sc->io.limit >> 8, 1); in pcib_write_windows()
226 pci_write_config(dev, PCIR_MEMBASE_1, sc->mem.base >> 16, 2); in pcib_write_windows()
227 pci_write_config(dev, PCIR_MEMLIMIT_1, sc->mem.limit >> 16, 2); in pcib_write_windows()
230 if (sc->pmem.valid && mask & WIN_PMEM) { in pcib_write_windows()
234 sc->pmem.base >> 32, 4); in pcib_write_windows()
236 sc->pmem.limit >> 32, 4); in pcib_write_windows()
238 pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2); in pcib_write_windows()
239 pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2); in pcib_write_windows()
253 if (!(sc->bridgectl & PCIB_BCR_ISA_ENABLE)) in pcib_is_isa_range()
257 if (start + count - 1 != end) in pcib_is_isa_range()
264 /* Check for overlap with 0x000 - 0x0ff as a special case. */ in pcib_is_isa_range()
282 device_printf(sc->dev, in pcib_is_isa_range()
283 "I/O range %#jx-%#jx overlaps with an ISA alias\n", start, in pcib_is_isa_range()
295 newarray = malloc(sizeof(struct resource *) * (w->count + count), in pcib_add_window_resources()
297 if (w->res != NULL) in pcib_add_window_resources()
298 bcopy(w->res, newarray, sizeof(struct resource *) * w->count); in pcib_add_window_resources()
299 bcopy(res, newarray + w->count, sizeof(struct resource *) * count); in pcib_add_window_resources()
300 free(w->res, M_DEVBUF); in pcib_add_window_resources()
301 w->res = newarray; in pcib_add_window_resources()
302 w->count += count; in pcib_add_window_resources()
305 error = rman_manage_region(&w->rman, rman_get_start(res[i]), in pcib_add_window_resources()
322 * of the next non-alias range. As a special case, addresses in pcib_walk_nonisa_ranges()
323 * in the range 0x000 - 0x0ff should also be skipped since in pcib_walk_nonisa_ranges()
368 if (as->error != 0) in alloc_ranges()
371 w = &as->sc->io; in alloc_ranges()
372 rid = w->reg; in alloc_ranges()
374 device_printf(as->sc->dev, in alloc_ranges()
375 "allocating non-ISA range %#jx-%#jx\n", start, end); in alloc_ranges()
376 as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT, in alloc_ranges()
377 &rid, start, end, end - start + 1, RF_ACTIVE | RF_UNMAPPED); in alloc_ranges()
378 if (as->res[as->count] == NULL) in alloc_ranges()
379 as->error = ENXIO; in alloc_ranges()
381 as->count++; in alloc_ranges()
403 bus_release_resource(sc->dev, SYS_RES_IOPORT, in pcib_alloc_nonisa_ranges()
404 sc->io.reg, as.res[i]); in pcib_alloc_nonisa_ranges()
411 pcib_add_window_resources(&sc->io, as.res, as.count); in pcib_alloc_nonisa_ranges()
426 w->rman.rm_start = 0; in pcib_alloc_window()
427 w->rman.rm_end = max_address; in pcib_alloc_window()
428 w->rman.rm_type = RMAN_ARRAY; in pcib_alloc_window()
430 device_get_nameunit(sc->dev), w->name); in pcib_alloc_window()
431 w->rman.rm_descr = strdup(buf, M_DEVBUF); in pcib_alloc_window()
432 error = rman_init(&w->rman); in pcib_alloc_window()
435 device_get_nameunit(sc->dev), w->name); in pcib_alloc_window()
440 if (w->base > max_address || w->limit > max_address) { in pcib_alloc_window()
441 device_printf(sc->dev, in pcib_alloc_window()
442 "initial %s window has too many bits, ignoring\n", w->name); in pcib_alloc_window()
445 if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE) in pcib_alloc_window()
446 (void)pcib_alloc_nonisa_ranges(sc, w->base, w->limit); in pcib_alloc_window()
448 rid = w->reg; in pcib_alloc_window()
449 res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit, in pcib_alloc_window()
450 w->limit - w->base + 1, flags | RF_ACTIVE | RF_UNMAPPED); in pcib_alloc_window()
454 if (w->res == NULL) { in pcib_alloc_window()
455 device_printf(sc->dev, in pcib_alloc_window()
456 "failed to allocate initial %s window: %#jx-%#jx\n", in pcib_alloc_window()
457 w->name, (uintmax_t)w->base, (uintmax_t)w->limit); in pcib_alloc_window()
458 w->base = max_address; in pcib_alloc_window()
459 w->limit = 0; in pcib_alloc_window()
460 pcib_write_windows(sc, w->mask); in pcib_alloc_window()
476 dev = sc->dev; in pcib_probe_windows()
486 * If 'val' is zero, then only 16-bits of I/O space in pcib_probe_windows()
491 sc->io.valid = 1; in pcib_probe_windows()
495 sc->io.valid = 1; in pcib_probe_windows()
498 if (sc->io.valid) { in pcib_probe_windows()
499 sc->io.reg = PCIR_IOBASEL_1; in pcib_probe_windows()
500 sc->io.step = 12; in pcib_probe_windows()
501 sc->io.mask = WIN_IO; in pcib_probe_windows()
502 sc->io.name = "I/O port"; in pcib_probe_windows()
504 sc->io.base = PCI_PPBIOBASE( in pcib_probe_windows()
506 sc->io.limit = PCI_PPBIOLIMIT( in pcib_probe_windows()
511 sc->io.base = PCI_PPBIOBASE(0, val); in pcib_probe_windows()
512 sc->io.limit = PCI_PPBIOLIMIT(0, in pcib_probe_windows()
516 pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max); in pcib_probe_windows()
520 sc->mem.valid = 1; in pcib_probe_windows()
521 sc->mem.reg = PCIR_MEMBASE_1; in pcib_probe_windows()
522 sc->mem.step = 20; in pcib_probe_windows()
523 sc->mem.mask = WIN_MEM; in pcib_probe_windows()
524 sc->mem.name = "memory"; in pcib_probe_windows()
525 sc->mem.base = PCI_PPBMEMBASE(0, in pcib_probe_windows()
527 sc->mem.limit = PCI_PPBMEMLIMIT(0, in pcib_probe_windows()
529 pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff); in pcib_probe_windows()
535 * If 'val' is zero, then only 32-bits of memory space in pcib_probe_windows()
540 sc->pmem.valid = 1; in pcib_probe_windows()
544 sc->pmem.valid = 1; in pcib_probe_windows()
547 if (sc->pmem.valid) { in pcib_probe_windows()
548 sc->pmem.reg = PCIR_PMBASEL_1; in pcib_probe_windows()
549 sc->pmem.step = 20; in pcib_probe_windows()
550 sc->pmem.mask = WIN_PMEM; in pcib_probe_windows()
551 sc->pmem.name = "prefetch"; in pcib_probe_windows()
553 sc->pmem.base = PCI_PPBMEMBASE( in pcib_probe_windows()
555 sc->pmem.limit = PCI_PPBMEMLIMIT( in pcib_probe_windows()
560 sc->pmem.base = PCI_PPBMEMBASE(0, val); in pcib_probe_windows()
561 sc->pmem.limit = PCI_PPBMEMLIMIT(0, in pcib_probe_windows()
565 pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY, in pcib_probe_windows()
576 if (!w->valid) in pcib_release_window()
579 dev = sc->dev; in pcib_release_window()
580 error = rman_fini(&w->rman); in pcib_release_window()
582 device_printf(dev, "failed to release %s rman\n", w->name); in pcib_release_window()
585 free(__DECONST(char *, w->rman.rm_descr), M_DEVBUF); in pcib_release_window()
587 for (i = 0; i < w->count; i++) { in pcib_release_window()
588 error = bus_free_resource(dev, type, w->res[i]); in pcib_release_window()
591 "failed to release %s resource: %d\n", w->name, in pcib_release_window()
594 free(w->res, M_DEVBUF); in pcib_release_window()
601 pcib_release_window(sc, &sc->pmem, SYS_RES_MEMORY); in pcib_free_windows()
602 pcib_release_window(sc, &sc->mem, SYS_RES_MEMORY); in pcib_free_windows()
603 pcib_release_window(sc, &sc->io, SYS_RES_IOPORT); in pcib_free_windows()
621 bus->sub_reg = PCIR_SUBBUS_1; in pcib_setup_secbus()
625 bus->sub_reg = PCIR_SUBBUS_2; in pcib_setup_secbus()
630 bus->sec = pci_read_config(dev, sec_reg, 1); in pcib_setup_secbus()
631 bus->sub = pci_read_config(dev, bus->sub_reg, 1); in pcib_setup_secbus()
632 bus->dev = dev; in pcib_setup_secbus()
633 bus->rman.rm_start = 0; in pcib_setup_secbus()
634 bus->rman.rm_end = PCI_BUSMAX; in pcib_setup_secbus()
635 bus->rman.rm_type = RMAN_ARRAY; in pcib_setup_secbus()
637 bus->rman.rm_descr = strdup(buf, M_DEVBUF); in pcib_setup_secbus()
638 error = rman_init(&bus->rman); in pcib_setup_secbus()
648 bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid, in pcib_setup_secbus()
650 if (bus->res == NULL) { in pcib_setup_secbus()
655 bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid, in pcib_setup_secbus()
657 } else if (rman_get_size(bus->res) < min_count) in pcib_setup_secbus()
662 (void)bus_adjust_resource(dev, PCI_RES_BUS, bus->res, in pcib_setup_secbus()
663 rman_get_start(bus->res), rman_get_start(bus->res) + in pcib_setup_secbus()
664 min_count - 1); in pcib_setup_secbus()
669 if (bus->res != NULL) { in pcib_setup_secbus()
670 error = rman_manage_region(&bus->rman, rman_get_start(bus->res), in pcib_setup_secbus()
671 rman_get_end(bus->res)); in pcib_setup_secbus()
674 bus->sec = rman_get_start(bus->res); in pcib_setup_secbus()
675 bus->sub = rman_get_end(bus->res); in pcib_setup_secbus()
684 error = rman_fini(&bus->rman); in pcib_free_secbus()
689 free(__DECONST(char *, bus->rman.rm_descr), M_DEVBUF); in pcib_free_secbus()
691 error = bus_free_resource(dev, PCI_RES_BUS, bus->res); in pcib_free_secbus()
703 res = rman_reserve_resource(&bus->rman, start, end, count, flags, in pcib_suballoc_bus()
709 device_printf(bus->dev, in pcib_suballoc_bus()
710 "allocated bus range (%ju-%ju) for rid %d of %s\n", in pcib_suballoc_bus()
729 old_end = rman_get_end(bus->res); in pcib_grow_subbus()
731 error = bus_adjust_resource(bus->dev, PCI_RES_BUS, bus->res, in pcib_grow_subbus()
732 rman_get_start(bus->res), new_end); in pcib_grow_subbus()
736 device_printf(bus->dev, "grew bus range to %ju-%ju\n", in pcib_grow_subbus()
737 rman_get_start(bus->res), rman_get_end(bus->res)); in pcib_grow_subbus()
738 error = rman_manage_region(&bus->rman, old_end + 1, in pcib_grow_subbus()
739 rman_get_end(bus->res)); in pcib_grow_subbus()
742 bus->sub = rman_get_end(bus->res); in pcib_grow_subbus()
743 pci_write_config(bus->dev, bus->sub_reg, bus->sub, 1); in pcib_grow_subbus()
767 if (rman_last_free_region(&bus->rman, &start_free, &end_free) != 0 || in pcib_alloc_subbus()
768 end_free != bus->sub) in pcib_alloc_subbus()
769 start_free = bus->sub + 1; in pcib_alloc_subbus()
772 new_end = start_free + count - 1; in pcib_alloc_subbus()
783 device_printf(bus->dev, in pcib_alloc_subbus()
785 printf("\tback candidate range: %ju-%ju\n", start_free, in pcib_alloc_subbus()
796 * PCI-express HotPlug support.
801 "Enable support for native PCI-express HotPlug.");
813 dev = sc->dev; in pcib_probe_hotplug()
820 sc->pcie_slot_cap = pcie_read_config(dev, PCIER_SLOT_CAP, 4); in pcib_probe_hotplug()
822 if ((sc->pcie_slot_cap & PCIEM_SLOT_CAP_HPC) == 0) in pcib_probe_hotplug()
837 if ((sc->pcie_slot_cap & PCIEM_SLOT_CAP_MRLSP) != 0) { in pcib_probe_hotplug()
856 sc->flags |= PCIB_HOTPLUG; in pcib_probe_hotplug()
873 dev = sc->dev; in pcib_pcie_hotplug_command()
875 if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) in pcib_pcie_hotplug_command()
883 device_printf(dev, "HotPlug command: %04x -> %04x\n", ctl, new); in pcib_pcie_hotplug_command()
885 if (!(sc->pcie_slot_cap & PCIEM_SLOT_CAP_NCCS) && in pcib_pcie_hotplug_command()
887 sc->flags |= PCIB_HOTPLUG_CMD_PENDING; in pcib_pcie_hotplug_command()
890 &sc->pcie_cc_task, hz); in pcib_pcie_hotplug_command()
899 dev = sc->dev; in pcib_pcie_hotplug_command_completed()
903 if (!(sc->flags & PCIB_HOTPLUG_CMD_PENDING)) in pcib_pcie_hotplug_command_completed()
905 taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_cc_task, NULL); in pcib_pcie_hotplug_command_completed()
906 sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING; in pcib_pcie_hotplug_command_completed()
920 if (sc->flags & PCIB_DETACHING) in pcib_hotplug_inserted()
924 if ((sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS) == 0) in pcib_hotplug_inserted()
928 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD) in pcib_hotplug_inserted()
932 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_MRLSP && in pcib_hotplug_inserted()
933 (sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSS) != 0) in pcib_hotplug_inserted()
940 * Returns -1 if the card is fully inserted, powered, and ready for
952 if (!(sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE)) in pcib_hotplug_present()
955 return (-1); in pcib_hotplug_present()
961 "Enable support for PCI-express Electromechanical Interlock.");
970 if ((sc->pcie_slot_sta & (PCIEM_SLOT_STA_PDC | PCIEM_SLOT_STA_PDS)) == in pcib_pcie_hotplug_update()
972 sc->flags &= ~PCIB_DETACHING; in pcib_pcie_hotplug_update()
977 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PIP) { in pcib_pcie_hotplug_update()
981 else if (sc->flags & PCIB_DETACH_PENDING) in pcib_pcie_hotplug_update()
988 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PCP) { in pcib_pcie_hotplug_update()
1002 if ((sc->pcie_slot_cap & PCIEM_SLOT_CAP_EIP) && in pcib_pcie_hotplug_update()
1005 ei_engaged = (sc->pcie_slot_sta & PCIEM_SLOT_STA_EIS) != 0; in pcib_pcie_hotplug_update()
1017 !(sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE) && in pcib_pcie_hotplug_update()
1018 sc->pcie_slot_sta & in pcib_pcie_hotplug_update()
1021 device_printf(sc->dev, in pcib_pcie_hotplug_update()
1025 &sc->pcie_dll_task, hz); in pcib_pcie_hotplug_update()
1026 } else if (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE) in pcib_pcie_hotplug_update()
1027 taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_dll_task, in pcib_pcie_hotplug_update()
1038 (pcib_hotplug_present(sc) != 0) != (sc->child != NULL)) in pcib_pcie_hotplug_update()
1039 taskqueue_enqueue(taskqueue_bus, &sc->pcie_hp_task); in pcib_pcie_hotplug_update()
1050 dev = sc->dev; in pcib_pcie_intr_hotplug()
1052 old_slot_sta = sc->pcie_slot_sta; in pcib_pcie_intr_hotplug()
1053 sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2); in pcib_pcie_intr_hotplug()
1056 pcie_write_config(dev, PCIER_SLOT_STA, sc->pcie_slot_sta, 2); in pcib_pcie_intr_hotplug()
1060 sc->pcie_slot_sta); in pcib_pcie_intr_hotplug()
1062 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_ABP) { in pcib_pcie_intr_hotplug()
1063 if (sc->flags & PCIB_DETACH_PENDING) { in pcib_pcie_intr_hotplug()
1066 sc->flags &= ~PCIB_DETACH_PENDING; in pcib_pcie_intr_hotplug()
1068 &sc->pcie_ab_task, NULL); in pcib_pcie_intr_hotplug()
1073 sc->flags |= PCIB_DETACH_PENDING; in pcib_pcie_intr_hotplug()
1075 &sc->pcie_ab_task, 5 * hz); in pcib_pcie_intr_hotplug()
1078 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD) in pcib_pcie_intr_hotplug()
1080 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSC) in pcib_pcie_intr_hotplug()
1082 sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSS ? "open" : in pcib_pcie_intr_hotplug()
1084 if (bootverbose && sc->pcie_slot_sta & PCIEM_SLOT_STA_PDC) in pcib_pcie_intr_hotplug()
1086 sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS ? "card present" : in pcib_pcie_intr_hotplug()
1088 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_CC) in pcib_pcie_intr_hotplug()
1090 if (sc->pcie_slot_sta & PCIEM_SLOT_STA_DLLSC) { in pcib_pcie_intr_hotplug()
1091 sc->pcie_link_sta = pcie_read_config(dev, PCIER_LINK_STA, 2); in pcib_pcie_intr_hotplug()
1095 sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE ? in pcib_pcie_intr_hotplug()
1111 dev = sc->dev; in pcib_pcie_hotplug_task()
1113 if (sc->child == NULL) { in pcib_pcie_hotplug_task()
1114 sc->child = device_add_child(dev, "pci", DEVICE_UNIT_ANY); in pcib_pcie_hotplug_task()
1118 if (sc->child != NULL) { in pcib_pcie_hotplug_task()
1119 if (device_delete_child(dev, sc->child) == 0) in pcib_pcie_hotplug_task()
1120 sc->child = NULL; in pcib_pcie_hotplug_task()
1132 if (sc->flags & PCIB_DETACH_PENDING) { in pcib_pcie_ab_timeout()
1133 sc->flags |= PCIB_DETACHING; in pcib_pcie_ab_timeout()
1134 sc->flags &= ~PCIB_DETACH_PENDING; in pcib_pcie_ab_timeout()
1144 device_t dev = sc->dev; in pcib_pcie_cc_timeout()
1151 sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING; in pcib_pcie_cc_timeout()
1164 device_t dev = sc->dev; in pcib_pcie_dll_timeout()
1172 sc->flags |= PCIB_DETACHING; in pcib_pcie_dll_timeout()
1174 } else if (sta != sc->pcie_link_sta) { in pcib_pcie_dll_timeout()
1188 rid = -1; in pcib_alloc_pcie_irq()
1189 dev = sc->dev; in pcib_alloc_pcie_irq()
1192 * For simplicity, only use MSI-X if there is a single message. in pcib_alloc_pcie_irq()
1199 sc->pcie_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in pcib_alloc_pcie_irq()
1201 if (sc->pcie_mem == NULL) { in pcib_alloc_pcie_irq()
1203 "Failed to allocate BAR for MSI-X table\n"); in pcib_alloc_pcie_irq()
1221 sc->pcie_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in pcib_alloc_pcie_irq()
1223 if (sc->pcie_irq == NULL) { in pcib_alloc_pcie_irq()
1225 "Failed to allocate interrupt for PCI-e events\n"); in pcib_alloc_pcie_irq()
1231 error = bus_setup_intr(dev, sc->pcie_irq, INTR_TYPE_MISC|INTR_MPSAFE, in pcib_alloc_pcie_irq()
1232 NULL, pcib_pcie_intr_hotplug, sc, &sc->pcie_ihand); in pcib_alloc_pcie_irq()
1234 device_printf(dev, "Failed to setup PCI-e interrupt handler\n"); in pcib_alloc_pcie_irq()
1235 bus_release_resource(dev, SYS_RES_IRQ, rid, sc->pcie_irq); in pcib_alloc_pcie_irq()
1249 dev = sc->dev; in pcib_release_pcie_irq()
1250 error = bus_teardown_intr(dev, sc->pcie_irq, sc->pcie_ihand); in pcib_release_pcie_irq()
1253 error = bus_free_resource(dev, SYS_RES_IRQ, sc->pcie_irq); in pcib_release_pcie_irq()
1259 if (sc->pcie_mem != NULL) in pcib_release_pcie_irq()
1260 error = bus_free_resource(dev, SYS_RES_MEMORY, sc->pcie_mem); in pcib_release_pcie_irq()
1270 dev = sc->dev; in pcib_setup_hotplug()
1271 TASK_INIT(&sc->pcie_hp_task, 0, pcib_pcie_hotplug_task, sc); in pcib_setup_hotplug()
1272 TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_ab_task, 0, in pcib_setup_hotplug()
1274 TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_cc_task, 0, in pcib_setup_hotplug()
1276 TIMEOUT_TASK_INIT(taskqueue_bus, &sc->pcie_dll_task, 0, in pcib_setup_hotplug()
1278 sc->pcie_hp_lock = bus_topo_mtx(); in pcib_setup_hotplug()
1284 sc->pcie_link_sta = pcie_read_config(dev, PCIER_LINK_STA, 2); in pcib_setup_hotplug()
1285 sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2); in pcib_setup_hotplug()
1288 pcie_write_config(dev, PCIER_SLOT_STA, sc->pcie_slot_sta, 2); in pcib_setup_hotplug()
1295 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_APB) in pcib_setup_hotplug()
1297 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PCP) in pcib_setup_hotplug()
1299 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_MRLSP) in pcib_setup_hotplug()
1301 if (!(sc->pcie_slot_cap & PCIEM_SLOT_CAP_NCCS)) in pcib_setup_hotplug()
1305 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_AIP) { in pcib_setup_hotplug()
1320 if (sc->flags & PCIB_DETACH_PENDING) { in pcib_detach_hotplug()
1321 sc->flags &= ~PCIB_DETACH_PENDING; in pcib_detach_hotplug()
1322 taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_ab_task, in pcib_detach_hotplug()
1325 sc->flags |= PCIB_DETACHING; in pcib_detach_hotplug()
1327 if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) { in pcib_detach_hotplug()
1328 taskqueue_cancel_timeout(taskqueue_bus, &sc->pcie_cc_task, in pcib_detach_hotplug()
1331 sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING; in pcib_detach_hotplug()
1341 if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_AIP) { in pcib_detach_hotplug()
1351 taskqueue_drain(taskqueue_bus, &sc->pcie_hp_task); in pcib_detach_hotplug()
1352 taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_ab_task); in pcib_detach_hotplug()
1353 taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_cc_task); in pcib_detach_hotplug()
1354 taskqueue_drain_timeout(taskqueue_bus, &sc->pcie_dll_task); in pcib_detach_hotplug()
1376 device_set_desc(dev, "PCI-PCI bridge"); in pcib_probe()
1377 return(-10000); in pcib_probe()
1391 sc->dev = dev; in pcib_attach_common()
1396 sc->domain = pci_get_domain(dev); in pcib_attach_common()
1397 sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2); in pcib_attach_common()
1403 sc->pribus = pci_get_bus(dev); in pcib_attach_common()
1404 pci_write_config(dev, PCIR_PRIBUS_1, sc->pribus, 1); in pcib_attach_common()
1412 CTLFLAG_RD, &sc->domain, 0, "Domain number"); in pcib_attach_common()
1414 CTLFLAG_RD, &sc->pribus, 0, "Primary bus number"); in pcib_attach_common()
1416 CTLFLAG_RD, &sc->bus.sec, 0, "Secondary bus number"); in pcib_attach_common()
1418 CTLFLAG_RD, &sc->bus.sub, 0, "Subordinate bus number"); in pcib_attach_common()
1425 * The i82380FB mobile docking controller is a PCI-PCI bridge, in pcib_attach_common()
1434 sc->flags |= PCIB_SUBTRACTIVE; in pcib_attach_common()
1439 sc->flags |= PCIB_DISABLE_MSI; in pcib_attach_common()
1442 sc->flags |= PCIB_DISABLE_MSIX; in pcib_attach_common()
1445 * Intel 815, 845 and other chipsets say they are PCI-PCI bridges, in pcib_attach_common()
1447 * BA/CA/DB and E) PCI bridges are HUB-PCI bridges, in Intelese. in pcib_attach_common()
1454 sc->flags |= PCIB_SUBTRACTIVE; in pcib_attach_common()
1459 pcib_setup_secbus(dev, &sc->bus, 1); in pcib_attach_common()
1462 if (sc->flags & PCIB_HOTPLUG) in pcib_attach_common()
1466 device_printf(dev, " domain %d\n", sc->domain); in pcib_attach_common()
1467 device_printf(dev, " secondary bus %d\n", sc->bus.sec); in pcib_attach_common()
1468 device_printf(dev, " subordinate bus %d\n", sc->bus.sub); in pcib_attach_common()
1469 if (pcib_is_window_open(&sc->io)) in pcib_attach_common()
1470 device_printf(dev, " I/O decode 0x%jx-0x%jx\n", in pcib_attach_common()
1471 (uintmax_t)sc->io.base, (uintmax_t)sc->io.limit); in pcib_attach_common()
1472 if (pcib_is_window_open(&sc->mem)) in pcib_attach_common()
1473 device_printf(dev, " memory decode 0x%jx-0x%jx\n", in pcib_attach_common()
1474 (uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit); in pcib_attach_common()
1475 if (pcib_is_window_open(&sc->pmem)) in pcib_attach_common()
1476 device_printf(dev, " prefetched decode 0x%jx-0x%jx\n", in pcib_attach_common()
1477 (uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit); in pcib_attach_common()
1478 if (sc->bridgectl & (PCIB_BCR_ISA_ENABLE | PCIB_BCR_VGA_ENABLE) || in pcib_attach_common()
1479 sc->flags & PCIB_SUBTRACTIVE) { in pcib_attach_common()
1482 if (sc->bridgectl & PCIB_BCR_ISA_ENABLE) { in pcib_attach_common()
1486 if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) { in pcib_attach_common()
1490 if (sc->flags & PCIB_SUBTRACTIVE) in pcib_attach_common()
1509 if (sc->flags & PCIB_HOTPLUG) in pcib_present()
1521 if (sc->bus.sec == 0) { in pcib_attach_child()
1533 sc->child = device_add_child(dev, "pci", DEVICE_UNIT_ANY); in pcib_attach_child()
1557 if (sc->flags & PCIB_HOTPLUG) { in pcib_detach()
1567 pcib_free_secbus(dev, &sc->bus); in pcib_detach()
1608 if (retval != 0 && sc->flags & PCIB_HOTPLUG) in pcib_child_present()
1623 *result = sc->domain; in pcib_read_ivar()
1626 *result = sc->bus.sec; in pcib_read_ivar()
1659 res = rman_reserve_resource(&w->rman, start, end, count, in pcib_suballoc_resource()
1665 device_printf(sc->dev, in pcib_suballoc_resource()
1666 "allocated %s range (%#jx-%#jx) for rid %x of %s\n", in pcib_suballoc_resource()
1667 w->name, rman_get_start(res), rman_get_end(res), *rid, in pcib_suballoc_resource()
1696 * was larger than the non-aliased range size of 0x100 our in pcib_alloc_new_window()
1700 if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && in pcib_alloc_new_window()
1702 for (base = 0xf000; (long)base >= 0; base -= 0x1000) { in pcib_alloc_new_window()
1708 * window that overlaps are the non-alias in pcib_alloc_new_window()
1712 if (start + count > limit - 0x400) in pcib_alloc_new_window()
1717 * 0 is 0x400-0x4ff. in pcib_alloc_new_window()
1719 if (end - count + 1 < 0x400) in pcib_alloc_new_window()
1722 if (end - count + 1 < base) in pcib_alloc_new_window()
1727 w->base = base; in pcib_alloc_new_window()
1728 w->limit = limit; in pcib_alloc_new_window()
1735 wmask = ((rman_res_t)1 << w->step) - 1; in pcib_alloc_new_window()
1736 if (RF_ALIGNMENT(flags) < w->step) { in pcib_alloc_new_window()
1738 flags |= RF_ALIGNMENT_LOG2(w->step); in pcib_alloc_new_window()
1742 count = roundup2(count, (rman_res_t)1 << w->step); in pcib_alloc_new_window()
1743 rid = w->reg; in pcib_alloc_new_window()
1744 res = bus_alloc_resource(sc->dev, type, &rid, start, end, count, in pcib_alloc_new_window()
1750 w->base = rman_get_start(res); in pcib_alloc_new_window()
1751 w->limit = rman_get_end(res); in pcib_alloc_new_window()
1763 KASSERT(base <= w->base && limit >= w->limit, in pcib_expand_window()
1770 KASSERT(limit == w->limit || base == w->base, in pcib_expand_window()
1775 * window behind an ISA-enabled bridge. Since I/O windows in pcib_expand_window()
1781 if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && in pcib_expand_window()
1782 (limit <= 65535 || (base <= 65535 && base != w->base))) { in pcib_expand_window()
1783 KASSERT(limit == w->limit || limit <= 65535, in pcib_expand_window()
1786 if (base != w->base) in pcib_expand_window()
1787 error = pcib_alloc_nonisa_ranges(sc, base, w->base - 1); in pcib_expand_window()
1789 error = pcib_alloc_nonisa_ranges(sc, w->limit + 1, in pcib_expand_window()
1792 w->base = base; in pcib_expand_window()
1793 w->limit = limit; in pcib_expand_window()
1800 * but for an ISA-enabled bridge we might be growing the I/O window in pcib_expand_window()
1804 for (i = 0; i < w->count; i++) { in pcib_expand_window()
1805 if (rman_get_end(w->res[i]) == w->limit) in pcib_expand_window()
1808 KASSERT(i != w->count, ("did not find existing resource")); in pcib_expand_window()
1809 res = w->res[i]; in pcib_expand_window()
1813 * existing range. The one exception is the ISA-enabled case in pcib_expand_window()
1817 if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE && in pcib_expand_window()
1818 w->base <= 65535) { in pcib_expand_window()
1823 KASSERT(w->base == rman_get_start(res), in pcib_expand_window()
1828 error = bus_adjust_resource(sc->dev, type, res, force_64k_base ? in pcib_expand_window()
1834 if (w->base != base) { in pcib_expand_window()
1835 error = rman_manage_region(&w->rman, base, w->base - 1); in pcib_expand_window()
1836 w->base = base; in pcib_expand_window()
1838 error = rman_manage_region(&w->rman, w->limit + 1, limit); in pcib_expand_window()
1839 w->limit = limit; in pcib_expand_window()
1843 device_printf(sc->dev, in pcib_expand_window()
1844 "failed to expand %s resource manager\n", w->name); in pcib_expand_window()
1845 (void)bus_adjust_resource(sc->dev, type, res, force_64k_base ? in pcib_expand_window()
1846 rman_get_start(res) : w->base, w->limit); in pcib_expand_window()
1868 if (!w->valid) in pcib_grow_window()
1870 if (sc->bridgectl & PCIB_BCR_ISA_ENABLE && count > 0x100 && in pcib_grow_window()
1873 if (end > w->rman.rm_end) in pcib_grow_window()
1874 end = w->rman.rm_end; in pcib_grow_window()
1875 if (start + count - 1 > end || start + count < start) in pcib_grow_window()
1877 wmask = ((rman_res_t)1 << w->step) - 1; in pcib_grow_window()
1883 if (w->res == NULL) { in pcib_grow_window()
1888 device_printf(sc->dev, in pcib_grow_window()
1889 "failed to allocate initial %s window (%#jx-%#jx,%#jx)\n", in pcib_grow_window()
1890 w->name, start, end, count); in pcib_grow_window()
1894 device_printf(sc->dev, in pcib_grow_window()
1895 "allocated initial %s window of %#jx-%#jx\n", in pcib_grow_window()
1896 w->name, (uintmax_t)w->base, (uintmax_t)w->limit); in pcib_grow_window()
1913 * non-alias ranges when it is grown in either direction. in pcib_grow_window()
1915 * XXX: Special case: if w->res is completely empty and the in pcib_grow_window()
1916 * request size is larger than w->res, we should find the in pcib_grow_window()
1917 * optimal aligned buffer containing w->res and allocate that. in pcib_grow_window()
1920 device_printf(sc->dev, in pcib_grow_window()
1921 "attempting to grow %s window for (%#jx-%#jx,%#jx)\n", in pcib_grow_window()
1922 w->name, start, end, count); in pcib_grow_window()
1924 if (start < w->base) { in pcib_grow_window()
1925 if (rman_first_free_region(&w->rman, &start_free, &end_free) != in pcib_grow_window()
1926 0 || start_free != w->base) in pcib_grow_window()
1927 end_free = w->base; in pcib_grow_window()
1932 end_free &= ~(align - 1); in pcib_grow_window()
1933 end_free--; in pcib_grow_window()
1934 front = end_free - (count - 1); in pcib_grow_window()
1945 printf("\tfront candidate range: %#jx-%#jx\n", in pcib_grow_window()
1948 front = w->base - front; in pcib_grow_window()
1953 if (end > w->limit) { in pcib_grow_window()
1954 if (rman_last_free_region(&w->rman, &start_free, &end_free) != in pcib_grow_window()
1955 0 || end_free != w->limit) in pcib_grow_window()
1956 start_free = w->limit + 1; in pcib_grow_window()
1962 back = start_free + count - 1; in pcib_grow_window()
1973 printf("\tback candidate range: %#jx-%#jx\n", in pcib_grow_window()
1976 back -= w->limit; in pcib_grow_window()
1989 error = pcib_expand_window(sc, w, type, w->base - front, in pcib_grow_window()
1990 w->limit); in pcib_grow_window()
1995 error = pcib_expand_window(sc, w, type, w->base, in pcib_grow_window()
1996 w->limit + back); in pcib_grow_window()
2006 device_printf(sc->dev, "grew %s window to %#jx-%#jx\n", in pcib_grow_window()
2007 w->name, (uintmax_t)w->base, (uintmax_t)w->limit); in pcib_grow_window()
2011 KASSERT((w->base & wmask) == 0, ("start address is not aligned")); in pcib_grow_window()
2012 KASSERT((w->limit & wmask) == wmask, ("end address is not aligned")); in pcib_grow_window()
2013 pcib_write_windows(sc, w->mask); in pcib_grow_window()
2037 if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) in pcib_alloc_resource()
2046 return (pcib_alloc_subbus(&sc->bus, child, rid, start, end, in pcib_alloc_resource()
2051 r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start, in pcib_alloc_resource()
2053 if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0) in pcib_alloc_resource()
2055 if (pcib_grow_window(sc, &sc->io, type, start, end, count, in pcib_alloc_resource()
2057 r = pcib_suballoc_resource(sc, &sc->io, child, type, in pcib_alloc_resource()
2070 r = pcib_suballoc_resource(sc, &sc->pmem, child, type, in pcib_alloc_resource()
2075 r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid, in pcib_alloc_resource()
2077 if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0) in pcib_alloc_resource()
2080 if (pcib_grow_window(sc, &sc->pmem, type, start, end, in pcib_alloc_resource()
2082 r = pcib_suballoc_resource(sc, &sc->pmem, child, in pcib_alloc_resource()
2088 if (pcib_grow_window(sc, &sc->mem, type, start, end, count, in pcib_alloc_resource()
2090 r = pcib_suballoc_resource(sc, &sc->mem, child, type, in pcib_alloc_resource()
2102 if (sc->flags & PCIB_SUBTRACTIVE && r == NULL) in pcib_alloc_resource()
2121 * If the resource wasn't sub-allocated from one of our region in pcib_adjust_resource()
2129 * If our bus range isn't big enough to grow the sub-allocation in pcib_adjust_resource()
2135 if (start >= sc->bus.sec && end > sc->bus.sub) { in pcib_adjust_resource()
2136 error = pcib_grow_subbus(&sc->bus, end); in pcib_adjust_resource()
2147 ("%s: no window for resource (%#jx-%#jx) type %d", in pcib_adjust_resource()
2151 * If our window isn't big enough to grow the sub-allocation in pcib_adjust_resource()
2154 if (start < w->base || end > w->limit) { in pcib_adjust_resource()
2155 wmask = ((rman_res_t)1 << w->step) - 1; in pcib_adjust_resource()
2157 MIN(start & ~wmask, w->base), in pcib_adjust_resource()
2158 MAX(end | wmask, w->limit)); in pcib_adjust_resource()
2162 device_printf(sc->dev, in pcib_adjust_resource()
2163 "grew %s window to %#jx-%#jx\n", in pcib_adjust_resource()
2164 w->name, (uintmax_t)w->base, in pcib_adjust_resource()
2165 (uintmax_t)w->limit); in pcib_adjust_resource()
2166 pcib_write_windows(sc, w->mask); in pcib_adjust_resource()
2245 for (int i = 0; i < w->count; i++) { in pcib_find_parent_resource()
2246 if (rman_get_start(w->res[i]) <= rman_get_start(r) && in pcib_find_parent_resource()
2247 rman_get_end(w->res[i]) >= rman_get_end(r)) in pcib_find_parent_resource()
2248 return (w->res[i]); in pcib_find_parent_resource()
2281 args.offset = start - rman_get_start(pres); in pcib_map_resource()
2306 * to the non-ARI slot/function. The downstream port will convert it back in
2318 if (sc->flags & PCIB_ENABLE_ARI) { in pcib_xlate_ari()
2320 ("Non-zero slot number with ARI enabled!")); in pcib_xlate_ari()
2331 ctl2 = pci_read_config(sc->dev, pcie_pos + PCIER_DEVICE_CTL2, 4); in pcib_enable_ari()
2333 pci_write_config(sc->dev, pcie_pos + PCIER_DEVICE_CTL2, ctl2, 4); in pcib_enable_ari()
2335 sc->flags |= PCIB_ENABLE_ARI; in pcib_enable_ari()
2370 if (sc->flags & PCIB_ENABLE_ARI) in pcib_ari_maxslots()
2383 if (sc->flags & PCIB_ENABLE_ARI) in pcib_ari_maxfuncs()
2398 if (sc->flags & PCIB_ENABLE_ARI) { in pcib_ari_decode_rid()
2460 * The PCI standard defines a swizzle of the child-side device/intpin to in pcib_route_interrupt()
2461 * the parent-side intpin as follows. in pcib_route_interrupt()
2464 * child_intpin = intpin on child bus slot (0-3) in pcib_route_interrupt()
2465 * parent_intpin = intpin on parent bus slot (0-3) in pcib_route_interrupt()
2469 parent_intpin = (pci_get_slot(dev) + (pin - 1)) % 4; in pcib_route_interrupt()
2479 pci_get_slot(dev), 'A' + pin - 1, intnum); in pcib_route_interrupt()
2484 /* Pass request to alloc MSI/MSI-X messages up to the parent bridge. */
2491 if (sc->flags & PCIB_DISABLE_MSI) in pcib_alloc_msi()
2498 /* Pass request to release MSI/MSI-X messages up to the parent bridge. */
2508 /* Pass request to alloc an MSI-X message up to the parent bridge. */
2515 if (sc->flags & PCIB_DISABLE_MSIX) in pcib_alloc_msix()
2521 /* Pass request to release an MSI-X message up to the parent bridge. */
2531 /* Pass request to map MSI/MSI-X message up to parent bridge. */
2565 return ((sc->flags & PCIB_ENABLE_ARI) != 0); in pcib_ari_enabled()
2583 if (sc->flags & PCIB_ENABLE_ARI) { in pcib_ari_get_id()
2681 * the firmware overrides the method of PCI-PCI bridges. in pcib_request_feature()
2721 if (pdinfo->cfg.pcie.pcie_location != 0 && in pcib_reset_child()
2722 (pdinfo->cfg.pcie.pcie_type == PCIEM_TYPE_DOWNSTREAM_PORT || in pcib_reset_child()
2723 pdinfo->cfg.pcie.pcie_type == PCIEM_TYPE_ROOT_PORT)) { in pcib_reset_child()
2727 pdinfo->cfg.pcie.pcie_location); in pcib_reset_child()