| 551 | } |
| 552 | |
| 553 | VOID GetPciADR(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT UINT32 *Addr1, OUT UINT32 *Addr2, OUT UINT32 *Addr3) |
| 554 | { |
| 555 | PCI_DEVICE_PATH *PciNode; |
| 556 | UINTN PciNodeCount; |
| 557 | EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath = DuplicateDevicePath(DevicePath); |
| 558 | |
| 559 | // default to 0 |
| 560 | if (Addr1 != NULL) *Addr1 = 0; |
| 561 | if (Addr2 != NULL) *Addr2 = 0xFFFE; //some code we will consider as "non-exists" b/c 0 is meaningful value |
| 562 | // as well as 0xFFFF |
| 563 | if (Addr3 != NULL) *Addr3 = 0xFFFE; |
| 564 | if (!TmpDevicePath) { |
| 565 | return; |
| 566 | } |
| 567 | |
| 568 | // sanity check - expecting ACPI path for PciRoot |
| 569 | if (TmpDevicePath->Type != ACPI_DEVICE_PATH && TmpDevicePath->SubType != ACPI_DP) { |
| 570 | FreePool(TmpDevicePath); |
| 571 | return; |
| 572 | } |
| 573 | |
| 574 | PciNodeCount = 0; |
| 575 | while (TmpDevicePath && !IsDevicePathEndType(TmpDevicePath)) { |
| 576 | if (TmpDevicePath->Type == HARDWARE_DEVICE_PATH && TmpDevicePath->SubType == HW_PCI_DP) { |
| 577 | PciNodeCount++; |
| 578 | PciNode = (PCI_DEVICE_PATH *)TmpDevicePath; |
| 579 | if (PciNodeCount == 1 && Addr1 != NULL) { |
| 580 | *Addr1 = (PciNode->Device << 16) | PciNode->Function; |
| 581 | } else if (PciNodeCount == 2 && Addr2 != NULL) { |
| 582 | *Addr2 = (PciNode->Device << 16) | PciNode->Function; |
| 583 | } else if (PciNodeCount == 3 && Addr3 != NULL) { |
| 584 | *Addr3 = (PciNode->Device << 16) | PciNode->Function; |
| 585 | } else { |
| 586 | break; |
| 587 | } |
| 588 | } |
| 589 | TmpDevicePath = NextDevicePathNode(TmpDevicePath); |
| 590 | } |
| 591 | return; |
| 592 | } |
| 593 | |
| 594 | /* Discussion |
| 595 | Native USB mean for those chipsets IOUSBFamily set some "errata" |
no test coverage detected