summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Redfish.md4
-rw-r--r--redfish-core/lib/pcie.hpp198
2 files changed, 178 insertions, 24 deletions
diff --git a/Redfish.md b/Redfish.md
index 347048dd5f..a7b3445d82 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -863,6 +863,10 @@ other.
- LanesInUse
- PCIeType
- SerialNumber
+- Slot
+ - Lanes
+ - PCIeType
+ - SlotType
- SparePartNumber
- Status
diff --git a/redfish-core/lib/pcie.hpp b/redfish-core/lib/pcie.hpp
index 82e1a5f1a6..e10ba64643 100644
--- a/redfish-core/lib/pcie.hpp
+++ b/redfish-core/lib/pcie.hpp
@@ -35,6 +35,8 @@ namespace redfish
static constexpr const char* inventoryPath = "/xyz/openbmc_project/inventory";
static constexpr std::array<std::string_view, 1> pcieDeviceInterface = {
"xyz.openbmc_project.Inventory.Item.PCIeDevice"};
+static constexpr std::array<std::string_view, 1> pcieSlotInterface = {
+ "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
static inline void handlePCIeDevicePath(
const std::string& pcieDeviceId,
@@ -146,6 +148,148 @@ inline void requestRoutesSystemPCIeDeviceCollection(App& app)
std::bind_front(handlePCIeDeviceCollectionGet, std::ref(app)));
}
+inline void addPCIeSlotProperties(
+ crow::Response& res, const boost::system::error_code& ec,
+ const dbus::utility::DBusPropertiesMap& pcieSlotProperties)
+{
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error for getAllProperties"
+ << ec.value();
+ messages::internalError(res);
+ return;
+ }
+ std::string generation;
+ size_t lanes = 0;
+ std::string slotType;
+
+ bool success = sdbusplus::unpackPropertiesNoThrow(
+ dbus_utils::UnpackErrorPrinter(), pcieSlotProperties, "Generation",
+ generation, "Lanes", lanes, "SlotType", slotType);
+
+ if (!success)
+ {
+ messages::internalError(res);
+ return;
+ }
+
+ std::optional<pcie_device::PCIeTypes> pcieType =
+ pcie_util::redfishPcieGenerationFromDbus(generation);
+ if (!pcieType)
+ {
+ BMCWEB_LOG_WARNING << "Unknown PCIeType: " << generation;
+ }
+ else
+ {
+ if (*pcieType == pcie_device::PCIeTypes::Invalid)
+ {
+ BMCWEB_LOG_ERROR << "Invalid PCIeType: " << generation;
+ messages::internalError(res);
+ return;
+ }
+ res.jsonValue["Slot"]["PCIeType"] = *pcieType;
+ }
+
+ res.jsonValue["Slot"]["Lanes"] = lanes;
+
+ std::optional<pcie_slots::SlotTypes> redfishSlotType =
+ pcie_util::dbusSlotTypeToRf(slotType);
+ if (!redfishSlotType)
+ {
+ BMCWEB_LOG_WARNING << "Unknown PCIeSlot Type: " << slotType;
+ }
+ else
+ {
+ if (*redfishSlotType == pcie_slots::SlotTypes::Invalid)
+ {
+ BMCWEB_LOG_ERROR << "Invalid PCIeSlot type: " << slotType;
+ messages::internalError(res);
+ return;
+ }
+ res.jsonValue["Slot"]["SlotType"] = *redfishSlotType;
+ }
+}
+
+inline void getPCIeDeviceSlotPath(
+ const std::string& pcieDevicePath,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ std::function<void(const std::string& pcieDeviceSlot)>&& callback)
+{
+ std::string associationPath = pcieDevicePath + "/contained_by";
+ dbus::utility::getAssociatedSubTreePaths(
+ associationPath, sdbusplus::message::object_path(inventoryPath), 0,
+ pcieSlotInterface,
+ [callback, asyncResp, pcieDevicePath](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse& endpoints) {
+ if (ec)
+ {
+ if (ec.value() == EBADR)
+ {
+ // Missing association is not an error
+ return;
+ }
+ BMCWEB_LOG_ERROR
+ << "DBUS response error for getAssociatedSubTreePaths "
+ << ec.value();
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (endpoints.size() > 1)
+ {
+ BMCWEB_LOG_ERROR
+ << "PCIeDevice is associated with more than one PCIeSlot: "
+ << endpoints.size();
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ if (endpoints.empty())
+ {
+ // If the device doesn't have an association, return without PCIe
+ // Slot properties
+ BMCWEB_LOG_DEBUG << "PCIeDevice is not associated with PCIeSlot";
+ return;
+ }
+ callback(endpoints[0]);
+ });
+}
+
+inline void
+ afterGetDbusObject(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDeviceSlot,
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperGetObject& object)
+{
+ if (ec || object.empty())
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error for getDbusObject "
+ << ec.value();
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ sdbusplus::asio::getAllProperties(
+ *crow::connections::systemBus, object.begin()->first, pcieDeviceSlot,
+ "xyz.openbmc_project.Inventory.Item.PCIeSlot",
+ [asyncResp](
+ const boost::system::error_code& ec2,
+ const dbus::utility::DBusPropertiesMap& pcieSlotProperties) {
+ addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
+ });
+}
+
+inline void afterGetPCIeDeviceSlotPath(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDeviceSlot)
+{
+ dbus::utility::getDbusObject(
+ pcieDeviceSlot, pcieSlotInterface,
+ [asyncResp,
+ pcieDeviceSlot](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetObject& object) {
+ afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
+ });
+}
+
inline void
getPCIeDeviceHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& pcieDevicePath,
@@ -181,7 +325,7 @@ inline void
sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, service, pcieDevicePath,
"xyz.openbmc_project.Inventory.Item", "Present",
- [asyncResp](const boost::system::error_code& ec, const bool value) {
+ [asyncResp](const boost::system::error_code& ec, bool value) {
if (ec)
{
if (ec.value() != EBADR)
@@ -265,7 +409,8 @@ inline void
}
inline void addPCIeDeviceProperties(
- crow::Response& resp, const std::string& pcieDeviceId,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDeviceId,
const dbus::utility::DBusPropertiesMap& pcieDevProperties)
{
const std::string* deviceType = nullptr;
@@ -279,13 +424,13 @@ inline void addPCIeDeviceProperties(
if (!success)
{
- messages::internalError(resp);
+ messages::internalError(asyncResp->res);
return;
}
if (deviceType != nullptr && !deviceType->empty())
{
- resp.jsonValue["PCIeInterface"]["DeviceType"] = *deviceType;
+ asyncResp->res.jsonValue["PCIeInterface"]["DeviceType"] = *deviceType;
}
if (generationInUse != nullptr)
@@ -304,10 +449,10 @@ inline void addPCIeDeviceProperties(
{
BMCWEB_LOG_ERROR << "Invalid PCIe Device Generation: "
<< *generationInUse;
- messages::internalError(resp);
+ messages::internalError(asyncResp->res);
return;
}
- resp.jsonValue["PCIeInterface"]["PCIeType"] =
+ asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] =
*redfishGenerationInUse;
}
}
@@ -316,12 +461,13 @@ inline void addPCIeDeviceProperties(
// left as off if it is a default value.
if (lanesInUse != nullptr && *lanesInUse != 0)
{
- resp.jsonValue["PCIeInterface"]["LanesInUse"] = *lanesInUse;
+ asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] = *lanesInUse;
}
- resp.jsonValue["PCIeFunctions"]["@odata.id"] = boost::urls::format(
- "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions",
- pcieDeviceId);
+ asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] =
+ boost::urls::format(
+ "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions",
+ pcieDeviceId);
}
inline void getPCIeDeviceProperties(
@@ -365,6 +511,23 @@ inline void addPCIeDeviceCommonProperties(
asyncResp->res.jsonValue["Status"]["Health"] = "OK";
}
+inline void afterGetValidPcieDevicePath(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& pcieDeviceId, const std::string& pcieDevicePath,
+ const std::string& service)
+{
+ addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
+ getPCIeDeviceAsset(asyncResp, pcieDevicePath, service);
+ getPCIeDeviceState(asyncResp, pcieDevicePath, service);
+ getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
+ getPCIeDeviceProperties(
+ asyncResp, pcieDevicePath, service,
+ std::bind_front(addPCIeDeviceProperties, asyncResp, pcieDeviceId));
+ getPCIeDeviceSlotPath(
+ pcieDevicePath, asyncResp,
+ std::bind_front(afterGetPCIeDeviceSlotPath, asyncResp));
+}
+
inline void
handlePCIeDeviceGet(App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -391,20 +554,7 @@ inline void
getValidPCIeDevicePath(
pcieDeviceId, asyncResp,
- [asyncResp, pcieDeviceId](const std::string& pcieDevicePath,
- const std::string& service) {
- addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
- getPCIeDeviceAsset(asyncResp, pcieDevicePath, service);
- getPCIeDeviceState(asyncResp, pcieDevicePath, service);
- getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
- getPCIeDeviceProperties(
- asyncResp, pcieDevicePath, service,
- [asyncResp, pcieDeviceId](
- const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
- addPCIeDeviceProperties(asyncResp->res, pcieDeviceId,
- pcieDevProperties);
- });
- });
+ std::bind_front(afterGetValidPcieDevicePath, asyncResp, pcieDeviceId));
}
inline void requestRoutesSystemPCIeDevice(App& app)