6 * Look for a PCI capability
8 * @v pci PCI device to query
9 * @v cap Capability code
10 * @ret address Address of capability, or 0 if not found
12 * Determine whether or not a device supports a given PCI capability.
13 * Returns the address of the requested capability structure within
14 * the device's PCI configuration space, or 0 if the device does not
17 int pci_find_capability ( struct pci_device *pci, int cap ) {
23 pci_read_config_word ( pci, PCI_STATUS, &status );
24 if ( ! ( status & PCI_STATUS_CAP_LIST ) )
27 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdr_type );
28 switch ( hdr_type & 0x7F ) {
29 case PCI_HEADER_TYPE_NORMAL:
30 case PCI_HEADER_TYPE_BRIDGE:
32 pci_read_config_byte ( pci, PCI_CAPABILITY_LIST, &pos );
34 case PCI_HEADER_TYPE_CARDBUS:
35 pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
38 while ( ttl-- && pos >= 0x40 ) {
40 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_ID, &id );
41 DBG ( "PCI Capability: %d\n", id );
46 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_NEXT, &pos );
52 * Find the size of a PCI BAR
55 * @v reg PCI register number
58 * It should not be necessary for any Etherboot code to call this
61 unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
64 /* Save the original bar */
65 pci_read_config_dword ( pci, reg, &start );
66 /* Compute which bits can be set */
67 pci_write_config_dword ( pci, reg, ~0 );
68 pci_read_config_dword ( pci, reg, &size );
69 /* Restore the original size */
70 pci_write_config_dword ( pci, reg, start );
71 /* Find the significant bits */
72 if ( start & PCI_BASE_ADDRESS_SPACE_IO ) {
73 size &= PCI_BASE_ADDRESS_IO_MASK;
75 size &= PCI_BASE_ADDRESS_MEM_MASK;
77 /* Find the lowest bit set */
78 size = size & ~( size - 1 );