Skip to content

Commit

Permalink
Improve SpiDevice error handling
Browse files Browse the repository at this point in the history
Summary:
We have a confusing error because when SpiDevice fails, we treat that as its SpiMaster failed.
So if SpiDevice X fails, in error reporting it will be reported as that SpiMaster failed.

We create a symlink for each SpiDevice and it will fail if SpiDevice creation fails.
So without some context, kinda hard to grasp a reason for symlink failure because the SpiDevice creation failure would be reported under its SpiMaster device path.

Reviewed By: somasun

Differential Revision: D67031958

fbshipit-source-id: 0737a252786d3f1bfe4987c8075e2a78dd5f666a
  • Loading branch information
Justin Kim authored and facebook-github-bot committed Dec 13, 2024
1 parent 10300eb commit c871f03
Showing 1 changed file with 50 additions and 25 deletions.
75 changes: 50 additions & 25 deletions fboss/platform/platform_manager/PciExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,45 +499,70 @@ std::map<std::string, std::string> PciExplorer::getSpiDeviceCharDevPaths(
if (!re2::RE2::FullMatch(spiDevId, kSpiDevIdRe, &busNum, &chipSelect)) {
continue;
}
// Find corresponding SpiDeviceConfig
auto spiDeviceConfigItr = std::find_if(
spiMasterConfig.spiDeviceConfigs()->begin(),
spiMasterConfig.spiDeviceConfigs()->end(),
[chipSelect](auto spiDeviceConfig) {
return *spiDeviceConfig.chipSelect() == chipSelect;
});
if (spiDeviceConfigItr == spiMasterConfig.spiDeviceConfigs()->end()) {
throw PciSubDeviceRuntimeError(
fmt::format(
"Unexpected SpiDevice created at {}. \
No matching SpiDeviceConfig defined with ChipSelect {} for SpiDevice {}",
childDirEntry.path().string(),
chipSelect,
*spiDeviceConfigItr->pmUnitScopedName()),
*spiDeviceConfigItr->pmUnitScopedName());
}
auto spiCharDevPath = fmt::format("/dev/spidev{}.{}", busNum, chipSelect);
if (!fs::exists(spiCharDevPath)) {
// For more details on the two commands:
// https://github.com/torvalds/linux/blob/master/Documentation/spi/spidev.rst#device-creation-driver-binding
// Overriding driver of the SpiDevice so spidev doesn't fail to probe.
PlatformUtils().execCommand(fmt::format(
"echo spidev > /sys/bus/spi/devices/{}/driver_override", spiDevId));
auto overrideDriver =
PlatformUtils()
.execCommand(fmt::format(
"echo spidev > /sys/bus/spi/devices/{}/driver_override",
spiDevId))
.first == 0;
if (!overrideDriver) {
throw PciSubDeviceRuntimeError(
fmt::format(
"Failed overridng SpiDriver spidev to /sys/bus/spi/devices/{}/driver_override "
"for SpiDevice {}",
spiDevId,
*spiDeviceConfigItr->pmUnitScopedName()),
*spiDeviceConfigItr->pmUnitScopedName());
}
// Bind SpiDevice to spidev driver in order to create its char device.
PlatformUtils().execCommand(fmt::format(
"echo {} > /sys/bus/spi/drivers/spidev/bind", spiDevId));
auto bindSpiDev =
PlatformUtils()
.execCommand(fmt::format(
"echo {} > /sys/bus/spi/drivers/spidev/bind", spiDevId))
.first == 0;
if (!bindSpiDev) {
throw PciSubDeviceRuntimeError(
fmt::format(
"Failed binding SpiDevice {} to /sys/bus/spi/drivers/spidev/bind for SpiDevice {}",
spiDevId,
*spiDeviceConfigItr->pmUnitScopedName()),
*spiDeviceConfigItr->pmUnitScopedName());
}
XLOG(INFO) << fmt::format(
"Completed binding SpiDevice {} to {} for SpiController {}",
"Completed initializing SpiDevice {} as {} for SpiDevice {}",
spiDevId,
spiCharDevPath,
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
*spiDeviceConfigItr->pmUnitScopedName());
} else {
XLOG(INFO) << fmt::format(
"{} already exists. Skipping binding SpiDevice {} for SpiController {}",
"{} already exists. Skipping binding SpiDevice {} for SpiDevice {}",
spiCharDevPath,
spiDevId,
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
}
auto itr = std::find_if(
spiMasterConfig.spiDeviceConfigs()->begin(),
spiMasterConfig.spiDeviceConfigs()->end(),
[chipSelect](auto spiDeviceConfig) {
return *spiDeviceConfig.chipSelect() == chipSelect;
});
if (itr == spiMasterConfig.spiDeviceConfigs()->end()) {
throw PciSubDeviceRuntimeError(
fmt::format(
"Unexpected SpiDevice created at {}. \
No matching SpiDeviceConfig defined with ChipSelect {} for SpiController {}",
childDirEntry.path().string(),
chipSelect,
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName()),
*spiMasterConfig.fpgaIpBlockConfig()->pmUnitScopedName());
*spiDeviceConfigItr->pmUnitScopedName());
}
spiCharDevPaths[*itr->pmUnitScopedName()] = spiCharDevPath;
spiCharDevPaths[*spiDeviceConfigItr->pmUnitScopedName()] = spiCharDevPath;
}
}
return spiCharDevPaths;
Expand Down

0 comments on commit c871f03

Please sign in to comment.