Tue Jan 26 15:30:05 2021 UTC ()
Trailing whitespace


(skrll)
diff -r1.22 -r1.23 src/sys/dev/acpi/acpi_mcfg.c

cvs diff -r1.22 -r1.23 src/sys/dev/acpi/acpi_mcfg.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_mcfg.c 2021/01/26 15:29:41 1.22
+++ src/sys/dev/acpi/acpi_mcfg.c 2021/01/26 15:30:05 1.23
@@ -1,946 +1,946 @@ @@ -1,946 +1,946 @@
1/* $NetBSD: acpi_mcfg.c,v 1.22 2021/01/26 15:29:41 skrll Exp $ */ 1/* $NetBSD: acpi_mcfg.c,v 1.23 2021/01/26 15:30:05 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (C) 2015 NONAKA Kimihiro <nonaka@NetBSD.org> 4 * Copyright (C) 2015 NONAKA Kimihiro <nonaka@NetBSD.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28#include "opt_pci.h" 28#include "opt_pci.h"
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.22 2021/01/26 15:29:41 skrll Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: acpi_mcfg.c,v 1.23 2021/01/26 15:30:05 skrll Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/kmem.h> 35#include <sys/kmem.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37 37
38#include <dev/pci/pcireg.h> 38#include <dev/pci/pcireg.h>
39#include <dev/pci/pcivar.h> 39#include <dev/pci/pcivar.h>
40#include <dev/pci/pciconf.h> 40#include <dev/pci/pciconf.h>
41#include <dev/pci/pcidevs.h> 41#include <dev/pci/pcidevs.h>
42 42
43#include <dev/acpi/acpireg.h> 43#include <dev/acpi/acpireg.h>
44#include <dev/acpi/acpivar.h> 44#include <dev/acpi/acpivar.h>
45#include <dev/acpi/acpi_mcfg.h> 45#include <dev/acpi/acpi_mcfg.h>
46 46
47#include "locators.h" 47#include "locators.h"
48 48
49#define _COMPONENT ACPI_RESOURCE_COMPONENT 49#define _COMPONENT ACPI_RESOURCE_COMPONENT
50ACPI_MODULE_NAME ("acpi_mcfg") 50ACPI_MODULE_NAME ("acpi_mcfg")
51 51
52#define EXTCONF_OFFSET(d, f, r) ((((d) * 8 + (f)) * PCI_EXTCONF_SIZE) + (r)) 52#define EXTCONF_OFFSET(d, f, r) ((((d) * 8 + (f)) * PCI_EXTCONF_SIZE) + (r))
53 53
54#define PCIDEV_SET_VALID(mb, d, f) ((mb)->valid_devs[(d)] |= __BIT((f))) 54#define PCIDEV_SET_VALID(mb, d, f) ((mb)->valid_devs[(d)] |= __BIT((f)))
55#define PCIDEV_SET_INVALID(mb, d, f) ((mb)->valid_devs[(d)] &= ~__BIT((f))) 55#define PCIDEV_SET_INVALID(mb, d, f) ((mb)->valid_devs[(d)] &= ~__BIT((f)))
56#define PCIDEV_IS_VALID(mb, d, f) ((mb)->valid_devs[(d)] & __BIT((f))) 56#define PCIDEV_IS_VALID(mb, d, f) ((mb)->valid_devs[(d)] & __BIT((f)))
57 57
58#define EXTCONF_SET_VALID(mb, d, f) ((mb)->valid_extconf[(d)] |= __BIT((f))) 58#define EXTCONF_SET_VALID(mb, d, f) ((mb)->valid_extconf[(d)] |= __BIT((f)))
59#define EXTCONF_SET_INVALID(mb, d, f) ((mb)->valid_extconf[(d)] &= ~__BIT((f))) 59#define EXTCONF_SET_INVALID(mb, d, f) ((mb)->valid_extconf[(d)] &= ~__BIT((f)))
60#define EXTCONF_IS_VALID(mb, d, f) ((mb)->valid_extconf[(d)] & __BIT((f))) 60#define EXTCONF_IS_VALID(mb, d, f) ((mb)->valid_extconf[(d)] & __BIT((f)))
61 61
62struct mcfg_segment { 62struct mcfg_segment {
63 uint64_t ms_address; /* Base address */ 63 uint64_t ms_address; /* Base address */
64 int ms_segment; /* Segment # */ 64 int ms_segment; /* Segment # */
65 int ms_bus_start; /* Start bus # */ 65 int ms_bus_start; /* Start bus # */
66 int ms_bus_end; /* End bus # */ 66 int ms_bus_end; /* End bus # */
67 bus_space_tag_t ms_bst; 67 bus_space_tag_t ms_bst;
68 struct mcfg_bus { 68 struct mcfg_bus {
69 bus_space_handle_t bsh[32][8]; 69 bus_space_handle_t bsh[32][8];
70 uint8_t valid_devs[32]; 70 uint8_t valid_devs[32];
71 uint8_t valid_extconf[32]; 71 uint8_t valid_extconf[32];
72 int valid_ndevs; 72 int valid_ndevs;
73 pcitag_t last_probed; 73 pcitag_t last_probed;
74 } *ms_bus; 74 } *ms_bus;
75}; 75};
76 76
77static struct mcfg_segment *mcfg_segs; 77static struct mcfg_segment *mcfg_segs;
78static int mcfg_nsegs; 78static int mcfg_nsegs;
79static ACPI_TABLE_MCFG *mcfg; 79static ACPI_TABLE_MCFG *mcfg;
80static int mcfg_inited; 80static int mcfg_inited;
81static struct acpi_softc *acpi_sc; 81static struct acpi_softc *acpi_sc;
82 82
83static const struct acpimcfg_ops mcfg_default_ops = { 83static const struct acpimcfg_ops mcfg_default_ops = {
84 .ao_validate = acpimcfg_default_validate, 84 .ao_validate = acpimcfg_default_validate,
85 85
86 .ao_read = acpimcfg_default_read, 86 .ao_read = acpimcfg_default_read,
87 .ao_write = acpimcfg_default_write, 87 .ao_write = acpimcfg_default_write,
88}; 88};
89static const struct acpimcfg_ops *mcfg_ops = &mcfg_default_ops; 89static const struct acpimcfg_ops *mcfg_ops = &mcfg_default_ops;
90 90
91/* 91/*
92 * default operations. 92 * default operations.
93 */ 93 */
94bool 94bool
95acpimcfg_default_validate(uint64_t address, int bus_start, int *bus_end) 95acpimcfg_default_validate(uint64_t address, int bus_start, int *bus_end)
96{ 96{
97 97
98 /* Always Ok */ 98 /* Always Ok */
99 return true; 99 return true;
100} 100}
101 101
102uint32_t 102uint32_t
103acpimcfg_default_read(bus_space_tag_t bst, bus_space_handle_t bsh, 103acpimcfg_default_read(bus_space_tag_t bst, bus_space_handle_t bsh,
104 bus_addr_t addr) 104 bus_addr_t addr)
105{ 105{
106 106
107 return bus_space_read_4(bst, bsh, addr); 107 return bus_space_read_4(bst, bsh, addr);
108} 108}
109 109
110void 110void
111acpimcfg_default_write(bus_space_tag_t bst, bus_space_handle_t bsh, 111acpimcfg_default_write(bus_space_tag_t bst, bus_space_handle_t bsh,
112 bus_addr_t addr, uint32_t data) 112 bus_addr_t addr, uint32_t data)
113{ 113{
114 114
115 bus_space_write_4(bst, bsh, addr, data); 115 bus_space_write_4(bst, bsh, addr, data);
116} 116}
117 117
118 118
119/* 119/*
120 * Check MCFG memory region at system resource 120 * Check MCFG memory region at system resource
121 */ 121 */
122struct acpimcfg_memrange { 122struct acpimcfg_memrange {
123 const char *hid; 123 const char *hid;
124 uint64_t address; 124 uint64_t address;
125 int bus_start; 125 int bus_start;
126 int bus_end; 126 int bus_end;
127 bool found; 127 bool found;
128}; 128};
129 129
130static ACPI_STATUS 130static ACPI_STATUS
131acpimcfg_parse_callback(ACPI_RESOURCE *res, void *ctx) 131acpimcfg_parse_callback(ACPI_RESOURCE *res, void *ctx)
132{ 132{
133 struct acpimcfg_memrange *mr = ctx; 133 struct acpimcfg_memrange *mr = ctx;
134 const char *type; 134 const char *type;
135 uint64_t size, mapaddr, mapsize; 135 uint64_t size, mapaddr, mapsize;
136 int n; 136 int n;
137 137
138 switch (res->Type) { 138 switch (res->Type) {
139 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 139 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
140 type = "FIXED_MEMORY32"; 140 type = "FIXED_MEMORY32";
141 mapaddr = res->Data.FixedMemory32.Address; 141 mapaddr = res->Data.FixedMemory32.Address;
142 mapsize = res->Data.FixedMemory32.AddressLength; 142 mapsize = res->Data.FixedMemory32.AddressLength;
143 break; 143 break;
144 144
145 case ACPI_RESOURCE_TYPE_ADDRESS32: 145 case ACPI_RESOURCE_TYPE_ADDRESS32:
146 /* XXX Only fixed size supported for now */ 146 /* XXX Only fixed size supported for now */
147 if (res->Data.Address32.Address.AddressLength == 0 || 147 if (res->Data.Address32.Address.AddressLength == 0 ||
148 res->Data.Address32.ProducerConsumer != ACPI_CONSUMER) 148 res->Data.Address32.ProducerConsumer != ACPI_CONSUMER)
149 goto out; 149 goto out;
150 150
151 if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE) 151 if (res->Data.Address32.ResourceType != ACPI_MEMORY_RANGE)
152 goto out; 152 goto out;
153 153
154 if (res->Data.Address32.MinAddressFixed != ACPI_ADDRESS_FIXED || 154 if (res->Data.Address32.MinAddressFixed != ACPI_ADDRESS_FIXED ||
155 res->Data.Address32.MaxAddressFixed != ACPI_ADDRESS_FIXED) 155 res->Data.Address32.MaxAddressFixed != ACPI_ADDRESS_FIXED)
156 goto out; 156 goto out;
157 157
158 type = "ADDRESS32"; 158 type = "ADDRESS32";
159 mapaddr = res->Data.Address32.Address.Minimum; 159 mapaddr = res->Data.Address32.Address.Minimum;
160 mapsize = res->Data.Address32.Address.AddressLength; 160 mapsize = res->Data.Address32.Address.AddressLength;
161 break; 161 break;
162 162
163#ifdef _LP64 163#ifdef _LP64
164 case ACPI_RESOURCE_TYPE_ADDRESS64: 164 case ACPI_RESOURCE_TYPE_ADDRESS64:
165 /* XXX Only fixed size supported for now */ 165 /* XXX Only fixed size supported for now */
166 if (res->Data.Address64.Address.AddressLength == 0 || 166 if (res->Data.Address64.Address.AddressLength == 0 ||
167 res->Data.Address64.ProducerConsumer != ACPI_CONSUMER) 167 res->Data.Address64.ProducerConsumer != ACPI_CONSUMER)
168 goto out; 168 goto out;
169 169
170 if (res->Data.Address64.ResourceType != ACPI_MEMORY_RANGE) 170 if (res->Data.Address64.ResourceType != ACPI_MEMORY_RANGE)
171 goto out; 171 goto out;
172 172
173 if (res->Data.Address64.MinAddressFixed != ACPI_ADDRESS_FIXED || 173 if (res->Data.Address64.MinAddressFixed != ACPI_ADDRESS_FIXED ||
174 res->Data.Address64.MaxAddressFixed != ACPI_ADDRESS_FIXED) 174 res->Data.Address64.MaxAddressFixed != ACPI_ADDRESS_FIXED)
175 goto out; 175 goto out;
176 176
177 type = "ADDRESS64"; 177 type = "ADDRESS64";
178 mapaddr = res->Data.Address64.Address.Minimum; 178 mapaddr = res->Data.Address64.Address.Minimum;
179 mapsize = res->Data.Address64.Address.AddressLength; 179 mapsize = res->Data.Address64.Address.AddressLength;
180 break; 180 break;
181#endif 181#endif
182 182
183 default: 183 default:
184 out: 184 out:
185 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d\n", 185 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d\n",
186 mr->hid, res->Type); 186 mr->hid, res->Type);
187 return_ACPI_STATUS(AE_OK); 187 return_ACPI_STATUS(AE_OK);
188 } 188 }
189 189
190 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d(%s), " 190 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: Type=%d(%s), "
191 "Address=0x%016" PRIx64 ", Length=0x%016" PRIx64 "\n", 191 "Address=0x%016" PRIx64 ", Length=0x%016" PRIx64 "\n",
192 mr->hid, res->Type, type, mapaddr, mapsize); 192 mr->hid, res->Type, type, mapaddr, mapsize);
193 193
194 if (mr->address < mapaddr || mr->address >= mapaddr + mapsize) 194 if (mr->address < mapaddr || mr->address >= mapaddr + mapsize)
195 return_ACPI_STATUS(AE_OK); 195 return_ACPI_STATUS(AE_OK);
196 196
197 size = (mr->bus_end - mr->bus_start + 1) * ACPIMCFG_SIZE_PER_BUS; 197 size = (mr->bus_end - mr->bus_start + 1) * ACPIMCFG_SIZE_PER_BUS;
198 198
199 /* full map */ 199 /* full map */
200 if (mr->address + size <= mapaddr + mapsize) { 200 if (mr->address + size <= mapaddr + mapsize) {
201 mr->found = true; 201 mr->found = true;
202 return_ACPI_STATUS(AE_CTRL_TERMINATE); 202 return_ACPI_STATUS(AE_CTRL_TERMINATE);
203 } 203 }
204 204
205 /* partial map */ 205 /* partial map */
206 n = (mapsize - (mr->address - mapaddr)) / ACPIMCFG_SIZE_PER_BUS; 206 n = (mapsize - (mr->address - mapaddr)) / ACPIMCFG_SIZE_PER_BUS;
207 /* bus_start == bus_end is not allowed. */ 207 /* bus_start == bus_end is not allowed. */
208 if (n > 1) { 208 if (n > 1) {
209 mr->bus_end = mr->bus_start + n - 1; 209 mr->bus_end = mr->bus_start + n - 1;
210 mr->found = true; 210 mr->found = true;
211 return_ACPI_STATUS(AE_CTRL_TERMINATE); 211 return_ACPI_STATUS(AE_CTRL_TERMINATE);
212 } 212 }
213 213
214 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d-%d, " 214 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d-%d, "
215 "address 0x%016" PRIx64 ": invalid size: request 0x%016" PRIx64 215 "address 0x%016" PRIx64 ": invalid size: request 0x%016" PRIx64
216 ", actual 0x%016" PRIx64 "\n", 216 ", actual 0x%016" PRIx64 "\n",
217 mr->bus_start, mr->bus_end, mr->address, size, mapsize); 217 mr->bus_start, mr->bus_end, mr->address, size, mapsize);
218 218
219 return_ACPI_STATUS(AE_OK); 219 return_ACPI_STATUS(AE_OK);
220} 220}
221 221
222static ACPI_STATUS 222static ACPI_STATUS
223acpimcfg_check_system_resource(ACPI_HANDLE handle, UINT32 level, void *ctx, 223acpimcfg_check_system_resource(ACPI_HANDLE handle, UINT32 level, void *ctx,
224 void **retval) 224 void **retval)
225{ 225{
226 struct acpimcfg_memrange *mr = ctx; 226 struct acpimcfg_memrange *mr = ctx;
227 ACPI_STATUS status; 227 ACPI_STATUS status;
228 228
229 status = AcpiWalkResources(handle, "_CRS", acpimcfg_parse_callback, mr); 229 status = AcpiWalkResources(handle, "_CRS", acpimcfg_parse_callback, mr);
230 if (ACPI_FAILURE(status)) 230 if (ACPI_FAILURE(status))
231 return_ACPI_STATUS(status); 231 return_ACPI_STATUS(status);
232 232
233 if (mr->found) 233 if (mr->found)
234 return_ACPI_STATUS(AE_CTRL_TERMINATE); 234 return_ACPI_STATUS(AE_CTRL_TERMINATE);
235 235
236 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: bus %d-%d, " 236 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: %s: bus %d-%d, "
237 "address 0x%016" PRIx64 ": no valid region\n", mr->hid, 237 "address 0x%016" PRIx64 ": no valid region\n", mr->hid,
238 mr->bus_start, mr->bus_end, mr->address); 238 mr->bus_start, mr->bus_end, mr->address);
239 239
240 return_ACPI_STATUS(AE_OK); 240 return_ACPI_STATUS(AE_OK);
241} 241}
242 242
243static bool 243static bool
244acpimcfg_find_system_resource(uint64_t address, int bus_start, int *bus_end) 244acpimcfg_find_system_resource(uint64_t address, int bus_start, int *bus_end)
245{ 245{
246 static const char *system_resource_hid[] = { 246 static const char *system_resource_hid[] = {
247 "PNP0C01", /* System Board */ 247 "PNP0C01", /* System Board */
248 "PNP0C02" /* General ID for reserving resources */ 248 "PNP0C02" /* General ID for reserving resources */
249 }; 249 };
250 struct acpimcfg_memrange mr; 250 struct acpimcfg_memrange mr;
251 ACPI_STATUS status; 251 ACPI_STATUS status;
252 int i; 252 int i;
253 253
254 mr.address = address; 254 mr.address = address;
255 mr.bus_start = bus_start; 255 mr.bus_start = bus_start;
256 mr.bus_end = *bus_end; 256 mr.bus_end = *bus_end;
257 mr.found = false; 257 mr.found = false;
258 258
259 for (i = 0; i < __arraycount(system_resource_hid); i++) { 259 for (i = 0; i < __arraycount(system_resource_hid); i++) {
260 mr.hid = system_resource_hid[i]; 260 mr.hid = system_resource_hid[i];
261 status = AcpiGetDevices(__UNCONST(system_resource_hid[i]), 261 status = AcpiGetDevices(__UNCONST(system_resource_hid[i]),
262 acpimcfg_check_system_resource, &mr, NULL); 262 acpimcfg_check_system_resource, &mr, NULL);
263 if (ACPI_FAILURE(status)) 263 if (ACPI_FAILURE(status))
264 continue; 264 continue;
265 if (mr.found) { 265 if (mr.found) {
266 *bus_end = mr.bus_end; 266 *bus_end = mr.bus_end;
267 return true; 267 return true;
268 } 268 }
269 } 269 }
270 return false; 270 return false;
271} 271}
272 272
273 273
274/* 274/*
275 * ACPI MCFG 275 * ACPI MCFG
276 */ 276 */
277void 277void
278acpimcfg_probe(struct acpi_softc *sc) 278acpimcfg_probe(struct acpi_softc *sc)
279{ 279{
280 ACPI_MCFG_ALLOCATION *ama; 280 ACPI_MCFG_ALLOCATION *ama;
281 ACPI_STATUS status; 281 ACPI_STATUS status;
282 uint32_t offset; 282 uint32_t offset;
283 int i, nsegs; 283 int i, nsegs;
284 284
285 if (acpi_sc != NULL) 285 if (acpi_sc != NULL)
286 panic("acpi_sc != NULL"); 286 panic("acpi_sc != NULL");
287 acpi_sc = sc; 287 acpi_sc = sc;
288 288
289 status = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg); 289 status = AcpiGetTable(ACPI_SIG_MCFG, 0, (ACPI_TABLE_HEADER **)&mcfg);
290 if (ACPI_FAILURE(status)) { 290 if (ACPI_FAILURE(status)) {
291 mcfg = NULL; 291 mcfg = NULL;
292 return; 292 return;
293 } 293 }
294 294
295 nsegs = 0; 295 nsegs = 0;
296 offset = sizeof(ACPI_TABLE_MCFG); 296 offset = sizeof(ACPI_TABLE_MCFG);
297 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset); 297 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
298 for (i = 0; offset + sizeof(ACPI_MCFG_ALLOCATION) <= 298 for (i = 0; offset + sizeof(ACPI_MCFG_ALLOCATION) <=
299 mcfg->Header.Length; i++) { 299 mcfg->Header.Length; i++) {
300 aprint_debug_dev(sc->sc_dev, 300 aprint_debug_dev(sc->sc_dev,
301 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n", 301 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n",
302 ama->PciSegment, ama->StartBusNumber, ama->EndBusNumber, 302 ama->PciSegment, ama->StartBusNumber, ama->EndBusNumber,
303 ama->Address); 303 ama->Address);
304 nsegs++; 304 nsegs++;
305 offset += sizeof(ACPI_MCFG_ALLOCATION); 305 offset += sizeof(ACPI_MCFG_ALLOCATION);
306 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset); 306 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
307 } 307 }
308 if (nsegs == 0) { 308 if (nsegs == 0) {
309 mcfg = NULL; 309 mcfg = NULL;
310 return; 310 return;
311 } 311 }
312 312
313 mcfg_segs = kmem_zalloc(sizeof(*mcfg_segs) * nsegs, KM_SLEEP); 313 mcfg_segs = kmem_zalloc(sizeof(*mcfg_segs) * nsegs, KM_SLEEP);
314 mcfg_nsegs = nsegs; 314 mcfg_nsegs = nsegs;
315} 315}
316 316
317int 317int
318acpimcfg_init(bus_space_tag_t memt, const struct acpimcfg_ops *ops) 318acpimcfg_init(bus_space_tag_t memt, const struct acpimcfg_ops *ops)
319{ 319{
320 ACPI_MCFG_ALLOCATION *ama; 320 ACPI_MCFG_ALLOCATION *ama;
321 struct mcfg_segment *seg; 321 struct mcfg_segment *seg;
322 uint32_t offset; 322 uint32_t offset;
323 int i, n, nsegs, bus_end; 323 int i, n, nsegs, bus_end;
324 324
325 if (mcfg == NULL) 325 if (mcfg == NULL)
326 return ENXIO; 326 return ENXIO;
327 327
328 if (mcfg_inited) 328 if (mcfg_inited)
329 return 0; 329 return 0;
330 330
331 if (ops != NULL) 331 if (ops != NULL)
332 mcfg_ops = ops; 332 mcfg_ops = ops;
333 333
334 nsegs = 0; 334 nsegs = 0;
335 offset = sizeof(ACPI_TABLE_MCFG); 335 offset = sizeof(ACPI_TABLE_MCFG);
336 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset); 336 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
337 for (i = 0; offset < mcfg->Header.Length; i++) { 337 for (i = 0; offset < mcfg->Header.Length; i++) {
338#ifndef _LP64 338#ifndef _LP64
339 if (ama->Address >= 0x100000000ULL) { 339 if (ama->Address >= 0x100000000ULL) {
340 aprint_debug_dev(acpi_sc->sc_dev, 340 aprint_debug_dev(acpi_sc->sc_dev,
341 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 341 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
342 ": ignore (64bit address)\n", ama->PciSegment, 342 ": ignore (64bit address)\n", ama->PciSegment,
343 ama->StartBusNumber, ama->EndBusNumber, 343 ama->StartBusNumber, ama->EndBusNumber,
344 ama->Address); 344 ama->Address);
345 goto next; 345 goto next;
346 } 346 }
347#endif 347#endif
348 /* 348 /*
349 * Some (broken?) BIOSen have an MCFG table for an empty 349 * Some (broken?) BIOSen have an MCFG table for an empty
350 * bus range. Ignore those tables. 350 * bus range. Ignore those tables.
351 */ 351 */
352 if (ama->StartBusNumber > ama->EndBusNumber) { 352 if (ama->StartBusNumber > ama->EndBusNumber) {
353 aprint_debug_dev(acpi_sc->sc_dev, 353 aprint_debug_dev(acpi_sc->sc_dev,
354 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 354 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
355 ": ignore (bus %d > %d)\n", ama->PciSegment, 355 ": ignore (bus %d > %d)\n", ama->PciSegment,
356 ama->StartBusNumber, ama->EndBusNumber, 356 ama->StartBusNumber, ama->EndBusNumber,
357 ama->Address, ama->StartBusNumber, 357 ama->Address, ama->StartBusNumber,
358 ama->EndBusNumber); 358 ama->EndBusNumber);
359 goto next; 359 goto next;
360 } 360 }
361 361
362 /* Validate MCFG memory range */ 362 /* Validate MCFG memory range */
363 bus_end = ama->EndBusNumber; 363 bus_end = ama->EndBusNumber;
364 if (mcfg_ops->ao_validate != NULL && 364 if (mcfg_ops->ao_validate != NULL &&
365 !mcfg_ops->ao_validate(ama->Address, ama->StartBusNumber, 365 !mcfg_ops->ao_validate(ama->Address, ama->StartBusNumber,
366 &bus_end)) { 366 &bus_end)) {
367 if (!acpimcfg_find_system_resource(ama->Address, 367 if (!acpimcfg_find_system_resource(ama->Address,
368 ama->StartBusNumber, &bus_end)) { 368 ama->StartBusNumber, &bus_end)) {
369 aprint_debug_dev(acpi_sc->sc_dev, 369 aprint_debug_dev(acpi_sc->sc_dev,
370 "MCFG: segment %d, bus %d-%d, " 370 "MCFG: segment %d, bus %d-%d, "
371 "address 0x%016" PRIx64 371 "address 0x%016" PRIx64
372 ": ignore (invalid address)\n", 372 ": ignore (invalid address)\n",
373 ama->PciSegment, 373 ama->PciSegment,
374 ama->StartBusNumber, ama->EndBusNumber, 374 ama->StartBusNumber, ama->EndBusNumber,
375 ama->Address); 375 ama->Address);
376 goto next; 376 goto next;
377 } 377 }
378 } 378 }
379 if (ama->EndBusNumber != bus_end) { 379 if (ama->EndBusNumber != bus_end) {
380 aprint_debug_dev(acpi_sc->sc_dev, 380 aprint_debug_dev(acpi_sc->sc_dev,
381 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 381 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
382 " -> bus %d-%d\n", ama->PciSegment, 382 " -> bus %d-%d\n", ama->PciSegment,
383 ama->StartBusNumber, ama->EndBusNumber, 383 ama->StartBusNumber, ama->EndBusNumber,
384 ama->Address, ama->StartBusNumber, bus_end); 384 ama->Address, ama->StartBusNumber, bus_end);
385 } 385 }
386 386
387#ifndef __HAVE_PCI_GET_SEGMENT 387#ifndef __HAVE_PCI_GET_SEGMENT
388 if (ama->PciSegment != 0) { 388 if (ama->PciSegment != 0) {
389 aprint_debug_dev(acpi_sc->sc_dev, 389 aprint_debug_dev(acpi_sc->sc_dev,
390 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 390 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64
391 ": ignore (non PCI segment 0)\n", ama->PciSegment, 391 ": ignore (non PCI segment 0)\n", ama->PciSegment,
392 ama->StartBusNumber, bus_end, ama->Address); 392 ama->StartBusNumber, bus_end, ama->Address);
393 goto next; 393 goto next;
394 } 394 }
395#endif 395#endif
396 396
397 seg = &mcfg_segs[nsegs++]; 397 seg = &mcfg_segs[nsegs++];
398 seg->ms_address = ama->Address; 398 seg->ms_address = ama->Address;
399 seg->ms_segment = ama->PciSegment; 399 seg->ms_segment = ama->PciSegment;
400 seg->ms_bus_start = ama->StartBusNumber; 400 seg->ms_bus_start = ama->StartBusNumber;
401 seg->ms_bus_end = bus_end; 401 seg->ms_bus_end = bus_end;
402 seg->ms_bst = memt; 402 seg->ms_bst = memt;
403 n = seg->ms_bus_end - seg->ms_bus_start + 1; 403 n = seg->ms_bus_end - seg->ms_bus_start + 1;
404 seg->ms_bus = kmem_zalloc(sizeof(*seg->ms_bus) * n, KM_SLEEP); 404 seg->ms_bus = kmem_zalloc(sizeof(*seg->ms_bus) * n, KM_SLEEP);
405 405
406 next: 406 next:
407 offset += sizeof(ACPI_MCFG_ALLOCATION); 407 offset += sizeof(ACPI_MCFG_ALLOCATION);
408 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset); 408 ama = ACPI_ADD_PTR(ACPI_MCFG_ALLOCATION, mcfg, offset);
409 } 409 }
410 if (nsegs == 0) 410 if (nsegs == 0)
411 return ENOENT; 411 return ENOENT;
412 412
413 for (i = 0; i < nsegs; i++) { 413 for (i = 0; i < nsegs; i++) {
414 seg = &mcfg_segs[i]; 414 seg = &mcfg_segs[i];
415 aprint_verbose_dev(acpi_sc->sc_dev, 415 aprint_verbose_dev(acpi_sc->sc_dev,
416 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n", 416 "MCFG: segment %d, bus %d-%d, address 0x%016" PRIx64 "\n",
417 seg->ms_segment, seg->ms_bus_start, seg->ms_bus_end, 417 seg->ms_segment, seg->ms_bus_start, seg->ms_bus_end,
418 seg->ms_address); 418 seg->ms_address);
419 } 419 }
420 420
421 /* Update # of segment */ 421 /* Update # of segment */
422 mcfg_nsegs = nsegs; 422 mcfg_nsegs = nsegs;
423 mcfg_inited = true; 423 mcfg_inited = true;
424 424
425 return 0; 425 return 0;
426} 426}
427 427
428static int 428static int
429acpimcfg_ext_conf_is_aliased(pci_chipset_tag_t pc, pcitag_t tag) 429acpimcfg_ext_conf_is_aliased(pci_chipset_tag_t pc, pcitag_t tag)
430{ 430{
431 pcireg_t id; 431 pcireg_t id;
432 int i; 432 int i;
433 433
434 id = pci_conf_read(pc, tag, PCI_ID_REG); 434 id = pci_conf_read(pc, tag, PCI_ID_REG);
435 for (i = PCI_CONF_SIZE; i < PCI_EXTCONF_SIZE; i += PCI_CONF_SIZE) { 435 for (i = PCI_CONF_SIZE; i < PCI_EXTCONF_SIZE; i += PCI_CONF_SIZE) {
436 if (pci_conf_read(pc, tag, i) != id) 436 if (pci_conf_read(pc, tag, i) != id)
437 return false; 437 return false;
438 } 438 }
439 return true; 439 return true;
440} 440}
441 441
442static struct mcfg_segment * 442static struct mcfg_segment *
443acpimcfg_get_segment(pci_chipset_tag_t pc, int bus) 443acpimcfg_get_segment(pci_chipset_tag_t pc, int bus)
444{ 444{
445 struct mcfg_segment *seg; 445 struct mcfg_segment *seg;
446 u_int segment; 446 u_int segment;
447 int i; 447 int i;
448 448
449#ifdef __HAVE_PCI_GET_SEGMENT 449#ifdef __HAVE_PCI_GET_SEGMENT
450 segment = pci_get_segment(pc); 450 segment = pci_get_segment(pc);
451#else 451#else
452 segment = 0; 452 segment = 0;
453#endif 453#endif
454 454
455 for (i = 0; i < mcfg_nsegs; i++) { 455 for (i = 0; i < mcfg_nsegs; i++) {
456 seg = &mcfg_segs[i]; 456 seg = &mcfg_segs[i];
457 if (segment == seg->ms_segment && 457 if (segment == seg->ms_segment &&
458 bus >= seg->ms_bus_start && bus <= seg->ms_bus_end) 458 bus >= seg->ms_bus_start && bus <= seg->ms_bus_end)
459 return seg; 459 return seg;
460 } 460 }
461 return NULL; 461 return NULL;
462} 462}
463 463
464static int 464static int
465acpimcfg_device_probe(const struct pci_attach_args *pa) 465acpimcfg_device_probe(const struct pci_attach_args *pa)
466{ 466{
467 pci_chipset_tag_t pc = pa->pa_pc; 467 pci_chipset_tag_t pc = pa->pa_pc;
468 struct mcfg_segment *seg; 468 struct mcfg_segment *seg;
469 struct mcfg_bus *mb; 469 struct mcfg_bus *mb;
470 pcitag_t tag; 470 pcitag_t tag;
471 pcireg_t reg; 471 pcireg_t reg;
472 int bus = pa->pa_bus; 472 int bus = pa->pa_bus;
473 int dev = pa->pa_device; 473 int dev = pa->pa_device;
474 int func = pa->pa_function; 474 int func = pa->pa_function;
475 int last_dev, last_func, end_func; 475 int last_dev, last_func, end_func;
476 int alias = 0; 476 int alias = 0;
477 const struct pci_quirkdata *qd; 477 const struct pci_quirkdata *qd;
478 bool force_hasextcnf = false; 478 bool force_hasextcnf = false;
479 bool force_noextcnf = false; 479 bool force_noextcnf = false;
480 int i, j; 480 int i, j;
481 481
482 seg = acpimcfg_get_segment(pc, bus); 482 seg = acpimcfg_get_segment(pc, bus);
483 if (seg == NULL) 483 if (seg == NULL)
484 return 0; 484 return 0;
485 485
486 mb = &seg->ms_bus[bus - seg->ms_bus_start]; 486 mb = &seg->ms_bus[bus - seg->ms_bus_start];
487 tag = pci_make_tag(pc, bus, dev, func); 487 tag = pci_make_tag(pc, bus, dev, func);
488 488
489 /* Mark invalid between last probed device to probed device. */ 489 /* Mark invalid between last probed device to probed device. */
490 pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func); 490 pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func);
491 if (dev != 0 || func != 0) { 491 if (dev != 0 || func != 0) {
492 for (i = last_dev; i <= dev; i++) { 492 for (i = last_dev; i <= dev; i++) {
493 end_func = (i == dev) ? func : 8; 493 end_func = (i == dev) ? func : 8;
494 for (j = last_func; j < end_func; j++) { 494 for (j = last_func; j < end_func; j++) {
495 if (i == last_dev && j == last_func) 495 if (i == last_dev && j == last_func)
496 continue; 496 continue;
497 PCIDEV_SET_INVALID(mb, i, j); 497 PCIDEV_SET_INVALID(mb, i, j);
498 } 498 }
499 last_func = 0; 499 last_func = 0;
500 } 500 }
501 } 501 }
502 mb->last_probed = tag; 502 mb->last_probed = tag;
503 503
504 reg = pci_conf_read(pc, tag, PCI_ID_REG); 504 reg = pci_conf_read(pc, tag, PCI_ID_REG);
505 qd = pci_lookup_quirkdata(PCI_VENDOR(reg), PCI_PRODUCT(reg)); 505 qd = pci_lookup_quirkdata(PCI_VENDOR(reg), PCI_PRODUCT(reg));
506 if (qd != NULL && (qd->quirks & PCI_QUIRK_HASEXTCNF) != 0) 506 if (qd != NULL && (qd->quirks & PCI_QUIRK_HASEXTCNF) != 0)
507 force_hasextcnf = true; 507 force_hasextcnf = true;
508 if (qd != NULL && (qd->quirks & PCI_QUIRK_NOEXTCNF) != 0) 508 if (qd != NULL && (qd->quirks & PCI_QUIRK_NOEXTCNF) != 0)
509 force_noextcnf = true; 509 force_noextcnf = true;
510  510
511 /* Probe extended configuration space. */ 511 /* Probe extended configuration space. */
512 if ((!force_hasextcnf) && ((force_noextcnf) || 512 if ((!force_hasextcnf) && ((force_noextcnf) ||
513 ((reg = pci_conf_read(pc, tag, PCI_CONF_SIZE)) == (pcireg_t)-1) 513 ((reg = pci_conf_read(pc, tag, PCI_CONF_SIZE)) == (pcireg_t)-1)
514 || (reg == 0) 514 || (reg == 0)
515 || (alias = acpimcfg_ext_conf_is_aliased(pc, tag)))) { 515 || (alias = acpimcfg_ext_conf_is_aliased(pc, tag)))) {
516 aprint_debug_dev(acpi_sc->sc_dev, 516 aprint_debug_dev(acpi_sc->sc_dev,
517 "MCFG: %03d:%02d:%d: invalid config space " 517 "MCFG: %03d:%02d:%d: invalid config space "
518 "(cfg[0x%03x]=0x%08x, alias=%s)\n", bus, dev, func, 518 "(cfg[0x%03x]=0x%08x, alias=%s)\n", bus, dev, func,
519 PCI_CONF_SIZE, reg, alias ? "true" : "false"); 519 PCI_CONF_SIZE, reg, alias ? "true" : "false");
520 EXTCONF_SET_INVALID(mb, dev, func); 520 EXTCONF_SET_INVALID(mb, dev, func);
521 } 521 }
522 522
523 aprint_debug_dev(acpi_sc->sc_dev, 523 aprint_debug_dev(acpi_sc->sc_dev,
524 "MCFG: %03d:%02d:%d: Ok (cfg[0x%03x]=0x%08x extconf=%c)\n", 524 "MCFG: %03d:%02d:%d: Ok (cfg[0x%03x]=0x%08x extconf=%c)\n",
525 bus, dev, func, PCI_CONF_SIZE, reg, 525 bus, dev, func, PCI_CONF_SIZE, reg,
526 EXTCONF_IS_VALID(mb, dev, func) ? 'Y' : 'N'); 526 EXTCONF_IS_VALID(mb, dev, func) ? 'Y' : 'N');
527 mb->valid_ndevs++; 527 mb->valid_ndevs++;
528 528
529 return 0; 529 return 0;
530} 530}
531 531
532#ifdef PCI_MACHDEP_ENUMERATE_BUS 532#ifdef PCI_MACHDEP_ENUMERATE_BUS
533#define pci_enumerate_bus PCI_MACHDEP_ENUMERATE_BUS 533#define pci_enumerate_bus PCI_MACHDEP_ENUMERATE_BUS
534#endif 534#endif
535 535
536static void 536static void
537acpimcfg_scan_bus(struct pci_softc *sc, pci_chipset_tag_t pc, int bus) 537acpimcfg_scan_bus(struct pci_softc *sc, pci_chipset_tag_t pc, int bus)
538{ 538{
539 static const int wildcard[PCICF_NLOCS] = { 539 static const int wildcard[PCICF_NLOCS] = {
540 PCICF_DEV_DEFAULT, PCICF_FUNCTION_DEFAULT 540 PCICF_DEV_DEFAULT, PCICF_FUNCTION_DEFAULT
541 }; 541 };
542 542
543 sc->sc_bus = bus; /* XXX */ 543 sc->sc_bus = bus; /* XXX */
544 sc->sc_pc = pc; 544 sc->sc_pc = pc;
545 545
546 pci_enumerate_bus(sc, wildcard, acpimcfg_device_probe, NULL); 546 pci_enumerate_bus(sc, wildcard, acpimcfg_device_probe, NULL);
547} 547}
548 548
549int 549int
550acpimcfg_map_bus(device_t self, pci_chipset_tag_t pc, int bus) 550acpimcfg_map_bus(device_t self, pci_chipset_tag_t pc, int bus)
551{ 551{
552 struct pci_softc *sc = device_private(self); 552 struct pci_softc *sc = device_private(self);
553 struct mcfg_segment *seg = NULL; 553 struct mcfg_segment *seg = NULL;
554 struct mcfg_bus *mb; 554 struct mcfg_bus *mb;
555 bus_space_handle_t bsh; 555 bus_space_handle_t bsh;
556 bus_addr_t baddr; 556 bus_addr_t baddr;
557 pcitag_t tag; 557 pcitag_t tag;
558 pcireg_t reg; 558 pcireg_t reg;
559 bool is_e7520_mch; 559 bool is_e7520_mch;
560 int boff; 560 int boff;
561 int last_dev, last_func; 561 int last_dev, last_func;
562 int i, j; 562 int i, j;
563 int error; 563 int error;
564 564
565 if (!mcfg_inited) 565 if (!mcfg_inited)
566 return ENXIO; 566 return ENXIO;
567 567
568 seg = acpimcfg_get_segment(pc, bus); 568 seg = acpimcfg_get_segment(pc, bus);
569 if (seg == NULL) 569 if (seg == NULL)
570 return ENOENT; 570 return ENOENT;
571 571
572 boff = bus - seg->ms_bus_start; 572 boff = bus - seg->ms_bus_start;
573 if (seg->ms_bus[boff].valid_ndevs > 0) 573 if (seg->ms_bus[boff].valid_ndevs > 0)
574 return 0; 574 return 0;
575 575
576 mb = &seg->ms_bus[boff]; 576 mb = &seg->ms_bus[boff];
577 baddr = seg->ms_address + (bus * ACPIMCFG_SIZE_PER_BUS); 577 baddr = seg->ms_address + (bus * ACPIMCFG_SIZE_PER_BUS);
578 578
579 /* Map extended configuration space of all dev/func. */ 579 /* Map extended configuration space of all dev/func. */
580 error = bus_space_map(seg->ms_bst, baddr, ACPIMCFG_SIZE_PER_BUS, 0, 580 error = bus_space_map(seg->ms_bst, baddr, ACPIMCFG_SIZE_PER_BUS, 0,
581 &bsh); 581 &bsh);
582 if (error != 0) 582 if (error != 0)
583 return error; 583 return error;
584 for (i = 0; i < 32; i++) { 584 for (i = 0; i < 32; i++) {
585 for (j = 0; j < 8; j++) { 585 for (j = 0; j < 8; j++) {
586 error = bus_space_subregion(seg->ms_bst, bsh, 586 error = bus_space_subregion(seg->ms_bst, bsh,
587 EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE, 587 EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE,
588 &mb->bsh[i][j]); 588 &mb->bsh[i][j]);
589 if (error != 0) 589 if (error != 0)
590 break; 590 break;
591 } 591 }
592 } 592 }
593 if (error != 0) 593 if (error != 0)
594 return error; 594 return error;
595 595
596 aprint_debug("\n"); 596 aprint_debug("\n");
597 597
598 /* Probe extended configuration space of all devices. */ 598 /* Probe extended configuration space of all devices. */
599 memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs)); 599 memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs));
600 memset(mb->valid_extconf, 0xff, sizeof(mb->valid_extconf)); 600 memset(mb->valid_extconf, 0xff, sizeof(mb->valid_extconf));
601 mb->valid_ndevs = 0; 601 mb->valid_ndevs = 0;
602 mb->last_probed = pci_make_tag(pc, bus, 0, 0); 602 mb->last_probed = pci_make_tag(pc, bus, 0, 0);
603 603
604 /* 604 /*
605 * On an Intel E7520 we have to temporarily disable 605 * On an Intel E7520 we have to temporarily disable
606 * Enhanced Config Access error detection and reporting 606 * Enhanced Config Access error detection and reporting
607 * by setting the appropriate error mask in HI_ERRMASK register. 607 * by setting the appropriate error mask in HI_ERRMASK register.
608 * 608 *
609 * See "Intel E7520 Memory Controller Hub (MCH) Datasheet", 609 * See "Intel E7520 Memory Controller Hub (MCH) Datasheet",
610 * Document 303006-002, pg. 82 610 * Document 303006-002, pg. 82
611 */ 611 */
612 tag = pci_make_tag(pc, 0, 0, 1); 612 tag = pci_make_tag(pc, 0, 0, 1);
613 reg = pci_conf_read(pc, tag, PCI_ID_REG); 613 reg = pci_conf_read(pc, tag, PCI_ID_REG);
614 is_e7520_mch = (reg == 614 is_e7520_mch = (reg ==
615 PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_E7525_MCHER)); 615 PCI_ID_CODE(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_E7525_MCHER));
616 if (is_e7520_mch) { 616 if (is_e7520_mch) {
617 reg = pci_conf_read(pc, tag, 0x54); 617 reg = pci_conf_read(pc, tag, 0x54);
618 pci_conf_write(pc, tag, 0x54, reg | 0x20); 618 pci_conf_write(pc, tag, 0x54, reg | 0x20);
619 } 619 }
620 620
621 acpimcfg_scan_bus(sc, pc, bus); 621 acpimcfg_scan_bus(sc, pc, bus);
622 622
623 if (is_e7520_mch) { 623 if (is_e7520_mch) {
624 pci_conf_write(pc, tag, 0x54, reg); 624 pci_conf_write(pc, tag, 0x54, reg);
625 } 625 }
626 626
627 /* Unmap configuration space of all dev/func. */ 627 /* Unmap configuration space of all dev/func. */
628 bus_space_unmap(seg->ms_bst, bsh, ACPIMCFG_SIZE_PER_BUS); 628 bus_space_unmap(seg->ms_bst, bsh, ACPIMCFG_SIZE_PER_BUS);
629 memset(mb->bsh, 0, sizeof(mb->bsh)); 629 memset(mb->bsh, 0, sizeof(mb->bsh));
630 630
631 if (mb->valid_ndevs == 0) { 631 if (mb->valid_ndevs == 0) {
632 aprint_debug_dev(acpi_sc->sc_dev, 632 aprint_debug_dev(acpi_sc->sc_dev,
633 "MCFG: bus %d: no valid devices.\n", bus); 633 "MCFG: bus %d: no valid devices.\n", bus);
634 memset(mb->valid_devs, 0, sizeof(mb->valid_devs)); 634 memset(mb->valid_devs, 0, sizeof(mb->valid_devs));
635 goto out; 635 goto out;
636 } 636 }
637 637
638 /* Mark invalid on remaining all devices. */ 638 /* Mark invalid on remaining all devices. */
639 pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func); 639 pci_decompose_tag(pc, mb->last_probed, NULL, &last_dev, &last_func);
640 for (i = last_dev; i < 32; i++) { 640 for (i = last_dev; i < 32; i++) {
641 for (j = last_func; j < 8; j++) { 641 for (j = last_func; j < 8; j++) {
642 if (i == last_dev && j == last_func) { 642 if (i == last_dev && j == last_func) {
643 /* Don't mark invalid to last probed device. */ 643 /* Don't mark invalid to last probed device. */
644 continue; 644 continue;
645 } 645 }
646 PCIDEV_SET_INVALID(mb, i, j); 646 PCIDEV_SET_INVALID(mb, i, j);
647 } 647 }
648 last_func = 0; 648 last_func = 0;
649 } 649 }
650 650
651 /* Map configuration space per dev/func. */ 651 /* Map configuration space per dev/func. */
652 for (i = 0; i < 32; i++) { 652 for (i = 0; i < 32; i++) {
653 for (j = 0; j < 8; j++) { 653 for (j = 0; j < 8; j++) {
654 if (!PCIDEV_IS_VALID(mb, i, j)) 654 if (!PCIDEV_IS_VALID(mb, i, j))
655 continue; 655 continue;
656 error = bus_space_map(seg->ms_bst, 656 error = bus_space_map(seg->ms_bst,
657 baddr + EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE, 657 baddr + EXTCONF_OFFSET(i, j, 0), PCI_EXTCONF_SIZE,
658 0, &mb->bsh[i][j]); 658 0, &mb->bsh[i][j]);
659 if (error != 0) { 659 if (error != 0) {
660 /* Unmap all handles when map failed. */ 660 /* Unmap all handles when map failed. */
661 do { 661 do {
662 while (--j >= 0) { 662 while (--j >= 0) {
663 if (!PCIDEV_IS_VALID(mb, i, j)) 663 if (!PCIDEV_IS_VALID(mb, i, j))
664 continue; 664 continue;
665 bus_space_unmap(seg->ms_bst, 665 bus_space_unmap(seg->ms_bst,
666 mb->bsh[i][j], 666 mb->bsh[i][j],
667 PCI_EXTCONF_SIZE); 667 PCI_EXTCONF_SIZE);
668 } 668 }
669 j = 8; 669 j = 8;
670 } while (--i >= 0); 670 } while (--i >= 0);
671 memset(mb->valid_devs, 0, 671 memset(mb->valid_devs, 0,
672 sizeof(mb->valid_devs)); 672 sizeof(mb->valid_devs));
673 goto out; 673 goto out;
674 } 674 }
675 } 675 }
676 } 676 }
677 677
678 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d: valid devices\n", bus); 678 aprint_debug_dev(acpi_sc->sc_dev, "MCFG: bus %d: valid devices\n", bus);
679 for (i = 0; i < 32; i++) { 679 for (i = 0; i < 32; i++) {
680 for (j = 0; j < 8; j++) { 680 for (j = 0; j < 8; j++) {
681 if (PCIDEV_IS_VALID(mb, i, j)) { 681 if (PCIDEV_IS_VALID(mb, i, j)) {
682 aprint_debug_dev(acpi_sc->sc_dev, 682 aprint_debug_dev(acpi_sc->sc_dev,
683 "MCFG: %03d:%02d:%d\n", bus, i, j); 683 "MCFG: %03d:%02d:%d\n", bus, i, j);
684 } 684 }
685 } 685 }
686 } 686 }
687 687
688 error = 0; 688 error = 0;
689out: 689out:
690 aprint_debug_dev(acpi_sc->sc_dev, "%s done", __func__); 690 aprint_debug_dev(acpi_sc->sc_dev, "%s done", __func__);
691 691
692 return error; 692 return error;
693} 693}
694 694
695#ifdef PCI_NETBSD_CONFIGURE 695#ifdef PCI_NETBSD_CONFIGURE
696static ACPI_STATUS 696static ACPI_STATUS
697acpimcfg_configure_bus_cb(ACPI_RESOURCE *res, void *ctx) 697acpimcfg_configure_bus_cb(ACPI_RESOURCE *res, void *ctx)
698{ 698{
699 struct pciconf_resources *pcires = ctx; 699 struct pciconf_resources *pcires = ctx;
700 int type; 700 int type;
701 bus_addr_t addr; 701 bus_addr_t addr;
702 bus_size_t size; 702 bus_size_t size;
703 const char *s; 703 const char *s;
704 int error; 704 int error;
705 705
706 if (res->Type != ACPI_RESOURCE_TYPE_ADDRESS16 && 706 if (res->Type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
707 res->Type != ACPI_RESOURCE_TYPE_ADDRESS32 && 707 res->Type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
708 res->Type != ACPI_RESOURCE_TYPE_ADDRESS64) 708 res->Type != ACPI_RESOURCE_TYPE_ADDRESS64)
709 return AE_OK; 709 return AE_OK;
710 710
711 if (res->Data.Address.ProducerConsumer != ACPI_PRODUCER) 711 if (res->Data.Address.ProducerConsumer != ACPI_PRODUCER)
712 return AE_OK; 712 return AE_OK;
713 713
714 if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE && 714 if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE &&
715 res->Data.Address.ResourceType != ACPI_IO_RANGE) 715 res->Data.Address.ResourceType != ACPI_IO_RANGE)
716 return AE_OK; 716 return AE_OK;
717 717
718 if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE && 718 if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE &&
719 res->Data.Address.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) { 719 res->Data.Address.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY) {
720 type = PCICONF_RESOURCE_PREFETCHABLE_MEM; 720 type = PCICONF_RESOURCE_PREFETCHABLE_MEM;
721 s = "prefetchable"; 721 s = "prefetchable";
722 } else if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE && 722 } else if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE &&
723 res->Data.Address.Info.Mem.Caching != ACPI_PREFETCHABLE_MEMORY) { 723 res->Data.Address.Info.Mem.Caching != ACPI_PREFETCHABLE_MEMORY) {
724 type = PCICONF_RESOURCE_MEM; 724 type = PCICONF_RESOURCE_MEM;
725 s = "non-prefetchable"; 725 s = "non-prefetchable";
726 } else { 726 } else {
727 KASSERT(res->Data.Address.ResourceType == ACPI_IO_RANGE); 727 KASSERT(res->Data.Address.ResourceType == ACPI_IO_RANGE);
728 type = PCICONF_RESOURCE_IO; 728 type = PCICONF_RESOURCE_IO;
729 s = "i/o"; 729 s = "i/o";
730 } 730 }
731 731
732 switch (res->Type) { 732 switch (res->Type) {
733 case ACPI_RESOURCE_TYPE_ADDRESS16: 733 case ACPI_RESOURCE_TYPE_ADDRESS16:
734 aprint_debug( 734 aprint_debug(
735 "MCFG: range 0x%04" PRIx16 " size %#" PRIx16 " (16-bit %s)\n", 735 "MCFG: range 0x%04" PRIx16 " size %#" PRIx16 " (16-bit %s)\n",
736 res->Data.Address16.Address.Minimum, 736 res->Data.Address16.Address.Minimum,
737 res->Data.Address16.Address.AddressLength, 737 res->Data.Address16.Address.AddressLength,
738 s); 738 s);
739 addr = res->Data.Address16.Address.Minimum; 739 addr = res->Data.Address16.Address.Minimum;
740 size = res->Data.Address16.Address.AddressLength; 740 size = res->Data.Address16.Address.AddressLength;
741 break; 741 break;
742 case ACPI_RESOURCE_TYPE_ADDRESS32: 742 case ACPI_RESOURCE_TYPE_ADDRESS32:
743 aprint_debug( 743 aprint_debug(
744 "MCFG: range 0x%08" PRIx32 " size %#" PRIx32 " (32-bit %s)\n", 744 "MCFG: range 0x%08" PRIx32 " size %#" PRIx32 " (32-bit %s)\n",
745 res->Data.Address32.Address.Minimum, 745 res->Data.Address32.Address.Minimum,
746 res->Data.Address32.Address.AddressLength, 746 res->Data.Address32.Address.AddressLength,
747 s); 747 s);
748 addr = res->Data.Address32.Address.Minimum; 748 addr = res->Data.Address32.Address.Minimum;
749 size = res->Data.Address32.Address.AddressLength; 749 size = res->Data.Address32.Address.AddressLength;
750 break; 750 break;
751 case ACPI_RESOURCE_TYPE_ADDRESS64: 751 case ACPI_RESOURCE_TYPE_ADDRESS64:
752 aprint_debug( 752 aprint_debug(
753 "MCFG: range 0x%016" PRIx64 " size %#" PRIx64 " (64-bit %s)\n", 753 "MCFG: range 0x%016" PRIx64 " size %#" PRIx64 " (64-bit %s)\n",
754 res->Data.Address64.Address.Minimum, 754 res->Data.Address64.Address.Minimum,
755 res->Data.Address64.Address.AddressLength, 755 res->Data.Address64.Address.AddressLength,
756 s); 756 s);
757 addr = res->Data.Address64.Address.Minimum; 757 addr = res->Data.Address64.Address.Minimum;
758 size = res->Data.Address64.Address.AddressLength; 758 size = res->Data.Address64.Address.AddressLength;
759 break; 759 break;
760 760
761 default: 761 default:
762 return AE_OK; 762 return AE_OK;
763 } 763 }
764 764
765 error = pciconf_resource_add(pcires, type, addr, size); 765 error = pciconf_resource_add(pcires, type, addr, size);
766 766
767 return error == 0 ? AE_OK : AE_NO_MEMORY; 767 return error == 0 ? AE_OK : AE_NO_MEMORY;
768} 768}
769 769
770int 770int
771acpimcfg_configure_bus(device_t self, pci_chipset_tag_t pc, ACPI_HANDLE handle, 771acpimcfg_configure_bus(device_t self, pci_chipset_tag_t pc, ACPI_HANDLE handle,
772 int bus, int cacheline_size) 772 int bus, int cacheline_size)
773{ 773{
774 struct pciconf_resources *pcires; 774 struct pciconf_resources *pcires;
775 struct mcfg_segment *seg; 775 struct mcfg_segment *seg;
776 struct mcfg_bus *mb; 776 struct mcfg_bus *mb;
777 bus_space_handle_t bsh[256]; 777 bus_space_handle_t bsh[256];
778 bool bsh_mapped[256]; 778 bool bsh_mapped[256];
779 int error, boff, b, d, f; 779 int error, boff, b, d, f;
780 bus_addr_t baddr; 780 bus_addr_t baddr;
781 ACPI_STATUS rv; 781 ACPI_STATUS rv;
782 782
783 seg = acpimcfg_get_segment(pc, bus); 783 seg = acpimcfg_get_segment(pc, bus);
784 if (seg == NULL) 784 if (seg == NULL)
785 return ENOENT; 785 return ENOENT;
786 786
787 pcires = pciconf_resource_init(); 787 pcires = pciconf_resource_init();
788 788
789 /* 789 /*
790 * Map config space for all possible busses and mark them valid during 790 * Map config space for all possible busses and mark them valid during
791 * configuration so pci_configure_bus can access them through our chipset 791 * configuration so pci_configure_bus can access them through our chipset
792 * tag with acpimcfg_conf_read/write below. 792 * tag with acpimcfg_conf_read/write below.
793 */ 793 */
794 memset(bsh_mapped, 0, sizeof(bsh_mapped)); 794 memset(bsh_mapped, 0, sizeof(bsh_mapped));
795 for (b = seg->ms_bus_start; b <= seg->ms_bus_end; b++) { 795 for (b = seg->ms_bus_start; b <= seg->ms_bus_end; b++) {
796 boff = b - seg->ms_bus_start; 796 boff = b - seg->ms_bus_start;
797 mb = &seg->ms_bus[boff]; 797 mb = &seg->ms_bus[boff];
798 baddr = seg->ms_address + (b * ACPIMCFG_SIZE_PER_BUS); 798 baddr = seg->ms_address + (b * ACPIMCFG_SIZE_PER_BUS);
799 799
800 /* Map extended configuration space of all dev/func. */ 800 /* Map extended configuration space of all dev/func. */
801 error = bus_space_map(seg->ms_bst, baddr, ACPIMCFG_SIZE_PER_BUS, 0, 801 error = bus_space_map(seg->ms_bst, baddr, ACPIMCFG_SIZE_PER_BUS, 0,
802 &bsh[b]); 802 &bsh[b]);
803 if (error != 0) 803 if (error != 0)
804 goto cleanup; 804 goto cleanup;
805 bsh_mapped[b] = true; 805 bsh_mapped[b] = true;
806 for (d = 0; d < 32; d++) { 806 for (d = 0; d < 32; d++) {
807 for (f = 0; f < 8; f++) { 807 for (f = 0; f < 8; f++) {
808 error = bus_space_subregion(seg->ms_bst, bsh[b], 808 error = bus_space_subregion(seg->ms_bst, bsh[b],
809 EXTCONF_OFFSET(d, f, 0), PCI_EXTCONF_SIZE, 809 EXTCONF_OFFSET(d, f, 0), PCI_EXTCONF_SIZE,
810 &mb->bsh[d][f]); 810 &mb->bsh[d][f]);
811 if (error != 0) 811 if (error != 0)
812 break; 812 break;
813 } 813 }
814 } 814 }
815 if (error != 0) 815 if (error != 0)
816 goto cleanup; 816 goto cleanup;
817 817
818 memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs)); 818 memset(mb->valid_devs, 0xff, sizeof(mb->valid_devs));
819 } 819 }
820 820
821 rv = AcpiWalkResources(handle, "_CRS", acpimcfg_configure_bus_cb, 821 rv = AcpiWalkResources(handle, "_CRS", acpimcfg_configure_bus_cb,
822 pcires); 822 pcires);
823 if (ACPI_FAILURE(rv)) { 823 if (ACPI_FAILURE(rv)) {
824 error = ENXIO; 824 error = ENXIO;
825 goto cleanup; 825 goto cleanup;
826 } 826 }
827 827
828 error = pci_configure_bus(pc, pcires, bus, cacheline_size); 828 error = pci_configure_bus(pc, pcires, bus, cacheline_size);
829 829
830cleanup: 830cleanup:
831 /* 831 /*
832 * Unmap config space for the segment's busses. Valid devices will be 832 * Unmap config space for the segment's busses. Valid devices will be
833 * re-mapped later on by acpimcfg_map_bus. 833 * re-mapped later on by acpimcfg_map_bus.
834 */ 834 */
835 for (b = seg->ms_bus_start; b <= seg->ms_bus_end; b++) { 835 for (b = seg->ms_bus_start; b <= seg->ms_bus_end; b++) {
836 boff = b - seg->ms_bus_start; 836 boff = b - seg->ms_bus_start;
837 mb = &seg->ms_bus[boff]; 837 mb = &seg->ms_bus[boff];
838 memset(mb->valid_devs, 0, sizeof(mb->valid_devs)); 838 memset(mb->valid_devs, 0, sizeof(mb->valid_devs));
839 839
840 if (bsh_mapped[b]) 840 if (bsh_mapped[b])
841 bus_space_unmap(seg->ms_bst, bsh[b], ACPIMCFG_SIZE_PER_BUS); 841 bus_space_unmap(seg->ms_bst, bsh[b], ACPIMCFG_SIZE_PER_BUS);
842 } 842 }
843 843
844 pciconf_resource_fini(pcires); 844 pciconf_resource_fini(pcires);
845 845
846 return error; 846 return error;
847} 847}
848#else 848#else
849int 849int
850acpimcfg_configure_bus(device_t self, pci_chipset_tag_t pc, ACPI_HANDLE handle, 850acpimcfg_configure_bus(device_t self, pci_chipset_tag_t pc, ACPI_HANDLE handle,
851 int bus, int cacheline_size) 851 int bus, int cacheline_size)
852{ 852{
853 return ENXIO; 853 return ENXIO;
854} 854}
855#endif 855#endif
856 856
857int 857int
858acpimcfg_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *data) 858acpimcfg_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *data)
859{ 859{
860 struct mcfg_segment *seg = NULL; 860 struct mcfg_segment *seg = NULL;
861 struct mcfg_bus *mb; 861 struct mcfg_bus *mb;
862 int bus, dev, func; 862 int bus, dev, func;
863 863
864 KASSERT(reg < PCI_EXTCONF_SIZE); 864 KASSERT(reg < PCI_EXTCONF_SIZE);
865 KASSERT((reg & 3) == 0); 865 KASSERT((reg & 3) == 0);
866 866
867 if (!mcfg_inited) { 867 if (!mcfg_inited) {
868 *data = -1; 868 *data = -1;
869 return ENXIO; 869 return ENXIO;
870 } 870 }
871 871
872 pci_decompose_tag(pc, tag, &bus, &dev, &func); 872 pci_decompose_tag(pc, tag, &bus, &dev, &func);
873 873
874 seg = acpimcfg_get_segment(pc, bus); 874 seg = acpimcfg_get_segment(pc, bus);
875 if (seg == NULL) { 875 if (seg == NULL) {
876 *data = -1; 876 *data = -1;
877 return ERANGE; 877 return ERANGE;
878 } 878 }
879 879
880 mb = &seg->ms_bus[bus - seg->ms_bus_start]; 880 mb = &seg->ms_bus[bus - seg->ms_bus_start];
881 if (!PCIDEV_IS_VALID(mb, dev, func)) { 881 if (!PCIDEV_IS_VALID(mb, dev, func)) {
882 *data = -1; 882 *data = -1;
883 return EINVAL; 883 return EINVAL;
884 } 884 }
885 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE) { 885 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE) {
886 *data = -1; 886 *data = -1;
887 return EINVAL; 887 return EINVAL;
888 } 888 }
889 889
890 *data = mcfg_ops->ao_read(seg->ms_bst, mb->bsh[dev][func], reg); 890 *data = mcfg_ops->ao_read(seg->ms_bst, mb->bsh[dev][func], reg);
891 return 0; 891 return 0;
892} 892}
893 893
894int 894int
895acpimcfg_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) 895acpimcfg_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
896{ 896{
897 struct mcfg_segment *seg = NULL; 897 struct mcfg_segment *seg = NULL;
898 struct mcfg_bus *mb; 898 struct mcfg_bus *mb;
899 int bus, dev, func; 899 int bus, dev, func;
900 900
901 KASSERT(reg < PCI_EXTCONF_SIZE); 901 KASSERT(reg < PCI_EXTCONF_SIZE);
902 KASSERT((reg & 3) == 0); 902 KASSERT((reg & 3) == 0);
903 903
904 if (!mcfg_inited) 904 if (!mcfg_inited)
905 return ENXIO; 905 return ENXIO;
906 906
907 pci_decompose_tag(pc, tag, &bus, &dev, &func); 907 pci_decompose_tag(pc, tag, &bus, &dev, &func);
908 908
909 seg = acpimcfg_get_segment(pc, bus); 909 seg = acpimcfg_get_segment(pc, bus);
910 if (seg == NULL) 910 if (seg == NULL)
911 return ERANGE; 911 return ERANGE;
912 912
913 mb = &seg->ms_bus[bus - seg->ms_bus_start]; 913 mb = &seg->ms_bus[bus - seg->ms_bus_start];
914 if (!PCIDEV_IS_VALID(mb, dev, func)) 914 if (!PCIDEV_IS_VALID(mb, dev, func))
915 return EINVAL; 915 return EINVAL;
916 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE) 916 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE)
917 return EINVAL; 917 return EINVAL;
918 918
919 mcfg_ops->ao_write(seg->ms_bst, mb->bsh[dev][func], reg, data); 919 mcfg_ops->ao_write(seg->ms_bst, mb->bsh[dev][func], reg, data);
920 return 0; 920 return 0;
921} 921}
922 922
923bool 923bool
924acpimcfg_conf_valid(pci_chipset_tag_t pc, pcitag_t tag, int reg) 924acpimcfg_conf_valid(pci_chipset_tag_t pc, pcitag_t tag, int reg)
925{ 925{
926 struct mcfg_segment *seg = NULL; 926 struct mcfg_segment *seg = NULL;
927 struct mcfg_bus *mb; 927 struct mcfg_bus *mb;
928 int bus, dev, func; 928 int bus, dev, func;
929 929
930 if (!mcfg_inited) 930 if (!mcfg_inited)
931 return false; 931 return false;
932 932
933 pci_decompose_tag(pc, tag, &bus, &dev, &func); 933 pci_decompose_tag(pc, tag, &bus, &dev, &func);
934 934
935 seg = acpimcfg_get_segment(pc, bus); 935 seg = acpimcfg_get_segment(pc, bus);
936 if (seg == NULL) 936 if (seg == NULL)
937 return false; 937 return false;
938 938
939 mb = &seg->ms_bus[bus - seg->ms_bus_start]; 939 mb = &seg->ms_bus[bus - seg->ms_bus_start];
940 if (!PCIDEV_IS_VALID(mb, dev, func)) 940 if (!PCIDEV_IS_VALID(mb, dev, func))
941 return false; 941 return false;
942 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE) 942 if (!EXTCONF_IS_VALID(mb, dev, func) && reg >= PCI_CONF_SIZE)
943 return false; 943 return false;
944 944
945 return true; 945 return true;
946} 946}