sculpt: safeguard the offering of suspend/resume

The USB host controller gets restarted during the suspend-resume cycle.
Hence, don't offer suspend while any USB storage device is in use, in
particular when deploying Sculpt from a USB stick.

Suspend/resume is not supposed to work with any framebuffer driver other
than intel_fb. Therefore, offer the suspend feature only when using intel_fb.

Issue #5174
This commit is contained in:
Norman Feske 2024-04-18 14:18:58 +02:00 committed by Christian Helmuth
parent f2b921f380
commit 9e69c7301a
5 changed files with 30 additions and 4 deletions

View File

@ -141,6 +141,13 @@ struct Sculpt::Fb_driver : private Noncopyable
_boot_fb.construct(registry, "boot_fb", Priority::MULTIMEDIA,
mode.ram_quota(), Cap_quota { 100 }); });
}
static bool suspend_supported(Board_info const &board_info)
{
/* offer suspend/resume only when using intel graphics */
return board_info.detected.intel_gfx
&& !board_info.options.suppress.intel_gpu;
}
};
#endif /* _DRIVER__FB_H_ */

View File

@ -37,21 +37,27 @@ struct Sculpt::Usb_driver : private Noncopyable
Constructible<Child_state> _hcd { }, _hid { }, _net { };
static constexpr unsigned CLASS_HID = 3, CLASS_NET = 2;
static constexpr unsigned CLASS_HID = 3, CLASS_NET = 2, CLASS_STORAGE = 8;
struct Detected
{
bool hid, net;
bool storage_aquired;
static Detected from_xml(Xml_node const &devices)
{
Detected result { };
devices.for_each_sub_node("device", [&] (Xml_node const &device) {
bool const acquired = device.attribute_value("acquired", false);
device.for_each_sub_node("config", [&] (Xml_node const &config) {
config.for_each_sub_node("interface", [&] (Xml_node const &interface) {
unsigned const class_id = interface.attribute_value("class", 0u);
result.hid |= (class_id == CLASS_HID);
result.net |= (class_id == CLASS_NET); }); }); });
result.hid |= (class_id == CLASS_HID);
result.net |= (class_id == CLASS_NET);
result.storage_aquired |= (class_id == CLASS_STORAGE) && acquired;
});
});
});
return result;
}
@ -183,6 +189,8 @@ struct Sculpt::Usb_driver : private Noncopyable
_devices.with_xml([&] (Xml_node const &devices) {
fn(_hcd.constructed() ? devices : Xml_node("<none/>")); });
}
bool suspend_supported() const { return !_detected.storage_aquired; }
};
#endif /* _DRIVER__USB_H_ */

View File

@ -165,6 +165,12 @@ class Sculpt::Drivers::Instance : Noncopyable,
void with(With_board_info::Callback const &fn) const { fn(_board_info); }
void with(With_platform_info::Callback const &fn) const { fn(_platform.xml()); }
bool suspend_supported() const
{
return _fb_driver.suspend_supported(_board_info)
&& _usb_driver.suspend_supported();
}
bool ready_for_suspend() const { return !_board_info.used.any(); }
Resumed resumed() const { return _resumed; }
@ -201,6 +207,7 @@ void Drivers::update_options(Board_info::Options opt) { _instance.update_options
void Drivers::gen_start_nodes(Xml_generator &xml) const { _instance.gen_start_nodes(xml); }
bool Drivers::suspend_supported() const { return _instance.suspend_supported(); };
bool Drivers::ready_for_suspend() const { return _instance.ready_for_suspend(); };
Drivers::Resumed Drivers::resumed() const { return _instance.resumed(); };

View File

@ -73,6 +73,10 @@ class Sculpt::Drivers : Noncopyable
void with_board_info (auto const &fn) const { _with(With_board_info::Fn { fn }); }
void with_platform_info (auto const &fn) const { _with(With_platform_info::Fn { fn }); }
/* true if hardware is suspend/resume capable */
bool suspend_supported() const;
/* true once 'Board_info::Option::suspending' phase is compete */
bool ready_for_suspend() const;
struct Resumed { unsigned count; };

View File

@ -2204,7 +2204,7 @@ void Sculpt::Main::_handle_runtime_state(Xml_node const &state)
bool const acpi_support = _runtime_state.present_in_runtime("acpi_support");
Power_features const orig_power_features = _power_features;
_power_features.poweroff = acpi_support;
_power_features.suspend = acpi_support;
_power_features.suspend = acpi_support && _drivers.suspend_supported();;
if (orig_power_features != _power_features)
_system_dialog.refresh();
}