diff --git a/drivers/graphics/fbcond/src/display.rs b/drivers/graphics/fbcond/src/display.rs index 46a7e5589d..a0bc8200f1 100644 --- a/drivers/graphics/fbcond/src/display.rs +++ b/drivers/graphics/fbcond/src/display.rs @@ -45,7 +45,9 @@ impl Display { let new_display_handle = match V2GraphicsHandle::from_file(display_file) { Ok(handle) => handle, Err(err) => { - log::warn!("fbcond: display not ready at handoff (from_file: {err}); will retry"); + // Transient during the handoff race; handle_handoff retries and + // emits a single warning if it ultimately gives up. + log::debug!("fbcond: display not ready at handoff (from_file: {err}); will retry"); return; } }; diff --git a/drivers/graphics/fbcond/src/text.rs b/drivers/graphics/fbcond/src/text.rs index fbf03f89ba..e74ffad4a0 100644 --- a/drivers/graphics/fbcond/src/text.rs +++ b/drivers/graphics/fbcond/src/text.rs @@ -53,10 +53,28 @@ impl TextScreen { pub fn handle_handoff(&mut self) { log::info!("fbcond: Performing handoff"); - self.display.reopen_for_handoff(); - if self.display.map.is_some() { - self.flush_pending_writes(); + // The handoff is one-shot: inputd signals it the moment the real display + // driver registers its path, but the driver's scheme may not serve the + // v2 open / capability query for a few more milliseconds. Without a + // retry, a transient not-ready driver leaves the framebuffer permanently + // blank (the login prompt is drawn to the framebuffer VT, so the console + // appears dead even though boot continues on the serial mirror). Retry + // briefly — the driver becomes ready well within this bound in practice. + for attempt in 0..250u32 { + self.display.reopen_for_handoff(); + if self.display.map.is_some() { + if attempt > 0 { + log::info!("fbcond: handoff completed after {attempt} retries"); + } + self.flush_pending_writes(); + return; + } + std::thread::sleep(std::time::Duration::from_millis(10)); } + log::warn!( + "fbcond: display still not ready after handoff retries; \ + framebuffer console will remain blank (serial mirror unaffected)" + ); } pub fn input(&mut self, event: &Event) {