|
@@ -3,6 +3,24 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
3
|
3
|
#include <stdint.h>
|
4
|
4
|
#include <ipxe/pci.h>
|
5
|
5
|
|
|
6
|
+static int pci_find_capability_common ( struct pci_device *pci,
|
|
7
|
+ uint8_t pos, int cap ) {
|
|
8
|
+ uint8_t id;
|
|
9
|
+ int ttl = 48;
|
|
10
|
+
|
|
11
|
+ while ( ttl-- && pos >= 0x40 ) {
|
|
12
|
+ pos &= ~3;
|
|
13
|
+ pci_read_config_byte ( pci, pos + PCI_CAP_ID, &id );
|
|
14
|
+ DBG ( "PCI Capability: %d\n", id );
|
|
15
|
+ if ( id == 0xff )
|
|
16
|
+ break;
|
|
17
|
+ if ( id == cap )
|
|
18
|
+ return pos;
|
|
19
|
+ pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &pos );
|
|
20
|
+ }
|
|
21
|
+ return 0;
|
|
22
|
+}
|
|
23
|
+
|
6
|
24
|
/**
|
7
|
25
|
* Look for a PCI capability
|
8
|
26
|
*
|
|
@@ -17,9 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
17
|
35
|
*/
|
18
|
36
|
int pci_find_capability ( struct pci_device *pci, int cap ) {
|
19
|
37
|
uint16_t status;
|
20
|
|
- uint8_t pos, id;
|
|
38
|
+ uint8_t pos;
|
21
|
39
|
uint8_t hdr_type;
|
22
|
|
- int ttl = 48;
|
23
|
40
|
|
24
|
41
|
pci_read_config_word ( pci, PCI_STATUS, &status );
|
25
|
42
|
if ( ! ( status & PCI_STATUS_CAP_LIST ) )
|
|
@@ -36,17 +53,28 @@ int pci_find_capability ( struct pci_device *pci, int cap ) {
|
36
|
53
|
pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
|
37
|
54
|
break;
|
38
|
55
|
}
|
39
|
|
- while ( ttl-- && pos >= 0x40 ) {
|
40
|
|
- pos &= ~3;
|
41
|
|
- pci_read_config_byte ( pci, pos + PCI_CAP_ID, &id );
|
42
|
|
- DBG ( "PCI Capability: %d\n", id );
|
43
|
|
- if ( id == 0xff )
|
44
|
|
- break;
|
45
|
|
- if ( id == cap )
|
46
|
|
- return pos;
|
47
|
|
- pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &pos );
|
48
|
|
- }
|
49
|
|
- return 0;
|
|
56
|
+ return pci_find_capability_common ( pci, pos, cap );
|
|
57
|
+}
|
|
58
|
+
|
|
59
|
+/**
|
|
60
|
+ * Look for another PCI capability
|
|
61
|
+ *
|
|
62
|
+ * @v pci PCI device to query
|
|
63
|
+ * @v pos Address of the current capability
|
|
64
|
+ * @v cap Capability code
|
|
65
|
+ * @ret address Address of capability, or 0 if not found
|
|
66
|
+ *
|
|
67
|
+ * Determine whether or not a device supports a given PCI capability
|
|
68
|
+ * starting the search at a given address within the device's PCI
|
|
69
|
+ * configuration space. Returns the address of the next capability
|
|
70
|
+ * structure within the device's PCI configuration space, or 0 if the
|
|
71
|
+ * device does not support another such capability.
|
|
72
|
+ */
|
|
73
|
+int pci_find_next_capability ( struct pci_device *pci, int pos, int cap ) {
|
|
74
|
+ uint8_t new_pos;
|
|
75
|
+
|
|
76
|
+ pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &new_pos );
|
|
77
|
+ return pci_find_capability_common ( pci, new_pos, cap );
|
50
|
78
|
}
|
51
|
79
|
|
52
|
80
|
/**
|