tools/pci: replace pciutils with pciaccess
The pciutils library has a license which is incompatible with ours, so
switch to pciaccess instead since it's MIT-licensed.
Signed-off-by: Benjamin Fair <benjaminfair@google.com>
Change-Id: Ie40580d9992f7c30d9fdc904f97c89057791b10e
diff --git a/README.md b/README.md
index ea03fc0..7774718 100644
--- a/README.md
+++ b/README.md
@@ -14,15 +14,25 @@
The host-tool depends on ipmi-blob-tool and pciutils.
-#### Building pciutils
+#### Building libpciaccess
-Check out the [pciutils source](https://github.com/pciutils/pciutils).
+Check out the [xorg-macros source](https://gitlab.freedesktop.org/xorg/util/macros).
Then run these commands in the source directory.
+
```
-make SHARED=yes
-make SHARED=yes install
-make install-lib
+./autogen.sh --prefix=/usr
+make install
+```
+
+Check out the [libpciaccess source](https://gitlab.freedesktop.org/xorg/lib/libpciaccess).
+
+Then run these commands in the source directory.
+
+```
+./autogen.sh
+make
+make install
```
#### Building ipmi-blob-tool
diff --git a/configure.ac b/configure.ac
index 41dd7f2..94ed8b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,10 +123,10 @@
# If not building the host-tool, we're building the BMC.
AS_IF([test "x$enable_build_host_tool" != "xno"], [
PKG_CHECK_MODULES(
- [PCILIB],
- [libpci],
+ [PCIACCESS],
+ [pciaccess >= 0.8.0],
[],
- [AC_MSG_ERROR([Could not find libpci... pciutils package required])]
+ [AC_MSG_ERROR([Could not find libpciaccess... pciaccess package required])]
)
])
diff --git a/internal/sys.hpp b/internal/sys.hpp
index a399903..7c56818 100644
--- a/internal/sys.hpp
+++ b/internal/sys.hpp
@@ -16,6 +16,7 @@
#include <cinttypes>
#include <cstddef>
#include <cstdint>
+#include <system_error>
namespace internal
{
@@ -88,6 +89,11 @@
std::int64_t getSize(const char* pathname) const override;
};
+inline std::system_error errnoException(const std::string& message)
+{
+ return std::system_error(errno, std::generic_category(), message);
+}
+
/** @brief Default instantiation of sys */
extern SysImpl sys_impl;
diff --git a/tools/Makefile.am b/tools/Makefile.am
index bb2a317..e0a192e 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -7,12 +7,12 @@
$(CODE_COVERAGE_CXXFLAGS)
noinst_LTLIBRARIES = libupdater.la
-libupdater_la_LDFLAGS = -static $(CODE_COVERAGE_LIBS) $(IPMIBLOB_LIBS) $(PCILIB_LIBS)
+libupdater_la_LDFLAGS = -static $(CODE_COVERAGE_LIBS) $(IPMIBLOB_LIBS) $(PCIACCESS_LIBS)
libupdater_la_CXXFLAGS = \
-I$(top_srcdir) \
$(CODE_COVERAGE_CXXFLAGS) \
$(IPMIBLOB_CFLAGS) \
- $(PCILIB_CFLAGS)
+ $(PCIACCESS_CFLAGS)
libupdater_la_SOURCES = \
updater.cpp \
handler.cpp \
diff --git a/tools/main.cpp b/tools/main.cpp
index 0e29295..dd43c11 100644
--- a/tools/main.cpp
+++ b/tools/main.cpp
@@ -217,7 +217,6 @@
#else
host_tool::DevMemDevice devmem;
#endif
- host_tool::PciUtilImpl pci;
host_tool::ProgressStdoutIndicator progress;
std::unique_ptr<host_tool::DataInterface> handler;
@@ -250,6 +249,7 @@
}
else if (interface == IPMIPCI)
{
+ auto& pci = host_tool::PciUtilImpl::getInstance();
handler = std::make_unique<host_tool::P2aDataHandler>(
&blob, &devmem, &pci, &progress);
}
diff --git a/tools/pci.cpp b/tools/pci.cpp
index feb5c60..7fa4d59 100644
--- a/tools/pci.cpp
+++ b/tools/pci.cpp
@@ -18,9 +18,11 @@
extern "C"
{
-#include <pci/pci.h>
+#include <pciaccess.h>
} // extern "C"
+#include <linux/pci_regs.h>
+
#include <cstring>
#include <optional>
#include <vector>
@@ -31,45 +33,40 @@
std::vector<PciDevice>
PciUtilImpl::getPciDevices(std::optional<PciFilter> filter)
{
- PciFilter test;
- bool check = false;
+ struct pci_id_match match = {PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ PCI_MATCH_ANY};
std::vector<PciDevice> results;
if (filter.has_value())
{
- test = filter.value();
- check = true;
+ match.vendor_id = filter.value().vid;
+ match.device_id = filter.value().did;
}
- pci_scan_bus(pacc);
- struct pci_dev* dev;
+ auto it = pci_id_match_iterator_create(&match);
+ struct pci_device* dev;
- for (dev = pacc->devices; dev; dev = dev->next)
+ while ((dev = pci_device_next(it)))
{
PciDevice item;
- pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS);
+ pci_device_probe(dev);
item.bus = dev->bus;
item.dev = dev->dev;
item.func = dev->func;
item.vid = dev->vendor_id;
item.did = dev->device_id;
- std::memcpy(item.bars, dev->base_addr, sizeof(dev->base_addr));
- if (check)
+ for (int i = 0; i < PCI_STD_NUM_BARS; i++)
{
- if (test.vid == dev->vendor_id && test.did == dev->device_id)
- {
- results.push_back(item);
- }
+ item.bars[i] = dev->regions[i].base_addr;
}
- else
- {
- results.push_back(item);
- }
+
+ results.push_back(item);
}
+ pci_iterator_destroy(it);
return results;
}
diff --git a/tools/pci.hpp b/tools/pci.hpp
index 0edc531..f421892 100644
--- a/tools/pci.hpp
+++ b/tools/pci.hpp
@@ -1,14 +1,23 @@
#pragma once
+#include "internal/sys.hpp"
+
extern "C"
{
-#include <pci/pci.h>
+#include <pciaccess.h>
} // extern "C"
+#include <linux/pci_regs.h>
+
#include <cstdint>
+#include <memory>
#include <optional>
#include <vector>
+#ifndef PCI_STD_NUM_BARS
+#define PCI_STD_NUM_BARS 6
+#endif // !PCI_STD_NUM_BARS
+
namespace host_tool
{
@@ -25,7 +34,7 @@
std::uint8_t bus;
std::uint8_t dev;
std::uint8_t func;
- pciaddr_t bars[6];
+ pciaddr_t bars[PCI_STD_NUM_BARS];
};
/**
@@ -56,21 +65,32 @@
class PciUtilImpl : public PciUtilInterface
{
public:
- PciUtilImpl()
+ static PciUtilImpl& getInstance()
{
- pacc = pci_alloc();
- pci_init(pacc);
- }
- ~PciUtilImpl()
- {
- pci_cleanup(pacc);
+ static PciUtilImpl instance;
+ return instance;
}
std::vector<PciDevice>
getPciDevices(std::optional<PciFilter> filter = std::nullopt) override;
+ PciUtilImpl(const PciUtilImpl&) = delete;
+ PciUtilImpl& operator=(const PciUtilImpl&) = delete;
+
private:
- struct pci_access* pacc;
+ PciUtilImpl()
+ {
+ int ret = pci_system_init();
+ if (ret)
+ {
+ throw internal::errnoException("pci_system_init");
+ }
+ }
+
+ ~PciUtilImpl()
+ {
+ pci_system_cleanup();
+ }
};
} // namespace host_tool