Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/pci/pci_resource.c
+++ new/usr/src/uts/intel/io/pci/pci_resource.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
24 24 *
25 25 * pci_resource.c -- routines to retrieve available bus resources from
26 26 * the MP Spec. Table and Hotplug Resource Table
27 27 */
28 28
29 29 #include <sys/types.h>
30 30 #include <sys/memlist.h>
31 31 #include <sys/pci_impl.h>
32 32 #include <sys/systm.h>
33 33 #include <sys/cmn_err.h>
34 -#include <sys/acpi/acpi.h>
34 +#include <acpica/include/acpi.h>
35 35 #include <sys/acpica.h>
36 36 #include "mps_table.h"
37 37 #include "pcihrt.h"
38 38
39 39 extern int pci_boot_debug;
40 40 extern int pci_bios_maxbus;
41 41 #define dprintf if (pci_boot_debug) printf
42 42
43 43 static int tbl_init = 0;
44 44 static uchar_t *mps_extp = NULL;
45 45 static uchar_t *mps_ext_endp = NULL;
46 46 static struct php_entry *hrt_hpep;
47 47 static int hrt_entry_cnt = 0;
48 48 static int acpi_cb_cnt = 0;
49 49
50 50 static void mps_probe(void);
51 51 static void acpi_pci_probe(void);
52 52 static int mps_find_bus_res(int, int, struct memlist **);
53 53 static void hrt_probe(void);
54 54 static int hrt_find_bus_res(int, int, struct memlist **);
55 55 static int acpi_find_bus_res(int, int, struct memlist **);
56 56 static uchar_t *find_sig(uchar_t *cp, int len, char *sig);
57 57 static int checksum(unsigned char *cp, int len);
58 58 static ACPI_STATUS acpi_wr_cb(ACPI_RESOURCE *rp, void *context);
59 59 void bus_res_fini(void);
60 60 static void acpi_trim_bus_ranges(void);
61 61
62 62 struct memlist *acpi_io_res[256];
63 63 struct memlist *acpi_mem_res[256];
64 64 struct memlist *acpi_pmem_res[256];
65 65 struct memlist *acpi_bus_res[256];
66 66
67 67 /*
68 68 * -1 = attempt ACPI resource discovery
69 69 * 0 = don't attempt ACPI resource discovery
70 70 * 1 = ACPI resource discovery successful
71 71 */
72 72 volatile int acpi_resource_discovery = -1;
73 73
74 74 struct memlist *
75 75 find_bus_res(int bus, int type)
76 76 {
77 77 struct memlist *res = NULL;
78 78
79 79 if (tbl_init == 0) {
80 80 tbl_init = 1;
81 81 acpi_pci_probe();
82 82 hrt_probe();
83 83 mps_probe();
84 84 }
85 85
86 86 if (acpi_find_bus_res(bus, type, &res) > 0)
87 87 return (res);
88 88
89 89 if (hrt_find_bus_res(bus, type, &res) > 0)
90 90 return (res);
91 91
92 92 (void) mps_find_bus_res(bus, type, &res);
93 93 return (res);
94 94 }
95 95
96 96
97 97 static void
98 98 acpi_pci_probe(void)
99 99 {
100 100 ACPI_HANDLE ah;
101 101 dev_info_t *dip;
102 102 int bus;
103 103
104 104 if (acpi_resource_discovery == 0)
105 105 return;
106 106
107 107 for (bus = 0; bus <= pci_bios_maxbus; bus++) {
108 108 /* if no dip or no ACPI handle, no resources to discover */
109 109 dip = pci_bus_res[bus].dip;
110 110 if ((dip == NULL) ||
111 111 (ACPI_FAILURE(acpica_get_handle(dip, &ah))))
112 112 continue;
113 113
114 114 (void) AcpiWalkResources(ah, "_CRS", acpi_wr_cb,
115 115 (void *)(uintptr_t)bus);
116 116 }
117 117
118 118 if (acpi_cb_cnt > 0) {
119 119 acpi_resource_discovery = 1;
120 120 acpi_trim_bus_ranges();
121 121 }
122 122 }
123 123
124 124 /*
125 125 * Trim overlapping bus ranges in acpi_bus_res[]
126 126 * Some BIOSes report root-bridges with bus ranges that
127 127 * overlap, for example:"0..255" and "8..255". Lower-numbered
128 128 * ranges are trimmed by upper-numbered ranges (so "0..255" would
129 129 * be trimmed to "0..7", in the example).
130 130 */
131 131 static void
132 132 acpi_trim_bus_ranges()
133 133 {
134 134 struct memlist *ranges, *current;
135 135 int bus;
136 136
137 137 ranges = NULL;
138 138
139 139 /*
140 140 * Assumptions:
141 141 * - there exists at most 1 bus range entry for each bus number
142 142 * - there are no (broken) ranges that start at the same bus number
143 143 */
144 144 for (bus = 0; bus < 256; bus++) {
145 145 struct memlist *prev, *orig, *new;
146 146 /* skip buses with no range entry */
147 147 if ((orig = acpi_bus_res[bus]) == NULL)
148 148 continue;
149 149
150 150 /*
151 151 * create copy of existing range and overload
152 152 * 'prev' pointer to link existing to new copy
153 153 */
154 154 new = memlist_alloc();
155 155 new->ml_address = orig->ml_address;
156 156 new->ml_size = orig->ml_size;
157 157 new->ml_prev = orig;
158 158
159 159 /* sorted insertion of 'new' into ranges list */
160 160 for (current = ranges, prev = NULL; current != NULL;
161 161 prev = current, current = current->ml_next)
162 162 if (new->ml_address < current->ml_address)
163 163 break;
164 164
165 165 if (prev == NULL) {
166 166 /* place at beginning of (possibly) empty list */
167 167 new->ml_next = ranges;
168 168 ranges = new;
169 169 } else {
170 170 /* place in list (possibly at end) */
171 171 new->ml_next = current;
172 172 prev->ml_next = new;
173 173 }
174 174 }
175 175
176 176 /* scan the list, perform trimming */
177 177 current = ranges;
178 178 while (current != NULL) {
179 179 struct memlist *next = current->ml_next;
180 180
181 181 /* done when no range above current */
182 182 if (next == NULL)
183 183 break;
184 184
185 185 /*
186 186 * trim size in original range element
187 187 * (current->ml_prev points to the original range)
188 188 */
189 189 if ((current->ml_address + current->ml_size) > next->ml_address)
190 190 current->ml_prev->ml_size =
191 191 next->ml_address - current->ml_address;
192 192
193 193 current = next;
194 194 }
195 195
196 196 /* discard the list */
197 197 memlist_free_all(&ranges); /* OK if ranges == NULL */
198 198 }
199 199
200 200 static int
201 201 acpi_find_bus_res(int bus, int type, struct memlist **res)
202 202 {
203 203
204 204 switch (type) {
205 205 case IO_TYPE:
206 206 *res = acpi_io_res[bus];
207 207 break;
208 208 case MEM_TYPE:
209 209 *res = acpi_mem_res[bus];
210 210 break;
211 211 case PREFETCH_TYPE:
212 212 *res = acpi_pmem_res[bus];
213 213 break;
214 214 case BUSRANGE_TYPE:
215 215 *res = acpi_bus_res[bus];
216 216 break;
217 217 default:
218 218 *res = NULL;
219 219 break;
220 220 }
221 221
222 222 /* memlist_count() treats NULL head as zero-length */
223 223 return (memlist_count(*res));
224 224 }
225 225
226 226 void
227 227 bus_res_fini(void)
228 228 {
229 229 int bus;
230 230
231 231 for (bus = 0; bus <= pci_bios_maxbus; bus++) {
232 232 memlist_free_all(&acpi_io_res[bus]);
233 233 memlist_free_all(&acpi_mem_res[bus]);
234 234 memlist_free_all(&acpi_pmem_res[bus]);
235 235 memlist_free_all(&acpi_bus_res[bus]);
236 236 }
237 237 }
238 238
239 239
240 240 struct memlist **
241 241 rlistpp(UINT8 t, UINT8 flags, int bus)
242 242 {
243 243 switch (t) {
244 244
245 245 case ACPI_MEMORY_RANGE:
246 246 /* is this really the best we've got? */
247 247 if (((flags >> 1) & 0x3) == ACPI_PREFETCHABLE_MEMORY)
248 248 return (&acpi_pmem_res[bus]);
249 249 else
250 250 return (&acpi_mem_res[bus]);
251 251
252 252 case ACPI_IO_RANGE: return &acpi_io_res[bus];
253 253 case ACPI_BUS_NUMBER_RANGE: return &acpi_bus_res[bus];
254 254 }
255 255 return ((struct memlist **)NULL);
256 256 }
257 257
258 258
259 259 ACPI_STATUS
260 260 acpi_wr_cb(ACPI_RESOURCE *rp, void *context)
261 261 {
262 262 int bus = (intptr_t)context;
263 263
264 264 /* ignore consumed resources */
265 265 if (rp->Data.Address.ProducerConsumer == 1)
266 266 return (AE_OK);
267 267
268 268 switch (rp->Type) {
269 269 case ACPI_RESOURCE_TYPE_IRQ:
270 270 /* never expect to see a PCI bus produce an Interrupt */
271 271 dprintf("%s\n", "IRQ");
272 272 break;
273 273
274 274 case ACPI_RESOURCE_TYPE_DMA:
275 275 /* never expect to see a PCI bus produce DMA */
276 276 dprintf("%s\n", "DMA");
277 277 break;
278 278
279 279 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
280 280 dprintf("%s\n", "START_DEPENDENT");
281 281 break;
282 282
283 283 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
284 284 dprintf("%s\n", "END_DEPENDENT");
285 285 break;
286 286
287 287 case ACPI_RESOURCE_TYPE_IO:
288 288 if (rp->Data.Io.AddressLength == 0)
289 289 break;
290 290 acpi_cb_cnt++;
291 291 memlist_insert(&acpi_io_res[bus], rp->Data.Io.Minimum,
292 292 rp->Data.Io.AddressLength);
293 293 break;
294 294
295 295 case ACPI_RESOURCE_TYPE_FIXED_IO:
296 296 /* only expect to see this as a consumer */
297 297 dprintf("%s\n", "FIXED_IO");
298 298 break;
299 299
300 300 case ACPI_RESOURCE_TYPE_VENDOR:
301 301 dprintf("%s\n", "VENDOR");
302 302 break;
303 303
304 304 case ACPI_RESOURCE_TYPE_END_TAG:
305 305 dprintf("%s\n", "END_TAG");
306 306 break;
307 307
308 308 case ACPI_RESOURCE_TYPE_MEMORY24:
309 309 /* only expect to see this as a consumer */
310 310 dprintf("%s\n", "MEMORY24");
311 311 break;
312 312
313 313 case ACPI_RESOURCE_TYPE_MEMORY32:
314 314 /* only expect to see this as a consumer */
315 315 dprintf("%s\n", "MEMORY32");
316 316 break;
317 317
318 318 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
319 319 /* only expect to see this as a consumer */
320 320 dprintf("%s\n", "FIXED_MEMORY32");
321 321 break;
322 322
323 323 case ACPI_RESOURCE_TYPE_ADDRESS16:
324 324 if (rp->Data.Address16.AddressLength == 0)
325 325 break;
326 326 acpi_cb_cnt++;
327 327 memlist_insert(rlistpp(rp->Data.Address16.ResourceType,
328 328 rp->Data.Address16.Info.TypeSpecific, bus),
329 329 rp->Data.Address16.Minimum,
330 330 rp->Data.Address16.AddressLength);
331 331 break;
332 332
333 333 case ACPI_RESOURCE_TYPE_ADDRESS32:
334 334 if (rp->Data.Address32.AddressLength == 0)
335 335 break;
336 336 acpi_cb_cnt++;
337 337 memlist_insert(rlistpp(rp->Data.Address32.ResourceType,
338 338 rp->Data.Address32.Info.TypeSpecific, bus),
339 339 rp->Data.Address32.Minimum,
340 340 rp->Data.Address32.AddressLength);
341 341 break;
342 342
343 343 case ACPI_RESOURCE_TYPE_ADDRESS64:
344 344 /*
345 345 * We comment out this block because we currently cannot deal with
346 346 * PCI 64-bit addresses. Will revisit this when we add PCI 64-bit MMIO
347 347 * support.
348 348 */
349 349 #if 0
350 350 if (rp->Data.Address64.AddressLength == 0)
351 351 break;
352 352 acpi_cb_cnt++;
353 353 memlist_insert(rlistpp(rp->Data.Address64.ResourceType,
354 354 rp->Data.Address64.Info.TypeSpecific, bus),
355 355 rp->Data.Address64.Minimum,
356 356 rp->Data.Address64.AddressLength);
357 357 #endif
358 358 break;
359 359
360 360 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
361 361 #if 0 /* Will revisit this when we add PCI 64-bit MMIO support */
362 362 if (rp->Data.ExtAddress64.AddressLength == 0)
363 363 break;
364 364 acpi_cb_cnt++;
365 365 memlist_insert(rlistpp(rp->Data.ExtAddress64.ResourceType,
366 366 rp->Data.ExtAddress64.Info.TypeSpecific, bus),
367 367 rp->Data.ExtAddress64.Minimum,
368 368 rp->Data.ExtAddress64.AddressLength);
369 369 #endif
370 370 break;
371 371
372 372 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
373 373 /* never expect to see a PCI bus produce an Interrupt */
374 374 dprintf("%s\n", "EXTENDED_IRQ");
375 375 break;
376 376
377 377 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
378 378 /* never expect to see a PCI bus produce an GAS */
379 379 dprintf("%s\n", "GENERIC_REGISTER");
380 380 break;
381 381 }
382 382
383 383 return (AE_OK);
384 384 }
385 385
386 386 static void
387 387 mps_probe()
388 388 {
389 389 uchar_t *extp;
390 390 struct mps_fps_hdr *fpp = NULL;
391 391 struct mps_ct_hdr *ctp;
392 392 uintptr_t ebda_start, base_end;
393 393 ushort_t ebda_seg, base_size, ext_len, base_len, base_end_seg;
394 394
395 395 base_size = *((ushort_t *)(0x413));
396 396 ebda_seg = *((ushort_t *)(0x40e));
397 397 ebda_start = ((uint32_t)ebda_seg) << 4;
398 398 if (ebda_seg != 0) {
399 399 fpp = (struct mps_fps_hdr *)find_sig(
400 400 (uchar_t *)ebda_start, 1024, "_MP_");
401 401 }
402 402 if (fpp == NULL) {
403 403 base_end_seg = (base_size > 512) ? 0x9FC0 : 0x7FC0;
404 404 if (base_end_seg != ebda_seg) {
405 405 base_end = ((uintptr_t)base_end_seg) << 4;
406 406 fpp = (struct mps_fps_hdr *)find_sig(
407 407 (uchar_t *)base_end, 1024, "_MP_");
408 408 }
409 409 }
410 410 if (fpp == NULL) {
411 411 fpp = (struct mps_fps_hdr *)find_sig(
412 412 (uchar_t *)0xF0000, 0x10000, "_MP_");
413 413 }
414 414
415 415 if (fpp == NULL) {
416 416 dprintf("MP Spec table doesn't exist");
417 417 return;
418 418 } else {
419 419 dprintf("Found MP Floating Pointer Structure at %p\n",
420 420 (void *)fpp);
421 421 }
422 422
423 423 if (checksum((uchar_t *)fpp, fpp->fps_len * 16) != 0) {
424 424 dprintf("MP Floating Pointer Structure checksum error");
425 425 return;
426 426 }
427 427
428 428 ctp = (struct mps_ct_hdr *)(uintptr_t)fpp->fps_mpct_paddr;
429 429 if (ctp->ct_sig != 0x504d4350) { /* check "PCMP" signature */
430 430 dprintf("MP Configuration Table signature is wrong");
431 431 return;
432 432 }
433 433
434 434 base_len = ctp->ct_len;
435 435 if (checksum((uchar_t *)ctp, base_len) != 0) {
436 436 dprintf("MP Configuration Table checksum error");
437 437 return;
438 438 }
439 439 if (ctp->ct_spec_rev != 4) { /* not MPSpec rev 1.4 */
440 440 dprintf("MP Spec 1.1 found - extended table doesn't exist");
441 441 return;
442 442 }
443 443 if ((ext_len = ctp->ct_ext_tbl_len) == 0) {
444 444 dprintf("MP Spec 1.4 found - extended table doesn't exist");
445 445 return;
446 446 }
447 447 extp = (uchar_t *)ctp + base_len;
448 448 if (((checksum(extp, ext_len) + ctp->ct_ext_cksum) & 0xFF) != 0) {
449 449 dprintf("MP Extended Table checksum error");
450 450 return;
451 451 }
452 452 mps_extp = extp;
453 453 mps_ext_endp = mps_extp + ext_len;
454 454 }
455 455
456 456
457 457 static int
458 458 mps_find_bus_res(int bus, int type, struct memlist **res)
459 459 {
460 460 struct sasm *sasmp;
461 461 uchar_t *extp;
462 462 int res_cnt;
463 463
464 464 if (mps_extp == NULL)
465 465 return (0);
466 466 extp = mps_extp;
467 467 res_cnt = 0;
468 468 while (extp < mps_ext_endp) {
469 469 switch (*extp) {
470 470 case SYS_AS_MAPPING:
471 471 sasmp = (struct sasm *)extp;
472 472 if (((int)sasmp->sasm_as_type) == type &&
473 473 ((int)sasmp->sasm_bus_id) == bus) {
474 474 if (sasmp->sasm_as_base_hi != 0 ||
475 475 sasmp->sasm_as_len_hi != 0) {
476 476 printf("64 bits address space\n");
477 477 extp += SYS_AS_MAPPING_SIZE;
478 478 break;
479 479 }
480 480 memlist_insert(res,
481 481 (uint64_t)sasmp->sasm_as_base,
482 482 sasmp->sasm_as_len);
483 483 res_cnt++;
484 484 }
485 485 extp += SYS_AS_MAPPING_SIZE;
486 486 break;
487 487 case BUS_HIERARCHY_DESC:
488 488 extp += BUS_HIERARCHY_DESC_SIZE;
489 489 break;
490 490 case COMP_BUS_AS_MODIFIER:
491 491 extp += COMP_BUS_AS_MODIFIER_SIZE;
492 492 break;
493 493 default:
494 494 cmn_err(CE_WARN, "Unknown descriptor type %d"
495 495 " in BIOS Multiprocessor Spec table.",
496 496 *extp);
497 497 while (*res) {
498 498 struct memlist *tmp = *res;
499 499 *res = tmp->ml_next;
500 500 memlist_free(tmp);
501 501 }
502 502 return (0);
503 503 }
504 504 }
505 505 return (res_cnt);
506 506 }
507 507
508 508 static void
509 509 hrt_probe()
510 510 {
511 511 struct hrt_hdr *hrtp;
512 512
513 513 dprintf("search PCI Hot-Plug Resource Table starting at 0xF0000\n");
514 514 if ((hrtp = (struct hrt_hdr *)find_sig((uchar_t *)0xF0000,
515 515 0x10000, "$HRT")) == NULL) {
516 516 dprintf("NO PCI Hot-Plug Resource Table");
517 517 return;
518 518 }
519 519 dprintf("Found PCI Hot-Plug Resource Table at %p\n", (void *)hrtp);
520 520 if (hrtp->hrt_ver != 1) {
521 521 dprintf("PCI Hot-Plug Resource Table version no. <> 1\n");
522 522 return;
523 523 }
524 524 hrt_entry_cnt = (int)hrtp->hrt_entry_cnt;
525 525 dprintf("No. of PCI hot-plug slot entries = 0x%x\n", hrt_entry_cnt);
526 526 hrt_hpep = (struct php_entry *)(hrtp + 1);
527 527 }
528 528
529 529 static int
530 530 hrt_find_bus_res(int bus, int type, struct memlist **res)
531 531 {
532 532 int res_cnt, i;
533 533 struct php_entry *hpep;
534 534
535 535 if (hrt_hpep == NULL || hrt_entry_cnt == 0)
536 536 return (0);
537 537 hpep = hrt_hpep;
538 538 res_cnt = 0;
539 539 for (i = 0; i < hrt_entry_cnt; i++, hpep++) {
540 540 if (hpep->php_pri_bus != bus)
541 541 continue;
542 542 if (type == IO_TYPE) {
543 543 if (hpep->php_io_start == 0 || hpep->php_io_size == 0)
544 544 continue;
545 545 memlist_insert(res, (uint64_t)hpep->php_io_start,
546 546 (uint64_t)hpep->php_io_size);
547 547 res_cnt++;
548 548 } else if (type == MEM_TYPE) {
549 549 if (hpep->php_mem_start == 0 || hpep->php_mem_size == 0)
550 550 continue;
551 551 memlist_insert(res,
552 552 (uint64_t)(((int)hpep->php_mem_start) << 16),
553 553 (uint64_t)(((int)hpep->php_mem_size) << 16));
554 554 res_cnt++;
555 555 } else if (type == PREFETCH_TYPE) {
556 556 if (hpep->php_pfmem_start == 0 ||
557 557 hpep->php_pfmem_size == 0)
558 558 continue;
559 559 memlist_insert(res,
560 560 (uint64_t)(((int)hpep->php_pfmem_start) << 16),
561 561 (uint64_t)(((int)hpep->php_pfmem_size) << 16));
562 562 res_cnt++;
563 563 }
564 564 }
565 565 return (res_cnt);
566 566 }
567 567
568 568 static uchar_t *
569 569 find_sig(uchar_t *cp, int len, char *sig)
570 570 {
571 571 long i;
572 572
573 573 /* Search for the "_MP_" or "$HRT" signature */
574 574 for (i = 0; i < len; i += 16) {
575 575 if (cp[0] == sig[0] && cp[1] == sig[1] &&
576 576 cp[2] == sig[2] && cp[3] == sig[3])
577 577 return (cp);
578 578 cp += 16;
579 579 }
580 580 return (NULL);
581 581 }
582 582
583 583 static int
584 584 checksum(unsigned char *cp, int len)
585 585 {
586 586 int i;
587 587 unsigned int cksum;
588 588
589 589 for (i = cksum = 0; i < len; i++)
590 590 cksum += (unsigned int) *cp++;
591 591
592 592 return ((int)(cksum & 0xFF));
593 593 }
594 594
595 595 #ifdef UNUSED_BUS_HIERARY_INFO
596 596
597 597 /*
598 598 * At this point, the bus hierarchy entries do not appear to
599 599 * provide anything we can't find out from PCI config space.
600 600 * The only interesting bit is the ISA bus number, which we
601 601 * don't care.
602 602 */
603 603 int
604 604 mps_find_parent_bus(int bus)
605 605 {
606 606 struct sasm *sasmp;
607 607 uchar_t *extp;
608 608
609 609 if (mps_extp == NULL)
610 610 return (-1);
611 611
612 612 extp = mps_extp;
613 613 while (extp < mps_ext_endp) {
614 614 bhdp = (struct bhd *)extp;
615 615 switch (*extp) {
616 616 case SYS_AS_MAPPING:
617 617 extp += SYS_AS_MAPPING_SIZE;
618 618 break;
619 619 case BUS_HIERARCHY_DESC:
620 620 if (bhdp->bhd_bus_id == bus)
621 621 return (bhdp->bhd_parent);
622 622 extp += BUS_HIERARCHY_DESC_SIZE;
623 623 break;
624 624 case COMP_BUS_AS_MODIFIER:
625 625 extp += COMP_BUS_AS_MODIFIER_SIZE;
626 626 break;
627 627 default:
628 628 cmn_err(CE_WARN, "Unknown descriptor type %d"
629 629 " in BIOS Multiprocessor Spec table.",
630 630 *extp);
631 631 return (-1);
632 632 }
633 633 }
634 634 return (-1);
635 635 }
636 636
637 637 int
638 638 hrt_find_bus_range(int bus)
639 639 {
640 640 int i, max_bus, sub_bus;
641 641 struct php_entry *hpep;
642 642
643 643 if (hrt_hpep == NULL || hrt_entry_cnt == 0) {
644 644 return (-1);
645 645 }
646 646 hpep = hrt_hpep;
647 647 max_bus = -1;
648 648 for (i = 0; i < hrt_entry_cnt; i++, hpep++) {
649 649 if (hpep->php_pri_bus != bus)
650 650 continue;
651 651 sub_bus = (int)hpep->php_subord_bus;
652 652 if (sub_bus > max_bus)
653 653 max_bus = sub_bus;
654 654 }
655 655 return (max_bus);
656 656 }
657 657
658 658 #endif /* UNUSED_BUS_HIERARY_INFO */
↓ open down ↓ |
614 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX