acpipci.c revision 1.5
1/*	$OpenBSD: acpipci.c,v 1.5 2018/08/11 20:46:48 kettenis Exp $	*/
2/*
3 * Copyright (c) 2018 Mark Kettenis
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/param.h>
19#include <sys/device.h>
20#include <sys/extent.h>
21#include <sys/malloc.h>
22#include <sys/systm.h>
23
24#include <machine/bus.h>
25
26#include <dev/acpi/acpireg.h>
27#include <dev/acpi/acpivar.h>
28#include <dev/acpi/acpidev.h>
29#include <dev/acpi/amltypes.h>
30#include <dev/acpi/dsdt.h>
31
32#include <dev/pci/pcidevs.h>
33#include <dev/pci/pcireg.h>
34#include <dev/pci/pcivar.h>
35#include <dev/pci/ppbreg.h>
36
37bus_addr_t pci_mcfg_addr;
38int pci_mcfg_min_bus, pci_mcfg_max_bus;
39bus_space_tag_t pci_mcfgt;
40bus_space_handle_t pci_mcfgh;
41
42struct acpipci_trans {
43	struct acpipci_trans *at_next;
44	bus_space_tag_t	at_iot;
45	bus_addr_t	at_base;
46	bus_size_t	at_size;
47	bus_size_t	at_offset;
48};
49
50struct acpipci_softc {
51	struct device	sc_dev;
52	struct acpi_softc *sc_acpi;
53	struct aml_node *sc_node;
54
55	bus_space_tag_t	sc_iot;
56	bus_space_handle_t sc_ioh;
57
58	struct bus_space sc_bus_iot;
59	struct bus_space sc_bus_memt;
60	struct acpipci_trans *sc_io_trans;
61	struct acpipci_trans *sc_mem_trans;
62
63	struct arm64_pci_chipset sc_pc;
64	struct extent	*sc_busex;
65	struct extent	*sc_memex;
66	struct extent	*sc_ioex;
67	char		sc_busex_name[32];
68	char		sc_ioex_name[32];
69	char		sc_memex_name[32];
70	int		sc_bus;
71	uint32_t	sc_seg;
72};
73
74int	acpipci_match(struct device *, void *, void *);
75void	acpipci_attach(struct device *, struct device *, void *);
76
77struct cfattach acpipci_ca = {
78	sizeof(struct acpipci_softc), acpipci_match, acpipci_attach
79};
80
81struct cfdriver acpipci_cd = {
82	NULL, "acpipci", DV_DULL
83};
84
85const char *acpipci_hids[] = {
86	"PNP0A08",
87	NULL
88};
89
90int	acpipci_parse_resources(int, union acpi_resource *, void *);
91int	acpipci_bs_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
92	    bus_space_handle_t *);
93
94void	acpipci_attach_hook(struct device *, struct device *,
95	    struct pcibus_attach_args *);
96int	acpipci_bus_maxdevs(void *, int);
97pcitag_t acpipci_make_tag(void *, int, int, int);
98void	acpipci_decompose_tag(void *, pcitag_t, int *, int *, int *);
99int	acpipci_conf_size(void *, pcitag_t);
100pcireg_t acpipci_conf_read(void *, pcitag_t, int);
101void	acpipci_conf_write(void *, pcitag_t, int, pcireg_t);
102
103int	acpipci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
104int	acpipci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
105int	acpipci_intr_map_msix(struct pci_attach_args *, int,
106	    pci_intr_handle_t *);
107const char *acpipci_intr_string(void *, pci_intr_handle_t);
108void	*acpipci_intr_establish(void *, pci_intr_handle_t, int,
109	    int (*)(void *), void *, char *);
110void	acpipci_intr_disestablish(void *, void *);
111
112uint32_t acpipci_iort_map_msi(pci_chipset_tag_t, pcitag_t);
113
114int
115acpipci_match(struct device *parent, void *match, void *aux)
116{
117	struct acpi_attach_args *aaa = aux;
118	struct cfdata *cf = match;
119
120	return acpi_matchhids(aaa, acpipci_hids, cf->cf_driver->cd_name);
121}
122
123void
124acpipci_attach(struct device *parent, struct device *self, void *aux)
125{
126	struct acpi_attach_args *aaa = aux;
127	struct acpipci_softc *sc = (struct acpipci_softc *)self;
128	struct pcibus_attach_args pba;
129	struct aml_value res;
130	uint64_t bbn = 0;
131	uint64_t seg = 0;
132
133	/* Bail out early if we don't have a valid MCFG table. */
134	if (pci_mcfg_addr == 0 || pci_mcfg_max_bus <= pci_mcfg_min_bus) {
135		printf(": no registers\n");
136		return;
137	}
138
139	sc->sc_acpi = (struct acpi_softc *)parent;
140	sc->sc_node = aaa->aaa_node;
141	printf(" %s", sc->sc_node->name);
142
143	if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
144		printf(": can't find resources\n");
145		return;
146	}
147
148	aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn);
149	sc->sc_bus = bbn;
150
151	aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg);
152	sc->sc_seg = seg;
153
154	sc->sc_iot = pci_mcfgt;
155	sc->sc_ioh = pci_mcfgh;
156
157	printf("\n");
158
159	/* XXX We only support segment 0 for now. */
160	if (seg != 0)
161		return;
162
163	/* Create extents for our address spaces. */
164	snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name),
165	    "%s pcibus", sc->sc_dev.dv_xname);
166	snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name),
167	    "%s pciio", sc->sc_dev.dv_xname);
168	snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name),
169	    "%s pcimem", sc->sc_dev.dv_xname);
170	sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255,
171	    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
172	sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff,
173	    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
174	sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1,
175	    M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
176
177	aml_parse_resource(&res, acpipci_parse_resources, sc);
178
179	memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot));
180	sc->sc_bus_iot.bus_private = sc->sc_io_trans;
181	sc->sc_bus_iot._space_map = acpipci_bs_map;
182	memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt));
183	sc->sc_bus_memt.bus_private = sc->sc_mem_trans;
184	sc->sc_bus_memt._space_map = acpipci_bs_map;
185
186	sc->sc_pc.pc_conf_v = sc;
187	sc->sc_pc.pc_attach_hook = acpipci_attach_hook;
188	sc->sc_pc.pc_bus_maxdevs = acpipci_bus_maxdevs;
189	sc->sc_pc.pc_make_tag = acpipci_make_tag;
190	sc->sc_pc.pc_decompose_tag = acpipci_decompose_tag;
191	sc->sc_pc.pc_conf_size = acpipci_conf_size;
192	sc->sc_pc.pc_conf_read = acpipci_conf_read;
193	sc->sc_pc.pc_conf_write = acpipci_conf_write;
194
195	sc->sc_pc.pc_intr_v = sc;
196	sc->sc_pc.pc_intr_map = acpipci_intr_map;
197	sc->sc_pc.pc_intr_map_msi = acpipci_intr_map_msi;
198	sc->sc_pc.pc_intr_map_msix = acpipci_intr_map_msix;
199	sc->sc_pc.pc_intr_string = acpipci_intr_string;
200	sc->sc_pc.pc_intr_establish = acpipci_intr_establish;
201	sc->sc_pc.pc_intr_disestablish = acpipci_intr_disestablish;
202
203	memset(&pba, 0, sizeof(pba));
204	pba.pba_busname = "pci";
205	pba.pba_iot = &sc->sc_bus_iot;
206	pba.pba_memt = &sc->sc_bus_memt;
207	pba.pba_dmat = aaa->aaa_dmat;
208	pba.pba_pc = &sc->sc_pc;
209	pba.pba_busex = sc->sc_busex;
210	pba.pba_ioex = sc->sc_ioex;
211	pba.pba_memex = sc->sc_memex;
212	pba.pba_domain = pci_ndomains++;
213	pba.pba_bus = sc->sc_bus;
214	pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
215
216	config_found(self, &pba, NULL);
217}
218
219int
220acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
221{
222	struct acpipci_softc *sc = arg;
223	struct acpipci_trans *at;
224	int type = AML_CRSTYPE(crs);
225	int restype, tflags;
226	u_long min, len = 0, tra;
227
228	switch (type) {
229	case LR_WORD:
230		restype = crs->lr_word.type;
231		tflags = crs->lr_word.tflags;
232		min = crs->lr_word._min;
233		len = crs->lr_word._len;
234		tra = crs->lr_word._tra;
235		break;
236	case LR_DWORD:
237		restype = crs->lr_dword.type;
238		tflags = crs->lr_dword.tflags;
239		min = crs->lr_dword._min;
240		len = crs->lr_dword._len;
241		tra = crs->lr_dword._tra;
242		break;
243	case LR_QWORD:
244		restype = crs->lr_qword.type;
245		tflags = crs->lr_qword.tflags;
246		min = crs->lr_qword._min;
247		len = crs->lr_qword._len;
248		tra = crs->lr_qword._tra;
249		break;
250	}
251
252	if (len == 0)
253		return 0;
254
255	switch (restype) {
256	case LR_TYPE_MEMORY:
257		if (tflags & LR_MEMORY_TTP)
258			return 0;
259		extent_free(sc->sc_memex, min, len, EX_WAITOK);
260		at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK);
261		at->at_iot = sc->sc_iot;
262		at->at_base = min;
263		at->at_size = len;
264		at->at_offset = tra;
265		at->at_next = sc->sc_mem_trans;
266		sc->sc_mem_trans = at;
267		break;
268	case LR_TYPE_IO:
269		if ((tflags & LR_IO_TTP) == 0)
270			return 0;
271		extent_free(sc->sc_ioex, min, len, EX_WAITOK);
272		at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK);
273		at->at_iot = sc->sc_iot;
274		at->at_base = min;
275		at->at_size = len;
276		at->at_offset = tra;
277		at->at_next = sc->sc_io_trans;
278		sc->sc_io_trans = at;
279		break;
280	case LR_TYPE_BUS:
281		extent_free(sc->sc_busex, min, len, EX_WAITOK);
282		break;
283	}
284
285	return 0;
286}
287
288void
289acpipci_attach_hook(struct device *parent, struct device *self,
290    struct pcibus_attach_args *pba)
291{
292}
293
294int
295acpipci_bus_maxdevs(void *v, int bus)
296{
297	return 32;
298}
299
300pcitag_t
301acpipci_make_tag(void *v, int bus, int device, int function)
302{
303	return ((bus << 20) | (device << 15) | (function << 12));
304}
305
306void
307acpipci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
308{
309	if (bp != NULL)
310		*bp = (tag >> 20) & 0xff;
311	if (dp != NULL)
312		*dp = (tag >> 15) & 0x1f;
313	if (fp != NULL)
314		*fp = (tag >> 12) & 0x7;
315}
316
317int
318acpipci_conf_size(void *v, pcitag_t tag)
319{
320	return PCIE_CONFIG_SPACE_SIZE;
321}
322
323pcireg_t
324acpipci_conf_read(void *v, pcitag_t tag, int reg)
325{
326	struct acpipci_softc *sc = v;
327
328	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, tag | reg);
329}
330
331void
332acpipci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
333{
334	struct acpipci_softc *sc = v;
335
336	bus_space_write_4(sc->sc_iot, sc->sc_ioh, tag | reg, data);
337}
338
339struct acpipci_intr_handle {
340	pci_chipset_tag_t	ih_pc;
341	pcitag_t		ih_tag;
342	int			ih_intrpin;
343	int			ih_msi;
344};
345
346int
347acpipci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
348{
349	struct acpipci_softc *sc = pa->pa_pc->pc_intr_v;
350	struct aml_node *node;
351	struct aml_value res;
352	uint64_t addr, pin, source, index;
353	struct acpipci_intr_handle *ih;
354	int i;
355
356	if (pa->pa_bridgetag == NULL)
357		return -1;
358
359	node = acpi_find_pci(pa->pa_pc, *pa->pa_bridgetag);
360	if (node == NULL)
361		return -1;
362
363	if (aml_evalname(sc->sc_acpi, node, "_PRT", 0, NULL, &res))
364		return -1;
365
366	if (res.type != AML_OBJTYPE_PACKAGE)
367		return -1;
368
369	for (i = 0; i < res.length; i++) {
370		struct aml_value *val = res.v_package[i];
371
372		if (val->type != AML_OBJTYPE_PACKAGE)
373			continue;
374		if (val->length != 4)
375			continue;
376		if (val->v_package[0]->type != AML_OBJTYPE_INTEGER ||
377		    val->v_package[1]->type != AML_OBJTYPE_INTEGER ||
378		    val->v_package[2]->type != AML_OBJTYPE_INTEGER ||
379		    val->v_package[3]->type != AML_OBJTYPE_INTEGER)
380			continue;
381
382		addr = val->v_package[0]->v_integer;
383		pin = val->v_package[1]->v_integer;
384		source = val->v_package[2]->v_integer;
385		index = val->v_package[3]->v_integer;
386		if (ACPI_ADR_PCIDEV(addr) != pa->pa_device ||
387		    ACPI_ADR_PCIFUN(addr) != 0xffff ||
388		    pin != pa->pa_intrpin - 1 || source != 0)
389			continue;
390
391		ih = malloc(sizeof(struct acpipci_intr_handle),
392		    M_DEVBUF, M_WAITOK);
393		ih->ih_pc = pa->pa_pc;
394		ih->ih_tag = pa->pa_tag;
395		ih->ih_intrpin = index;
396		ih->ih_msi = 0;
397		*ihp = (pci_intr_handle_t)ih;
398
399		return 0;
400	}
401
402	return -1;
403}
404
405int
406acpipci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
407{
408	pci_chipset_tag_t pc = pa->pa_pc;
409	pcitag_t tag = pa->pa_tag;
410	struct acpipci_intr_handle *ih;
411
412	if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 ||
413	    pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
414		return -1;
415
416	ih = malloc(sizeof(struct acpipci_intr_handle), M_DEVBUF, M_WAITOK);
417	ih->ih_pc = pa->pa_pc;
418	ih->ih_tag = pa->pa_tag;
419	ih->ih_intrpin = pa->pa_intrpin;
420	ih->ih_msi = 1;
421	*ihp = (pci_intr_handle_t)ih;
422
423	return 0;
424}
425
426int
427acpipci_intr_map_msix(struct pci_attach_args *pa, int vec,
428    pci_intr_handle_t *ihp)
429{
430	return -1;
431}
432
433const char *
434acpipci_intr_string(void *v, pci_intr_handle_t ihp)
435{
436	struct acpipci_intr_handle *ih = (struct acpipci_intr_handle *)ihp;
437	static char irqstr[32];
438
439	if (ih->ih_msi)
440		return "msi";
441
442	snprintf(irqstr, sizeof(irqstr), "irq %d", ih->ih_intrpin);
443	return irqstr;
444}
445
446void *
447acpipci_intr_establish(void *v, pci_intr_handle_t ihp, int level,
448    int (*func)(void *), void *arg, char *name)
449{
450	struct acpipci_intr_handle *ih = (struct acpipci_intr_handle *)ihp;
451	struct interrupt_controller *ic;
452	void *cookie;
453
454	extern LIST_HEAD(, interrupt_controller) interrupt_controllers;
455	LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
456		if (ic->ic_establish_msi)
457			break;
458	}
459	if (ic == NULL)
460		return NULL;
461
462	if (ih->ih_msi) {
463		uint64_t addr, data;
464		pcireg_t reg;
465		int off;
466
467		/* Map Requester ID through IORT to get sideband data. */
468		data = acpipci_iort_map_msi(ih->ih_pc, ih->ih_tag);
469		cookie = ic->ic_establish_msi(ic->ic_cookie, &addr,
470		    &data, level, func, arg, name);
471		if (cookie == NULL)
472			return NULL;
473
474		/* TODO: translate address to the PCI device's view */
475
476		if (pci_get_capability(ih->ih_pc, ih->ih_tag, PCI_CAP_MSI,
477		    &off, &reg) == 0)
478			panic("%s: no msi capability", __func__);
479
480		if (reg & PCI_MSI_MC_C64) {
481			pci_conf_write(ih->ih_pc, ih->ih_tag,
482			    off + PCI_MSI_MA, addr);
483			pci_conf_write(ih->ih_pc, ih->ih_tag,
484			    off + PCI_MSI_MAU32, addr >> 32);
485			pci_conf_write(ih->ih_pc, ih->ih_tag,
486			    off + PCI_MSI_MD64, data);
487		} else {
488			pci_conf_write(ih->ih_pc, ih->ih_tag,
489			    off + PCI_MSI_MA, addr);
490			pci_conf_write(ih->ih_pc, ih->ih_tag,
491			    off + PCI_MSI_MD32, data);
492		}
493		pci_conf_write(ih->ih_pc, ih->ih_tag,
494		    off, reg | PCI_MSI_MC_MSIE);
495	} else {
496		cookie = acpi_intr_establish(ih->ih_intrpin, 0, level,
497		    func, arg, name);
498	}
499
500	free(ih, M_DEVBUF, sizeof(struct acpipci_intr_handle));
501	return cookie;
502}
503
504void
505acpipci_intr_disestablish(void *v, void *cookie)
506{
507	panic("%s", __func__);
508}
509
510/*
511 * Translate memory address if needed.
512 */
513int
514acpipci_bs_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
515    int flags, bus_space_handle_t *bshp)
516{
517	struct acpipci_trans *at;
518
519	for (at = t->bus_private; at; at = at->at_next) {
520		if (addr >= at->at_base && addr < at->at_base + at->at_size) {
521			return bus_space_map(at->at_iot,
522			    addr + at->at_offset, size, flags, bshp);
523		}
524	}
525
526	return ENXIO;
527}
528
529struct arm64_pci_chipset pci_mcfg_chipset;
530
531pcireg_t
532pci_mcfg_conf_read(void *v, pcitag_t tag, int reg)
533{
534	return bus_space_read_4(pci_mcfgt, pci_mcfgh, tag | reg);
535}
536
537void
538pci_mcfg_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
539{
540	bus_space_write_4(pci_mcfgt, pci_mcfgh, tag | reg, data);
541}
542
543pci_chipset_tag_t
544pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int min_bus, int max_bus)
545{
546	pci_chipset_tag_t pc = &pci_mcfg_chipset;
547
548	pci_mcfgt = iot;
549	pci_mcfg_addr = addr;
550	pci_mcfg_min_bus = min_bus;
551	pci_mcfg_max_bus = max_bus;
552
553	if (bus_space_map(iot, addr, (pci_mcfg_max_bus + 1) << 20, 0,
554	    &pci_mcfgh))
555		panic("%s: can't map config space", __func__);
556
557	memset(pc, 0, sizeof(*pc));
558	pc->pc_bus_maxdevs = acpipci_bus_maxdevs;
559	pc->pc_make_tag = acpipci_make_tag;
560	pc->pc_decompose_tag = acpipci_decompose_tag;
561	pc->pc_conf_size = acpipci_conf_size;
562	pc->pc_conf_read = pci_mcfg_conf_read;
563	pc->pc_conf_write = pci_mcfg_conf_write;
564
565	return pc;
566}
567
568/*
569 * IORT support.
570 */
571
572struct acpi_iort {
573	struct acpi_table_header	hdr;
574#define IORT_SIG	"IORT"
575	uint32_t	number_of_nodes;
576	uint32_t	offset;
577	uint32_t	reserved;
578} __packed;
579
580struct acpi_iort_node {
581	uint8_t		type;
582#define ACPI_IORT_ITS		0
583#define ACPI_IORT_ROOT_COMPLEX	2
584	uint16_t	length;
585	uint8_t		revision;
586	uint32_t	reserved1;
587	uint32_t	number_of_mappings;
588	uint32_t	mapping_offset;
589	uint64_t	memory_access_properties;
590	uint32_t	atf_attributes;
591	uint32_t	segment;
592	uint8_t		memory_address_size_limit;
593	uint8_t		reserved2[3];
594} __packed;
595
596struct acpi_iort_mapping {
597	uint32_t	input_base;
598	uint32_t	length;
599	uint32_t	output_base;
600	uint32_t	output_reference;
601	uint32_t	flags;
602#define ACPI_IORT_MAPPING_SINGLE	0x00000001
603} __packed;
604
605uint32_t
606acpipci_iort_map_node(struct acpi_iort_node *node, uint32_t id, uint32_t reference)
607{
608	struct acpi_iort_mapping *map =
609	    (struct acpi_iort_mapping *)((char *)node + node->mapping_offset);
610	int i;
611
612	for (i = 0; i < node->number_of_mappings; i++) {
613		if (map[i].output_reference != reference)
614			continue;
615
616		if (map[i].flags & ACPI_IORT_MAPPING_SINGLE)
617			return map[i].output_base;
618
619		if (map[i].input_base <= id &&
620		    id < map[i].input_base + map[i].length)
621			return map[i].output_base + (id - map[i].input_base);
622	}
623
624	return id;
625}
626
627uint32_t
628acpipci_iort_map_msi(pci_chipset_tag_t pc, pcitag_t tag)
629{
630	struct acpipci_softc *sc = pc->pc_intr_v;
631	struct acpi_table_header *hdr;
632	struct acpi_iort *iort = NULL;
633	struct acpi_iort_node *node;
634	struct acpi_q *entry;
635	uint32_t rid, its = 0;
636	uint32_t offset;
637	int i;
638
639	rid = pci_requester_id(pc, tag);
640
641	/* Look for IORT table. */
642	SIMPLEQ_FOREACH(entry, &sc->sc_acpi->sc_tables, q_next) {
643		hdr = entry->q_table;
644		if (strncmp(hdr->signature, IORT_SIG,
645		    sizeof(hdr->signature)) == 0) {
646			iort = entry->q_table;
647			break;
648		}
649	}
650	if (iort == NULL)
651		return rid;
652
653	/* Find reference to ITS group. */
654	offset = iort->offset;
655	for (i = 0; i < iort->number_of_nodes; i++) {
656		node = (struct acpi_iort_node *)((char *)iort + offset);
657		switch (node->type) {
658		case ACPI_IORT_ITS:
659			its = offset;
660			break;
661		}
662		offset += node->length;
663	}
664	if (its == 0)
665		return rid;
666
667	/* Find our root complex and map. */
668	offset = iort->offset;
669	for (i = 0; i < iort->number_of_nodes; i++) {
670		node = (struct acpi_iort_node *)((char *)iort + offset);
671		switch (node->type) {
672		case ACPI_IORT_ROOT_COMPLEX:
673			if (node->segment == sc->sc_seg)
674				return acpipci_iort_map_node(node, rid, its);
675			break;
676		}
677		offset += node->length;
678	}
679
680	return rid;
681}
682