1 /* 2 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> 3 * Andreas Heppel <aheppel@sysgo.de> 4 * 5 * (C) Copyright 2002, 2003 6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 /* 12 * PCI routines 13 */ 14 15 #include <common.h> 16 17 #include <command.h> 18 #include <asm/processor.h> 19 #include <asm/io.h> 20 #include <pci.h> 21 22 #define PCI_HOSE_OP(rw, size, type) \ 23 int pci_hose_##rw##_config_##size(struct pci_controller *hose, \ 24 pci_dev_t dev, \ 25 int offset, type value) \ 26 { \ 27 return hose->rw##_##size(hose, dev, offset, value); \ 28 } 29 30 PCI_HOSE_OP(read, byte, u8 *) 31 PCI_HOSE_OP(read, word, u16 *) 32 PCI_HOSE_OP(read, dword, u32 *) 33 PCI_HOSE_OP(write, byte, u8) 34 PCI_HOSE_OP(write, word, u16) 35 PCI_HOSE_OP(write, dword, u32) 36 37 #define PCI_OP(rw, size, type, error_code) \ 38 int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value) \ 39 { \ 40 struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev)); \ 41 \ 42 if (!hose) \ 43 { \ 44 error_code; \ 45 return -1; \ 46 } \ 47 \ 48 return pci_hose_##rw##_config_##size(hose, dev, offset, value); \ 49 } 50 51 PCI_OP(read, byte, u8 *, *value = 0xff) 52 PCI_OP(read, word, u16 *, *value = 0xffff) 53 PCI_OP(read, dword, u32 *, *value = 0xffffffff) 54 PCI_OP(write, byte, u8, ) 55 PCI_OP(write, word, u16, ) 56 PCI_OP(write, dword, u32, ) 57 58 #define PCI_READ_VIA_DWORD_OP(size, type, off_mask) \ 59 int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\ 60 pci_dev_t dev, \ 61 int offset, type val) \ 62 { \ 63 u32 val32; \ 64 \ 65 if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) { \ 66 *val = -1; \ 67 return -1; \ 68 } \ 69 \ 70 *val = (val32 >> ((offset & (int)off_mask) * 8)); \ 71 \ 72 return 0; \ 73 } 74 75 #define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask) \ 76 int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\ 77 pci_dev_t dev, \ 78 int offset, type val) \ 79 { \ 80 u32 val32, mask, ldata, shift; \ 81 \ 82 if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\ 83 return -1; \ 84 \ 85 shift = ((offset & (int)off_mask) * 8); \ 86 ldata = (((unsigned long)val) & val_mask) << shift; \ 87 mask = val_mask << shift; \ 88 val32 = (val32 & ~mask) | ldata; \ 89 \ 90 if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\ 91 return -1; \ 92 \ 93 return 0; \ 94 } 95 96 PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03) 97 PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02) 98 PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff) 99 PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) 100 101 /* Get a virtual address associated with a BAR region */ 102 void *pci_map_bar(pci_dev_t pdev, int bar, int flags) 103 { 104 pci_addr_t pci_bus_addr; 105 u32 bar_response; 106 107 /* read BAR address */ 108 pci_read_config_dword(pdev, bar, &bar_response); 109 pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); 110 111 /* 112 * Pass "0" as the length argument to pci_bus_to_virt. The arg 113 * isn't actualy used on any platform because u-boot assumes a static 114 * linear mapping. In the future, this could read the BAR size 115 * and pass that as the size if needed. 116 */ 117 return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE); 118 } 119 120 /* 121 * 122 */ 123 124 static struct pci_controller* hose_head; 125 126 void pci_register_hose(struct pci_controller* hose) 127 { 128 struct pci_controller **phose = &hose_head; 129 130 while(*phose) 131 phose = &(*phose)->next; 132 133 hose->next = NULL; 134 135 *phose = hose; 136 } 137 138 struct pci_controller *pci_bus_to_hose(int bus) 139 { 140 struct pci_controller *hose; 141 142 for (hose = hose_head; hose; hose = hose->next) { 143 if (bus >= hose->first_busno && bus <= hose->last_busno) 144 return hose; 145 } 146 147 printf("pci_bus_to_hose() failed\n"); 148 return NULL; 149 } 150 151 struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr) 152 { 153 struct pci_controller *hose; 154 155 for (hose = hose_head; hose; hose = hose->next) { 156 if (hose->cfg_addr == cfg_addr) 157 return hose; 158 } 159 160 return NULL; 161 } 162 163 int pci_last_busno(void) 164 { 165 struct pci_controller *hose = hose_head; 166 167 if (!hose) 168 return -1; 169 170 while (hose->next) 171 hose = hose->next; 172 173 return hose->last_busno; 174 } 175 176 pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) 177 { 178 struct pci_controller * hose; 179 u16 vendor, device; 180 u8 header_type; 181 pci_dev_t bdf; 182 int i, bus, found_multi = 0; 183 184 for (hose = hose_head; hose; hose = hose->next) { 185 #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE 186 for (bus = hose->last_busno; bus >= hose->first_busno; bus--) 187 #else 188 for (bus = hose->first_busno; bus <= hose->last_busno; bus++) 189 #endif 190 for (bdf = PCI_BDF(bus, 0, 0); 191 #if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX) 192 bdf < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, 193 PCI_MAX_PCI_FUNCTIONS - 1); 194 #else 195 bdf < PCI_BDF(bus + 1, 0, 0); 196 #endif 197 bdf += PCI_BDF(0, 0, 1)) { 198 if (pci_skip_dev(hose, bdf)) 199 continue; 200 201 if (!PCI_FUNC(bdf)) { 202 pci_read_config_byte(bdf, 203 PCI_HEADER_TYPE, 204 &header_type); 205 206 found_multi = header_type & 0x80; 207 } else { 208 if (!found_multi) 209 continue; 210 } 211 212 pci_read_config_word(bdf, 213 PCI_VENDOR_ID, 214 &vendor); 215 pci_read_config_word(bdf, 216 PCI_DEVICE_ID, 217 &device); 218 219 for (i = 0; ids[i].vendor != 0; i++) { 220 if (vendor == ids[i].vendor && 221 device == ids[i].device) { 222 if (index <= 0) 223 return bdf; 224 225 index--; 226 } 227 } 228 } 229 } 230 231 return -1; 232 } 233 234 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) 235 { 236 static struct pci_device_id ids[2] = {{}, {0, 0}}; 237 238 ids[0].vendor = vendor; 239 ids[0].device = device; 240 241 return pci_find_devices(ids, index); 242 } 243 244 /* 245 * 246 */ 247 248 int __pci_hose_phys_to_bus(struct pci_controller *hose, 249 phys_addr_t phys_addr, 250 unsigned long flags, 251 unsigned long skip_mask, 252 pci_addr_t *ba) 253 { 254 struct pci_region *res; 255 pci_addr_t bus_addr; 256 int i; 257 258 for (i = 0; i < hose->region_count; i++) { 259 res = &hose->regions[i]; 260 261 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) 262 continue; 263 264 if (res->flags & skip_mask) 265 continue; 266 267 bus_addr = phys_addr - res->phys_start + res->bus_start; 268 269 if (bus_addr >= res->bus_start && 270 bus_addr < res->bus_start + res->size) { 271 *ba = bus_addr; 272 return 0; 273 } 274 } 275 276 return 1; 277 } 278 279 pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, 280 phys_addr_t phys_addr, 281 unsigned long flags) 282 { 283 pci_addr_t bus_addr = 0; 284 int ret; 285 286 if (!hose) { 287 puts("pci_hose_phys_to_bus: invalid hose\n"); 288 return bus_addr; 289 } 290 291 /* 292 * if PCI_REGION_MEM is set we do a two pass search with preference 293 * on matches that don't have PCI_REGION_SYS_MEMORY set 294 */ 295 if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { 296 ret = __pci_hose_phys_to_bus(hose, phys_addr, 297 flags, PCI_REGION_SYS_MEMORY, &bus_addr); 298 if (!ret) 299 return bus_addr; 300 } 301 302 ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr); 303 304 if (ret) 305 puts("pci_hose_phys_to_bus: invalid physical address\n"); 306 307 return bus_addr; 308 } 309 310 int __pci_hose_bus_to_phys(struct pci_controller *hose, 311 pci_addr_t bus_addr, 312 unsigned long flags, 313 unsigned long skip_mask, 314 phys_addr_t *pa) 315 { 316 struct pci_region *res; 317 int i; 318 319 for (i = 0; i < hose->region_count; i++) { 320 res = &hose->regions[i]; 321 322 if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) 323 continue; 324 325 if (res->flags & skip_mask) 326 continue; 327 328 if (bus_addr >= res->bus_start && 329 (bus_addr - res->bus_start) < res->size) { 330 *pa = (bus_addr - res->bus_start + res->phys_start); 331 return 0; 332 } 333 } 334 335 return 1; 336 } 337 338 phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, 339 pci_addr_t bus_addr, 340 unsigned long flags) 341 { 342 phys_addr_t phys_addr = 0; 343 int ret; 344 345 if (!hose) { 346 puts("pci_hose_bus_to_phys: invalid hose\n"); 347 return phys_addr; 348 } 349 350 /* 351 * if PCI_REGION_MEM is set we do a two pass search with preference 352 * on matches that don't have PCI_REGION_SYS_MEMORY set 353 */ 354 if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { 355 ret = __pci_hose_bus_to_phys(hose, bus_addr, 356 flags, PCI_REGION_SYS_MEMORY, &phys_addr); 357 if (!ret) 358 return phys_addr; 359 } 360 361 ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr); 362 363 if (ret) 364 puts("pci_hose_bus_to_phys: invalid physical address\n"); 365 366 return phys_addr; 367 } 368 369 /* 370 * 371 */ 372 373 int pci_hose_config_device(struct pci_controller *hose, 374 pci_dev_t dev, 375 unsigned long io, 376 pci_addr_t mem, 377 unsigned long command) 378 { 379 u32 bar_response; 380 unsigned int old_command; 381 pci_addr_t bar_value; 382 pci_size_t bar_size; 383 unsigned char pin; 384 int bar, found_mem64; 385 386 debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io, 387 (u64)mem, command); 388 389 pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0); 390 391 for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { 392 pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); 393 pci_hose_read_config_dword(hose, dev, bar, &bar_response); 394 395 if (!bar_response) 396 continue; 397 398 found_mem64 = 0; 399 400 /* Check the BAR type and set our address mask */ 401 if (bar_response & PCI_BASE_ADDRESS_SPACE) { 402 bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1; 403 /* round up region base address to a multiple of size */ 404 io = ((io - 1) | (bar_size - 1)) + 1; 405 bar_value = io; 406 /* compute new region base address */ 407 io = io + bar_size; 408 } else { 409 if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == 410 PCI_BASE_ADDRESS_MEM_TYPE_64) { 411 u32 bar_response_upper; 412 u64 bar64; 413 pci_hose_write_config_dword(hose, dev, bar + 4, 414 0xffffffff); 415 pci_hose_read_config_dword(hose, dev, bar + 4, 416 &bar_response_upper); 417 418 bar64 = ((u64)bar_response_upper << 32) | bar_response; 419 420 bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; 421 found_mem64 = 1; 422 } else { 423 bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); 424 } 425 426 /* round up region base address to multiple of size */ 427 mem = ((mem - 1) | (bar_size - 1)) + 1; 428 bar_value = mem; 429 /* compute new region base address */ 430 mem = mem + bar_size; 431 } 432 433 /* Write it out and update our limit */ 434 pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value); 435 436 if (found_mem64) { 437 bar += 4; 438 #ifdef CONFIG_SYS_PCI_64BIT 439 pci_hose_write_config_dword(hose, dev, bar, 440 (u32)(bar_value >> 32)); 441 #else 442 pci_hose_write_config_dword(hose, dev, bar, 0x00000000); 443 #endif 444 } 445 } 446 447 /* Configure Cache Line Size Register */ 448 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); 449 450 /* Configure Latency Timer */ 451 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); 452 453 /* Disable interrupt line, if device says it wants to use interrupts */ 454 pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin); 455 if (pin != 0) { 456 pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff); 457 } 458 459 pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command); 460 pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 461 (old_command & 0xffff0000) | command); 462 463 return 0; 464 } 465 466 /* 467 * 468 */ 469 470 struct pci_config_table *pci_find_config(struct pci_controller *hose, 471 unsigned short class, 472 unsigned int vendor, 473 unsigned int device, 474 unsigned int bus, 475 unsigned int dev, 476 unsigned int func) 477 { 478 struct pci_config_table *table; 479 480 for (table = hose->config_table; table && table->vendor; table++) { 481 if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) && 482 (table->device == PCI_ANY_ID || table->device == device) && 483 (table->class == PCI_ANY_ID || table->class == class) && 484 (table->bus == PCI_ANY_ID || table->bus == bus) && 485 (table->dev == PCI_ANY_ID || table->dev == dev) && 486 (table->func == PCI_ANY_ID || table->func == func)) { 487 return table; 488 } 489 } 490 491 return NULL; 492 } 493 494 void pci_cfgfunc_config_device(struct pci_controller *hose, 495 pci_dev_t dev, 496 struct pci_config_table *entry) 497 { 498 pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], 499 entry->priv[2]); 500 } 501 502 void pci_cfgfunc_do_nothing(struct pci_controller *hose, 503 pci_dev_t dev, struct pci_config_table *entry) 504 { 505 } 506 507 /* 508 * HJF: Changed this to return int. I think this is required 509 * to get the correct result when scanning bridges 510 */ 511 extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); 512 513 #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW) 514 const char * pci_class_str(u8 class) 515 { 516 switch (class) { 517 case PCI_CLASS_NOT_DEFINED: 518 return "Build before PCI Rev2.0"; 519 break; 520 case PCI_BASE_CLASS_STORAGE: 521 return "Mass storage controller"; 522 break; 523 case PCI_BASE_CLASS_NETWORK: 524 return "Network controller"; 525 break; 526 case PCI_BASE_CLASS_DISPLAY: 527 return "Display controller"; 528 break; 529 case PCI_BASE_CLASS_MULTIMEDIA: 530 return "Multimedia device"; 531 break; 532 case PCI_BASE_CLASS_MEMORY: 533 return "Memory controller"; 534 break; 535 case PCI_BASE_CLASS_BRIDGE: 536 return "Bridge device"; 537 break; 538 case PCI_BASE_CLASS_COMMUNICATION: 539 return "Simple comm. controller"; 540 break; 541 case PCI_BASE_CLASS_SYSTEM: 542 return "Base system peripheral"; 543 break; 544 case PCI_BASE_CLASS_INPUT: 545 return "Input device"; 546 break; 547 case PCI_BASE_CLASS_DOCKING: 548 return "Docking station"; 549 break; 550 case PCI_BASE_CLASS_PROCESSOR: 551 return "Processor"; 552 break; 553 case PCI_BASE_CLASS_SERIAL: 554 return "Serial bus controller"; 555 break; 556 case PCI_BASE_CLASS_INTELLIGENT: 557 return "Intelligent controller"; 558 break; 559 case PCI_BASE_CLASS_SATELLITE: 560 return "Satellite controller"; 561 break; 562 case PCI_BASE_CLASS_CRYPT: 563 return "Cryptographic device"; 564 break; 565 case PCI_BASE_CLASS_SIGNAL_PROCESSING: 566 return "DSP"; 567 break; 568 case PCI_CLASS_OTHERS: 569 return "Does not fit any class"; 570 break; 571 default: 572 return "???"; 573 break; 574 }; 575 } 576 #endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */ 577 578 __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) 579 { 580 /* 581 * Check if pci device should be skipped in configuration 582 */ 583 if (dev == PCI_BDF(hose->first_busno, 0, 0)) { 584 #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */ 585 /* 586 * Only skip configuration if "pciconfighost" is not set 587 */ 588 if (getenv("pciconfighost") == NULL) 589 return 1; 590 #else 591 return 1; 592 #endif 593 } 594 595 return 0; 596 } 597 598 #ifdef CONFIG_PCI_SCAN_SHOW 599 __weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) 600 { 601 if (dev == PCI_BDF(hose->first_busno, 0, 0)) 602 return 0; 603 604 return 1; 605 } 606 #endif /* CONFIG_PCI_SCAN_SHOW */ 607 608 int pci_hose_scan_bus(struct pci_controller *hose, int bus) 609 { 610 unsigned int sub_bus, found_multi = 0; 611 unsigned short vendor, device, class; 612 unsigned char header_type; 613 #ifndef CONFIG_PCI_PNP 614 struct pci_config_table *cfg; 615 #endif 616 pci_dev_t dev; 617 #ifdef CONFIG_PCI_SCAN_SHOW 618 static int indent = 0; 619 #endif 620 621 sub_bus = bus; 622 623 for (dev = PCI_BDF(bus,0,0); 624 dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, 625 PCI_MAX_PCI_FUNCTIONS - 1); 626 dev += PCI_BDF(0, 0, 1)) { 627 628 if (pci_skip_dev(hose, dev)) 629 continue; 630 631 if (PCI_FUNC(dev) && !found_multi) 632 continue; 633 634 pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); 635 636 pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); 637 638 if (vendor == 0xffff || vendor == 0x0000) 639 continue; 640 641 if (!PCI_FUNC(dev)) 642 found_multi = header_type & 0x80; 643 644 debug("PCI Scan: Found Bus %d, Device %d, Function %d\n", 645 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); 646 647 pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device); 648 pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); 649 650 #ifdef CONFIG_PCI_FIXUP_DEV 651 board_pci_fixup_dev(hose, dev, vendor, device, class); 652 #endif 653 654 #ifdef CONFIG_PCI_SCAN_SHOW 655 indent++; 656 657 /* Print leading space, including bus indentation */ 658 printf("%*c", indent + 1, ' '); 659 660 if (pci_print_dev(hose, dev)) { 661 printf("%02x:%02x.%-*x - %04x:%04x - %s\n", 662 PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev), 663 vendor, device, pci_class_str(class >> 8)); 664 } 665 #endif 666 667 #ifdef CONFIG_PCI_PNP 668 sub_bus = max((unsigned int)pciauto_config_device(hose, dev), 669 sub_bus); 670 #else 671 cfg = pci_find_config(hose, class, vendor, device, 672 PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); 673 if (cfg) { 674 cfg->config_device(hose, dev, cfg); 675 sub_bus = max(sub_bus, 676 (unsigned int)hose->current_busno); 677 } 678 #endif 679 680 #ifdef CONFIG_PCI_SCAN_SHOW 681 indent--; 682 #endif 683 684 if (hose->fixup_irq) 685 hose->fixup_irq(hose, dev); 686 } 687 688 return sub_bus; 689 } 690 691 int pci_hose_scan(struct pci_controller *hose) 692 { 693 #if defined(CONFIG_PCI_BOOTDELAY) 694 static int pcidelay_done; 695 char *s; 696 int i; 697 698 if (!pcidelay_done) { 699 /* wait "pcidelay" ms (if defined)... */ 700 s = getenv("pcidelay"); 701 if (s) { 702 int val = simple_strtoul(s, NULL, 10); 703 for (i = 0; i < val; i++) 704 udelay(1000); 705 } 706 pcidelay_done = 1; 707 } 708 #endif /* CONFIG_PCI_BOOTDELAY */ 709 710 /* 711 * Start scan at current_busno. 712 * PCIe will start scan at first_busno+1. 713 */ 714 /* For legacy support, ensure current >= first */ 715 if (hose->first_busno > hose->current_busno) 716 hose->current_busno = hose->first_busno; 717 #ifdef CONFIG_PCI_PNP 718 pciauto_config_init(hose); 719 #endif 720 return pci_hose_scan_bus(hose, hose->current_busno); 721 } 722 723 void pci_init(void) 724 { 725 hose_head = NULL; 726 727 /* now call board specific pci_init()... */ 728 pci_init_board(); 729 } 730 731 /* Returns the address of the requested capability structure within the 732 * device's PCI configuration space or 0 in case the device does not 733 * support it. 734 * */ 735 int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev, 736 int cap) 737 { 738 int pos; 739 u8 hdr_type; 740 741 pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type); 742 743 pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F); 744 745 if (pos) 746 pos = pci_find_cap(hose, dev, pos, cap); 747 748 return pos; 749 } 750 751 /* Find the header pointer to the Capabilities*/ 752 int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev, 753 u8 hdr_type) 754 { 755 u16 status; 756 757 pci_hose_read_config_word(hose, dev, PCI_STATUS, &status); 758 759 if (!(status & PCI_STATUS_CAP_LIST)) 760 return 0; 761 762 switch (hdr_type) { 763 case PCI_HEADER_TYPE_NORMAL: 764 case PCI_HEADER_TYPE_BRIDGE: 765 return PCI_CAPABILITY_LIST; 766 case PCI_HEADER_TYPE_CARDBUS: 767 return PCI_CB_CAPABILITY_LIST; 768 default: 769 return 0; 770 } 771 } 772 773 int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap) 774 { 775 int ttl = PCI_FIND_CAP_TTL; 776 u8 id; 777 u8 next_pos; 778 779 while (ttl--) { 780 pci_hose_read_config_byte(hose, dev, pos, &next_pos); 781 if (next_pos < CAP_START_POS) 782 break; 783 next_pos &= ~3; 784 pos = (int) next_pos; 785 pci_hose_read_config_byte(hose, dev, 786 pos + PCI_CAP_LIST_ID, &id); 787 if (id == 0xff) 788 break; 789 if (id == cap) 790 return pos; 791 pos += PCI_CAP_LIST_NEXT; 792 } 793 return 0; 794 } 795