@@ -807,11 +807,15 @@ namespace pci {
807807 write_pci_config (_bus, _device, _func, offset, val);
808808 }
809809
810+ // Returns the offset of the first capability with id matching @cap_id, or
811+ // 0xFF if none found.
810812 u8 function::find_capability (u8 cap_id)
811813 {
812- return this -> find_capability (cap_id, [](function *fun, u8 off) { return true ; } );
814+ return find_capability (cap_id, [](function *fun, u8 off) { return true ; } );
813815 }
814816
817+ // Returns the offset of the first capability with id matching @cap_id and
818+ // satisfying @predicate (if specified). If none found, returns 0xFF.
815819 u8 function::find_capability (u8 cap_id, std::function<bool (function*, u8 )> predicate)
816820 {
817821 u8 capabilities_base = pci_readb (PCI_CAPABILITIES_PTR);
@@ -839,6 +843,36 @@ namespace pci {
839843 return bad_offset;
840844 }
841845
846+ // Append to @cap_offs the offsets of all capabilities with id matching
847+ // @cap_id. Returns whether any such capabilities were found.
848+ bool function::find_capabilities (std::vector<u8 >& cap_offs, u8 cap_id)
849+ {
850+ u8 capabilities_base = pci_readb (PCI_CAPABILITIES_PTR);
851+ u8 off = capabilities_base;
852+ u8 max_capabilities = 0xF0 ;
853+ u8 ctr = 0 ;
854+ bool found = false ;
855+
856+ while (off != 0 ) {
857+ // Read capability
858+ u8 capability = pci_readb (off + PCI_CAP_OFF_ID);
859+ if (capability == cap_id) {
860+ cap_offs.push_back (off);
861+ found = true ;
862+ }
863+
864+ ctr++;
865+ if (ctr > max_capabilities) {
866+ return found;
867+ }
868+
869+ // Next
870+ off = pci_readb (off + PCI_CAP_OFF_NEXT);
871+ }
872+
873+ return found;
874+ }
875+
842876 bar * function::get_bar (int idx)
843877 {
844878 auto it = _bars.find (idx);
0 commit comments