1 /* $NetBSD: acpi_pci_machdep.c,v 1.20 2021/08/08 12:09:52 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 2018, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jared McNeill <jmcneill@invisible.ca>. 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 #include "opt_pci.h" 33 34 #define _INTR_PRIVATE 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.20 2021/08/08 12:09:52 jmcneill Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/bus.h> 41 #include <sys/device.h> 42 #include <sys/intr.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/queue.h> 46 #include <sys/mutex.h> 47 #include <sys/kmem.h> 48 #include <sys/cpu.h> 49 50 #include <arm/cpufunc.h> 51 52 #include <arm/pic/picvar.h> 53 54 #include <dev/pci/pcireg.h> 55 #include <dev/pci/pcivar.h> 56 #include <dev/pci/pciconf.h> 57 58 #include <dev/acpi/acpivar.h> 59 #include <dev/acpi/acpi_mcfg.h> 60 #include <dev/acpi/acpi_pci.h> 61 62 #include <arm/acpi/acpi_iort.h> 63 #include <arm/acpi/acpi_pci_machdep.h> 64 65 #ifdef PCI_SMCCC 66 #include <arm/pci/pci_smccc.h> 67 #endif 68 69 #include <arm/pci/pci_msi_machdep.h> 70 71 struct acpi_pci_prt { 72 u_int prt_segment; 73 u_int prt_bus; 74 ACPI_HANDLE prt_handle; 75 TAILQ_ENTRY(acpi_pci_prt) prt_list; 76 }; 77 78 static TAILQ_HEAD(, acpi_pci_prt) acpi_pci_irq_routes = 79 TAILQ_HEAD_INITIALIZER(acpi_pci_irq_routes); 80 81 struct acpi_pci_pct { 82 struct acpi_pci_context pct_ap; 83 TAILQ_ENTRY(acpi_pci_pct) pct_list; 84 }; 85 86 static TAILQ_HEAD(, acpi_pci_pct) acpi_pci_chipset_tags = 87 TAILQ_HEAD_INITIALIZER(acpi_pci_chipset_tags); 88 89 struct acpi_pci_intr; 90 91 struct acpi_pci_intr { 92 struct pic_softc pi_pic; 93 int pi_irqbase; 94 int pi_irq; 95 uint32_t pi_unblocked; 96 void *pi_ih; 97 TAILQ_ENTRY(acpi_pci_intr) pi_list; 98 }; 99 100 static TAILQ_HEAD(, acpi_pci_intr) acpi_pci_intrs = 101 TAILQ_HEAD_INITIALIZER(acpi_pci_intrs); 102 103 static const struct acpi_pci_quirk acpi_pci_mcfg_quirks[] = { 104 /* OEM ID OEM Table ID Revision Seg Func */ 105 { "AMAZON", "GRAVITON", 0, -1, acpi_pci_graviton_init }, 106 { "ARMLTD", "ARMN1SDP", 0x20181101, 0, acpi_pci_n1sdp_init }, 107 { "ARMLTD", "ARMN1SDP", 0x20181101, 1, acpi_pci_n1sdp_init }, 108 { "NXP ", "LX2160 ", 0, -1, acpi_pci_layerscape_gen4_init }, 109 }; 110 111 #ifdef PCI_SMCCC 112 static const struct acpi_pci_quirk acpi_pci_smccc_quirk = { 113 .q_segment = -1, 114 .q_init = acpi_pci_smccc_init, 115 }; 116 #endif 117 118 pci_chipset_tag_t acpi_pci_md_get_chipset_tag(struct acpi_softc *, int, int); 119 120 static void acpi_pci_md_attach_hook(device_t, device_t, 121 struct pcibus_attach_args *); 122 static int acpi_pci_md_bus_maxdevs(void *, int); 123 static pcitag_t acpi_pci_md_make_tag(void *, int, int, int); 124 static void acpi_pci_md_decompose_tag(void *, pcitag_t, int *, int *, int *); 125 static u_int acpi_pci_md_get_segment(void *); 126 static uint32_t acpi_pci_md_get_devid(void *, uint32_t); 127 static uint32_t acpi_pci_md_get_frameid(void *, uint32_t); 128 static pcireg_t acpi_pci_md_conf_read(void *, pcitag_t, int); 129 static void acpi_pci_md_conf_write(void *, pcitag_t, int, pcireg_t); 130 static int acpi_pci_md_conf_hook(void *, int, int, int, pcireg_t); 131 static void acpi_pci_md_conf_interrupt(void *, int, int, int, int, int *); 132 133 static int acpi_pci_md_intr_map(const struct pci_attach_args *, 134 pci_intr_handle_t *); 135 static const char *acpi_pci_md_intr_string(void *, pci_intr_handle_t, 136 char *, size_t); 137 static const struct evcnt *acpi_pci_md_intr_evcnt(void *, pci_intr_handle_t); 138 static int acpi_pci_md_intr_setattr(void *, pci_intr_handle_t *, int, 139 uint64_t); 140 static void * acpi_pci_md_intr_establish(void *, pci_intr_handle_t, 141 int, int (*)(void *), void *, 142 const char *); 143 static void acpi_pci_md_intr_disestablish(void *, void *); 144 145 struct arm32_pci_chipset arm_acpi_pci_chipset = { 146 .pc_attach_hook = acpi_pci_md_attach_hook, 147 .pc_bus_maxdevs = acpi_pci_md_bus_maxdevs, 148 .pc_make_tag = acpi_pci_md_make_tag, 149 .pc_decompose_tag = acpi_pci_md_decompose_tag, 150 .pc_get_segment = acpi_pci_md_get_segment, 151 .pc_get_devid = acpi_pci_md_get_devid, 152 .pc_get_frameid = acpi_pci_md_get_frameid, 153 .pc_conf_read = acpi_pci_md_conf_read, 154 .pc_conf_write = acpi_pci_md_conf_write, 155 .pc_conf_hook = acpi_pci_md_conf_hook, 156 .pc_conf_interrupt = acpi_pci_md_conf_interrupt, 157 158 .pc_intr_map = acpi_pci_md_intr_map, 159 .pc_intr_string = acpi_pci_md_intr_string, 160 .pc_intr_evcnt = acpi_pci_md_intr_evcnt, 161 .pc_intr_setattr = acpi_pci_md_intr_setattr, 162 .pc_intr_establish = acpi_pci_md_intr_establish, 163 .pc_intr_disestablish = acpi_pci_md_intr_disestablish, 164 }; 165 166 static ACPI_STATUS 167 acpi_pci_md_pci_link(ACPI_HANDLE handle, pci_chipset_tag_t pc, int bus) 168 { 169 ACPI_PCI_ROUTING_TABLE *prt; 170 ACPI_HANDLE linksrc; 171 ACPI_BUFFER buf; 172 ACPI_STATUS rv; 173 void *linkdev; 174 175 rv = acpi_get(handle, &buf, AcpiGetIrqRoutingTable); 176 if (ACPI_FAILURE(rv)) 177 return rv; 178 179 for (char *p = buf.Pointer; ; p += prt->Length) { 180 prt = (ACPI_PCI_ROUTING_TABLE *)p; 181 if (prt->Length == 0) 182 break; 183 184 const u_int dev = ACPI_HIWORD(prt->Address); 185 if (prt->Source[0] != 0) { 186 aprint_debug("ACPI: %s dev %u INT%c on lnkdev %s\n", 187 acpi_name(handle), dev, 'A' + (prt->Pin & 3), prt->Source); 188 rv = AcpiGetHandle(ACPI_ROOT_OBJECT, prt->Source, &linksrc); 189 if (ACPI_FAILURE(rv)) { 190 aprint_debug("ACPI: AcpiGetHandle failed for '%s': %s\n", 191 prt->Source, AcpiFormatException(rv)); 192 continue; 193 } 194 195 linkdev = acpi_pci_link_devbyhandle(linksrc); 196 acpi_pci_link_add_reference(linkdev, pc, 0, bus, dev, prt->Pin & 3); 197 } else { 198 aprint_debug("ACPI: %s dev %u INT%c on globint %d\n", 199 acpi_name(handle), dev, 'A' + (prt->Pin & 3), prt->SourceIndex); 200 } 201 } 202 203 return AE_OK; 204 } 205 206 static void 207 acpi_pci_md_attach_hook(device_t parent, device_t self, 208 struct pcibus_attach_args *pba) 209 { 210 struct acpi_pci_context *ap = pba->pba_pc->pc_conf_v; 211 struct acpi_pci_prt *prt, *prtp; 212 struct acpi_devnode *ad; 213 ACPI_HANDLE handle; 214 int seg, bus, dev, func; 215 216 seg = ap->ap_seg; 217 handle = NULL; 218 219 if (pba->pba_bridgetag) { 220 /* 221 * Find the PCI address of our parent bridge and look for the 222 * corresponding ACPI device node. If there is no node for this 223 * bus, use the parent bridge routing information. 224 */ 225 acpi_pci_md_decompose_tag(NULL, *pba->pba_bridgetag, &bus, &dev, &func); 226 ad = acpi_pcidev_find(seg, bus, dev, func); 227 if (ad != NULL) { 228 handle = ad->ad_handle; 229 } else { 230 /* No routes defined for this bus, copy from parent */ 231 TAILQ_FOREACH(prtp, &acpi_pci_irq_routes, prt_list) 232 if (prtp->prt_bus == bus) { 233 handle = prtp->prt_handle; 234 break; 235 } 236 } 237 } else { 238 /* 239 * Lookup the ACPI device node for the root bus. 240 */ 241 ad = acpi_pciroot_find(seg, 0); 242 if (ad != NULL) 243 handle = ad->ad_handle; 244 } 245 246 if (handle != NULL) { 247 prt = kmem_alloc(sizeof(*prt), KM_SLEEP); 248 prt->prt_bus = pba->pba_bus; 249 prt->prt_segment = ap->ap_seg; 250 prt->prt_handle = handle; 251 TAILQ_INSERT_TAIL(&acpi_pci_irq_routes, prt, prt_list); 252 } 253 254 acpimcfg_map_bus(self, pba->pba_pc, pba->pba_bus); 255 256 if (ad != NULL) { 257 /* 258 * This is a new ACPI managed bus. Add PCI link references. 259 */ 260 acpi_pci_md_pci_link(ad->ad_handle, pba->pba_pc, pba->pba_bus); 261 } 262 } 263 264 static int 265 acpi_pci_md_bus_maxdevs(void *v, int busno) 266 { 267 return 32; 268 } 269 270 static pcitag_t 271 acpi_pci_md_make_tag(void *v, int b, int d, int f) 272 { 273 return (b << 16) | (d << 11) | (f << 8); 274 } 275 276 static void 277 acpi_pci_md_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 278 { 279 if (bp) 280 *bp = (tag >> 16) & 0xff; 281 if (dp) 282 *dp = (tag >> 11) & 0x1f; 283 if (fp) 284 *fp = (tag >> 8) & 0x7; 285 } 286 287 static u_int 288 acpi_pci_md_get_segment(void *v) 289 { 290 struct acpi_pci_context * const ap = v; 291 292 return ap->ap_seg; 293 } 294 295 static uint32_t 296 acpi_pci_md_get_devid(void *v, uint32_t devid) 297 { 298 struct acpi_pci_context * const ap = v; 299 300 return acpi_iort_pci_root_map(ap->ap_seg, devid); 301 } 302 303 static uint32_t 304 acpi_pci_md_get_frameid(void *v, uint32_t devid) 305 { 306 struct acpi_pci_context * const ap = v; 307 308 return acpi_iort_its_id_map(ap->ap_seg, devid); 309 } 310 311 static pcireg_t 312 acpi_pci_md_conf_read(void *v, pcitag_t tag, int offset) 313 { 314 struct acpi_pci_context * const ap = v; 315 pcireg_t val; 316 317 if (offset < 0 || offset >= PCI_EXTCONF_SIZE) 318 return (pcireg_t) -1; 319 320 if (ap->ap_conf_read != NULL) 321 ap->ap_conf_read(&ap->ap_pc, tag, offset, &val); 322 else 323 acpimcfg_conf_read(&ap->ap_pc, tag, offset, &val); 324 325 return val; 326 } 327 328 static void 329 acpi_pci_md_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val) 330 { 331 struct acpi_pci_context * const ap = v; 332 333 if (offset < 0 || offset >= PCI_EXTCONF_SIZE) 334 return; 335 336 if (ap->ap_conf_write != NULL) 337 ap->ap_conf_write(&ap->ap_pc, tag, offset, val); 338 else 339 acpimcfg_conf_write(&ap->ap_pc, tag, offset, val); 340 } 341 342 static int 343 acpi_pci_md_conf_hook(void *v, int b, int d, int f, pcireg_t id) 344 { 345 return PCI_CONF_DEFAULT; 346 } 347 348 static void 349 acpi_pci_md_conf_interrupt(void *v, int bus, int dev, int ipin, int sqiz, int *ilinep) 350 { 351 } 352 353 static struct acpi_pci_prt * 354 acpi_pci_md_intr_find_prt(pci_chipset_tag_t pc, u_int bus) 355 { 356 struct acpi_pci_prt *prt, *prtp; 357 u_int segment; 358 359 segment = pci_get_segment(pc); 360 361 prt = NULL; 362 TAILQ_FOREACH(prtp, &acpi_pci_irq_routes, prt_list) 363 if (prtp->prt_segment == segment && prtp->prt_bus == bus) { 364 prt = prtp; 365 break; 366 } 367 368 return prt; 369 } 370 371 static int 372 acpi_pci_md_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih) 373 { 374 struct acpi_pci_prt *prt; 375 ACPI_PCI_ROUTING_TABLE *tab; 376 int line, pol, trig, error; 377 ACPI_HANDLE linksrc; 378 ACPI_BUFFER buf; 379 void *linkdev; 380 381 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE) 382 return EINVAL; 383 384 prt = acpi_pci_md_intr_find_prt(pa->pa_pc, pa->pa_bus); 385 if (prt == NULL) 386 return ENXIO; 387 388 if (ACPI_FAILURE(acpi_get(prt->prt_handle, &buf, AcpiGetIrqRoutingTable))) 389 return EIO; 390 391 error = ENOENT; 392 for (char *p = buf.Pointer; ; p += tab->Length) { 393 tab = (ACPI_PCI_ROUTING_TABLE *)p; 394 if (tab->Length == 0) 395 break; 396 397 if (pa->pa_device == ACPI_HIWORD(tab->Address) && 398 (pa->pa_intrpin - 1) == (tab->Pin & 3)) { 399 if (tab->Source[0] != 0) { 400 if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, tab->Source, &linksrc))) 401 goto done; 402 linkdev = acpi_pci_link_devbyhandle(linksrc); 403 *ih = acpi_pci_link_route_interrupt(linkdev, 404 pa->pa_pc, tab->SourceIndex, 405 &line, &pol, &trig); 406 error = 0; 407 goto done; 408 } else { 409 *ih = tab->SourceIndex; 410 error = 0; 411 goto done; 412 } 413 } 414 } 415 416 done: 417 ACPI_FREE(buf.Pointer); 418 return error; 419 } 420 421 static const char * 422 acpi_pci_md_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len) 423 { 424 const int irq = __SHIFTOUT(ih, ARM_PCI_INTR_IRQ); 425 const int vec = __SHIFTOUT(ih, ARM_PCI_INTR_MSI_VEC); 426 427 if (ih & ARM_PCI_INTR_MSIX) 428 snprintf(buf, len, "irq %d (MSI-X vec %d)", irq, vec); 429 else if (ih & ARM_PCI_INTR_MSI) 430 snprintf(buf, len, "irq %d (MSI vec %d)", irq, vec); 431 else 432 snprintf(buf, len, "irq %d", irq); 433 434 return buf; 435 } 436 437 static const struct evcnt * 438 acpi_pci_md_intr_evcnt(void *v, pci_intr_handle_t ih) 439 { 440 return NULL; 441 } 442 443 static int 444 acpi_pci_md_intr_setattr(void *v, pci_intr_handle_t *ih, int attr, uint64_t data) 445 { 446 switch (attr) { 447 case PCI_INTR_MPSAFE: 448 if (data) 449 *ih |= ARM_PCI_INTR_MPSAFE; 450 else 451 *ih &= ~ARM_PCI_INTR_MPSAFE; 452 return 0; 453 default: 454 return ENODEV; 455 } 456 } 457 458 static struct acpi_pci_intr * 459 acpi_pci_md_intr_lookup(int irq) 460 { 461 struct acpi_pci_intr *pi; 462 463 TAILQ_FOREACH(pi, &acpi_pci_intrs, pi_list) 464 if (pi->pi_irq == irq) 465 return pi; 466 467 return NULL; 468 } 469 470 static void 471 acpi_pci_md_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irqmask) 472 { 473 struct acpi_pci_intr * const pi = (struct acpi_pci_intr *)pic; 474 475 pi->pi_unblocked |= irqmask; 476 } 477 478 static void 479 acpi_pci_md_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irqmask) 480 { 481 struct acpi_pci_intr * const pi = (struct acpi_pci_intr *)pic; 482 483 pi->pi_unblocked &= ~irqmask; 484 } 485 486 static int 487 acpi_pci_md_find_pending_irqs(struct pic_softc *pic) 488 { 489 struct acpi_pci_intr * const pi = (struct acpi_pci_intr *)pic; 490 491 pic_mark_pending_sources(pic, 0, pi->pi_unblocked); 492 493 return 1; 494 } 495 496 static void 497 acpi_pci_md_establish_irq(struct pic_softc *pic, struct intrsource *is) 498 { 499 } 500 501 static void 502 acpi_pci_md_source_name(struct pic_softc *pic, int irq, char *buf, size_t len) 503 { 504 snprintf(buf, len, "slot %d", irq); 505 } 506 507 static struct pic_ops acpi_pci_pic_ops = { 508 .pic_unblock_irqs = acpi_pci_md_unblock_irqs, 509 .pic_block_irqs = acpi_pci_md_block_irqs, 510 .pic_find_pending_irqs = acpi_pci_md_find_pending_irqs, 511 .pic_establish_irq = acpi_pci_md_establish_irq, 512 .pic_source_name = acpi_pci_md_source_name, 513 }; 514 515 static void * 516 acpi_pci_md_intr_establish(void *v, pci_intr_handle_t ih, int ipl, 517 int (*callback)(void *), void *arg, const char *xname) 518 { 519 struct acpi_pci_context * const ap = v; 520 struct acpi_pci_intr *pi; 521 int slot; 522 523 if ((ih & (ARM_PCI_INTR_MSI | ARM_PCI_INTR_MSIX)) != 0) 524 return arm_pci_msi_intr_establish(&ap->ap_pc, ih, ipl, callback, arg, xname); 525 526 const int irq = (int)__SHIFTOUT(ih, ARM_PCI_INTR_IRQ); 527 const int mpsafe = (ih & ARM_PCI_INTR_MPSAFE) ? IST_MPSAFE : 0; 528 529 pi = acpi_pci_md_intr_lookup(irq); 530 if (pi == NULL) { 531 pi = kmem_zalloc(sizeof(*pi), KM_SLEEP); 532 pi->pi_irq = irq; 533 snprintf(pi->pi_pic.pic_name, sizeof(pi->pi_pic.pic_name), 534 "PCI irq %d", irq); 535 pi->pi_pic.pic_maxsources = 32; 536 pi->pi_pic.pic_ops = &acpi_pci_pic_ops; 537 pi->pi_irqbase = pic_add(&pi->pi_pic, PIC_IRQBASE_ALLOC); 538 TAILQ_INSERT_TAIL(&acpi_pci_intrs, pi, pi_list); 539 pi->pi_ih = intr_establish_xname(irq, IPL_VM, IST_LEVEL | IST_MPSAFE, 540 pic_handle_intr, &pi->pi_pic, device_xname(ap->ap_dev)); 541 } 542 if (pi->pi_ih == NULL) 543 return NULL; 544 545 /* Find a free slot */ 546 for (slot = 0; slot < pi->pi_pic.pic_maxsources; slot++) 547 if (pi->pi_pic.pic_sources[slot] == NULL) 548 break; 549 if (slot == pi->pi_pic.pic_maxsources) 550 return NULL; 551 552 return intr_establish_xname(pi->pi_irqbase + slot, ipl, IST_LEVEL | mpsafe, 553 callback, arg, xname); 554 } 555 556 static void 557 acpi_pci_md_intr_disestablish(void *v, void *vih) 558 { 559 intr_disestablish(vih); 560 } 561 562 const struct acpi_pci_quirk * 563 acpi_pci_md_find_quirk(int seg) 564 { 565 ACPI_STATUS rv; 566 ACPI_TABLE_MCFG *mcfg; 567 u_int n; 568 569 rv = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg); 570 if (ACPI_FAILURE(rv)) { 571 #ifdef PCI_SMCCC 572 uint32_t ver = pci_smccc_version(); 573 aprint_debug("%s: SMCCC version %#x\n", __func__, ver); 574 if (PCI_SMCCC_SUCCESS(ver)) { 575 return &acpi_pci_smccc_quirk; 576 } 577 #endif 578 return NULL; 579 } 580 581 for (n = 0; n < __arraycount(acpi_pci_mcfg_quirks); n++) { 582 const struct acpi_pci_quirk *q = &acpi_pci_mcfg_quirks[n]; 583 if (memcmp(q->q_oemid, mcfg->Header.OemId, ACPI_OEM_ID_SIZE) == 0 && 584 memcmp(q->q_oemtableid, mcfg->Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE) == 0 && 585 q->q_oemrevision == mcfg->Header.OemRevision && 586 (q->q_segment == -1 || q->q_segment == seg)) 587 return q; 588 } 589 590 return NULL; 591 } 592 593 pci_chipset_tag_t 594 acpi_pci_md_get_chipset_tag(struct acpi_softc *sc, int seg, int bbn) 595 { 596 struct acpi_pci_pct *pct = NULL, *pctp; 597 const struct acpi_pci_quirk *q; 598 599 TAILQ_FOREACH(pctp, &acpi_pci_chipset_tags, pct_list) 600 if (pctp->pct_ap.ap_seg == seg) { 601 pct = pctp; 602 break; 603 } 604 605 if (pct == NULL) { 606 pct = kmem_zalloc(sizeof(*pct), KM_SLEEP); 607 pct->pct_ap.ap_dev = sc->sc_dev; 608 pct->pct_ap.ap_pc = arm_acpi_pci_chipset; 609 pct->pct_ap.ap_pc.pc_conf_v = &pct->pct_ap; 610 pct->pct_ap.ap_pc.pc_intr_v = &pct->pct_ap; 611 pct->pct_ap.ap_seg = seg; 612 pct->pct_ap.ap_bus = bbn; 613 pct->pct_ap.ap_maxbus = -1; 614 pct->pct_ap.ap_bst = acpi_softc->sc_memt; 615 616 q = acpi_pci_md_find_quirk(seg); 617 if (q != NULL) 618 q->q_init(&pct->pct_ap); 619 620 TAILQ_INSERT_TAIL(&acpi_pci_chipset_tags, pct, pct_list); 621 } 622 623 return &pct->pct_ap.ap_pc; 624 } 625 __strong_alias(acpi_get_pci_chipset_tag,acpi_pci_md_get_chipset_tag); 626