Skip to content

Commit

Permalink
bmc_application: restore power and usb settings
Browse files Browse the repository at this point in the history
This commit contains 2 improvements:
* Internal operations are not triggering persistency updates anymore.
  Minimizing flash wear.
* After a flash command the power and USB settings are restored to their
  previous values
  • Loading branch information
svenrademakers committed Nov 3, 2023
1 parent 5f8ed0f commit 2e2b7bb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
25 changes: 18 additions & 7 deletions src/app/bmc_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl BmcApplication {
self.initialize_power().await
}

async fn initialize_power(&self) -> anyhow::Result<()> {
pub async fn initialize_power(&self) -> anyhow::Result<()> {
if self.app_db.get::<u8>(ACTIVATED_NODES_KEY).await != 0 {
self.power_on().await?;
}
Expand Down Expand Up @@ -187,7 +187,19 @@ impl BmcApplication {
self.power_controller.set_power_node(0b0000, 0b1111).await
}

pub async fn power_off_node(&self, node: NodeId) -> anyhow::Result<()> {
self.power_controller
.set_power_node(node.to_bitfield(), node.to_bitfield())
.await
}

pub async fn configure_usb(&self, config: UsbConfig) -> anyhow::Result<()> {
self.configure_usb_internal(config).await?;
self.app_db.set(USB_CONFIG, config).await;
Ok(())
}

async fn configure_usb_internal(&self, config: UsbConfig) -> anyhow::Result<()> {
log::debug!("changing usb config to {:?}", config);
let (mode, dest, route) = match config {
UsbConfig::UsbA(device) => (UsbMode::Device, device, UsbRoute::UsbA),
Expand All @@ -197,7 +209,6 @@ impl BmcApplication {

self.pin_controller.set_usb_route(route).await?;
self.pin_controller.select_usb(dest, mode)?;
self.app_db.set(USB_CONFIG, config).await;
Ok(())
}

Expand All @@ -220,8 +231,6 @@ impl BmcApplication {
}

pub async fn set_node_in_msd(&self, node: NodeId, router: UsbRoute) -> anyhow::Result<()> {
// The SUPPORTED_MSD_DEVICES list contains vid_pids of USB drivers we know will load the
// storage of a node as a MSD device.
self.configure_node_for_fwupgrade(node, router, SUPPORTED_DEVICES.keys())
.await
.map(|_| ())
Expand All @@ -237,7 +246,8 @@ impl BmcApplication {
I: IntoIterator<Item = &'a (u16, u16)>,
{
log::info!("Powering off node {:?}...", node);
self.activate_slot(!node.to_bitfield(), node.to_bitfield())
self.power_controller
.set_power_node(!node.to_bitfield(), node.to_bitfield())
.await?;
self.pin_controller
.set_usb_boot(!node.to_bitfield(), node.to_bitfield())?;
Expand All @@ -249,10 +259,11 @@ impl BmcApplication {
UsbRoute::UsbA => UsbConfig::UsbA(node),
};
self.usb_boot(node, true).await?;
self.configure_usb(config).await?;
self.configure_usb_internal(config).await?;

log::info!("Prerequisite settings toggled, powering on...");
self.activate_slot(node.to_bitfield(), node.to_bitfield())
self.power_controller
.set_power_node(node.to_bitfield(), node.to_bitfield())
.await?;

tokio::time::sleep(Duration::from_secs(1)).await;
Expand Down
15 changes: 4 additions & 11 deletions src/app/firmware_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::bmc_application::UsbConfig;
use crate::app::bmc_application::BmcApplication;
use crate::firmware_update::FwUpdateError;
use crate::utils::{reader_with_crc64, WriteWatcher};
Expand Down Expand Up @@ -100,17 +99,11 @@ impl FirmwareRunner {
bail!(FwUpdateError::ChecksumMismatch)
}

log::info!("Flashing {node} successful, restarting device...");
bmc.activate_slot(!node.to_bitfield(), node.to_bitfield())
.await?;

//TODO: we probably want to restore the state prior flashing
log::info!("Flashing {node} successful, restoring USB & power settings...");
bmc.power_off_node(node).await?;
bmc.usb_boot(node, false).await?;
bmc.configure_usb(UsbConfig::UsbA(node)).await?;
bmc.activate_slot(node.to_bitfield(), node.to_bitfield())
.await?;

Ok(())
bmc.configure_usb(bmc.get_usb_mode().await).await?;
bmc.initialize_power().await
}

pub async fn os_update(self) -> anyhow::Result<()> {
Expand Down

0 comments on commit 2e2b7bb

Please sign in to comment.