Anime: Better prevent await blocking. Prevent Slash taking over anime USB dev

This commit is contained in:
Luke D. Jones
2024-05-05 10:56:55 +12:00
parent 661ea8d3bf
commit 487d140bd5
9 changed files with 204 additions and 124 deletions

View File

@@ -106,7 +106,7 @@ impl AnimeConfigCached {
} }
/// Config for base system actions for the anime display /// Config for base system actions for the anime display
#[derive(Deserialize, Serialize, Debug)] #[derive(Deserialize, Serialize, Debug, Clone)]
pub struct AnimeConfig { pub struct AnimeConfig {
pub model_override: Option<AnimeType>, pub model_override: Option<AnimeType>,
pub system: Vec<ActionLoader>, pub system: Vec<ActionLoader>,

View File

@@ -66,26 +66,28 @@ impl CtrlAnime {
let usb = USBRaw::new(0x193b).ok(); let usb = USBRaw::new(0x193b).ok();
let hid = HidRaw::new("193b").ok(); let hid = HidRaw::new("193b").ok();
let node = if usb.is_some() { let node = if usb.is_some() {
info!("Anime using the USB interface");
unsafe { Node::Usb(usb.unwrap_unchecked()) } unsafe { Node::Usb(usb.unwrap_unchecked()) }
} else if hid.is_some() { } else if hid.is_some() {
info!("Anime using the HID interface");
unsafe { Node::Hid(hid.unwrap_unchecked()) } unsafe { Node::Hid(hid.unwrap_unchecked()) }
} else { } else {
return Err(RogError::Anime(AnimeError::NoDevice)); return Err(RogError::Anime(AnimeError::NoDevice));
}; };
// TODO: something better to set wakeups disabled // TODO: something better to set wakeups disabled
if matches!(node, Node::Usb(_)) { // if matches!(node, Node::Usb(_)) {
if let Ok(mut enumerator) = udev::Enumerator::new() { // if let Ok(mut enumerator) = udev::Enumerator::new() {
enumerator.match_subsystem("usb").ok(); // enumerator.match_subsystem("usb").ok();
enumerator.match_attribute("idProduct", "193b").ok(); // enumerator.match_attribute("idProduct", "193b").ok();
if let Ok(mut enumer) = enumerator.scan_devices() { // if let Ok(mut enumer) = enumerator.scan_devices() {
if let Some(mut dev) = enumer.next() { // if let Some(mut dev) = enumer.next() {
dev.set_attribute_value("power/wakeup", "disabled").ok(); // dev.set_attribute_value("power/wakeup", "disabled").ok();
} // }
} // }
} // }
} // }
let mut anime_type = get_anime_type()?; let mut anime_type = get_anime_type()?;
if let AnimeType::Unknown = anime_type { if let AnimeType::Unknown = anime_type {

View File

@@ -12,6 +12,7 @@ use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
use zbus::export::futures_util::lock::Mutex; use zbus::export::futures_util::lock::Mutex;
use zbus::{interface, CacheProperties, Connection, SignalContext}; use zbus::{interface, CacheProperties, Connection, SignalContext};
use super::config::AnimeConfig;
use super::CtrlAnime; use super::CtrlAnime;
use crate::error::RogError; use crate::error::RogError;
@@ -48,42 +49,53 @@ impl CtrlAnimeZbus {
/// Writes a data stream of length. Will force system thread to exit until /// Writes a data stream of length. Will force system thread to exit until
/// it is restarted /// it is restarted
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> { async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
let lock = self.0.lock().await; self.0
lock.thread_exit.store(true, Ordering::SeqCst); .lock()
lock.write_data_buffer(input).map_err(|err| { .await
warn!("ctrl_anime::run_animation:callback {}", err); .thread_exit
err .store(true, Ordering::SeqCst);
})?; self.0
.lock()
.await
.write_data_buffer(input)
.map_err(|err| {
warn!("ctrl_anime::run_animation:callback {}", err);
err
})?;
Ok(()) Ok(())
} }
/// Set base brightness level /// Set base brightness level
#[zbus(property)] #[zbus(property)]
async fn brightness(&self) -> Brightness { async fn brightness(&self) -> Brightness {
let lock = self.0.lock().await; self.0.lock().await.config.display_brightness
lock.config.display_brightness
} }
/// Set base brightness level /// Set base brightness level
#[zbus(property)] #[zbus(property)]
async fn set_brightness(&self, brightness: Brightness) { async fn set_brightness(&self, brightness: Brightness) {
let mut lock = self.0.lock().await; self.0
lock.node .lock()
.await
.node
.write_bytes(&pkt_set_brightness(brightness)) .write_bytes(&pkt_set_brightness(brightness))
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::set_brightness {}", err); warn!("ctrl_anime::set_brightness {}", err);
}) })
.ok(); .ok();
lock.node self.0
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display(brightness != Brightness::Off)) .write_bytes(&pkt_set_enable_display(brightness != Brightness::Off))
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::set_brightness {}", err); warn!("ctrl_anime::set_brightness {}", err);
}) })
.ok(); .ok();
lock.config.display_enabled = brightness != Brightness::Off; self.0.lock().await.config.display_enabled = brightness != Brightness::Off;
lock.config.display_brightness = brightness; self.0.lock().await.config.display_brightness = brightness;
lock.config.write(); self.0.lock().await.config.write();
} }
#[zbus(property)] #[zbus(property)]
@@ -96,20 +108,27 @@ impl CtrlAnimeZbus {
/// animations" in Armory crate /// animations" in Armory crate
#[zbus(property)] #[zbus(property)]
async fn set_builtins_enabled(&self, enabled: bool) { async fn set_builtins_enabled(&self, enabled: bool) {
let mut lock = self.0.lock().await; let brightness = self.0.lock().await.config.display_brightness;
lock.node self.0
.set_builtins_enabled(enabled, lock.config.display_brightness) .lock()
.await
.node
.set_builtins_enabled(enabled, brightness)
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::set_builtins_enabled {}", err); warn!("ctrl_anime::set_builtins_enabled {}", err);
}) })
.ok(); .ok();
if !enabled { if !enabled {
let data = vec![255u8; lock.anime_type.data_length()]; let anime_type = self.0.lock().await.anime_type;
if let Ok(tmp) = AnimeDataBuffer::from_vec(lock.anime_type, data).map_err(|err| { let data = vec![255u8; anime_type.data_length()];
if let Ok(tmp) = AnimeDataBuffer::from_vec(anime_type, data).map_err(|err| {
warn!("ctrl_anime::set_builtins_enabled {}", err); warn!("ctrl_anime::set_builtins_enabled {}", err);
}) { }) {
lock.node self.0
.lock()
.await
.node
.write_bytes(tmp.data()) .write_bytes(tmp.data())
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::set_builtins_enabled {}", err); warn!("ctrl_anime::set_builtins_enabled {}", err);
@@ -118,24 +137,29 @@ impl CtrlAnimeZbus {
} }
} }
lock.config.builtin_anims_enabled = enabled; self.0.lock().await.config.builtin_anims_enabled = enabled;
lock.config.write(); self.0.lock().await.config.write();
if enabled { if enabled {
lock.thread_exit.store(true, Ordering::Release); self.0
.lock()
.await
.thread_exit
.store(true, Ordering::Release);
} }
} }
#[zbus(property)] #[zbus(property)]
async fn builtin_animations(&self) -> Animations { async fn builtin_animations(&self) -> Animations {
let lock = self.0.lock().await; self.0.lock().await.config.builtin_anims
lock.config.builtin_anims
} }
/// Set which builtin animation is used for each stage /// Set which builtin animation is used for each stage
#[zbus(property)] #[zbus(property)]
async fn set_builtin_animations(&self, settings: Animations) { async fn set_builtin_animations(&self, settings: Animations) {
let mut lock = self.0.lock().await; self.0
lock.node .lock()
.await
.node
.write_bytes(&pkt_set_builtin_animations( .write_bytes(&pkt_set_builtin_animations(
settings.boot, settings.boot,
settings.awake, settings.awake,
@@ -146,114 +170,125 @@ impl CtrlAnimeZbus {
warn!("ctrl_anime::run_animation:callback {}", err); warn!("ctrl_anime::run_animation:callback {}", err);
}) })
.ok(); .ok();
lock.node self.0
.lock()
.await
.node
.write_bytes(&pkt_set_enable_powersave_anim(true)) .write_bytes(&pkt_set_enable_powersave_anim(true))
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::run_animation:callback {}", err); warn!("ctrl_anime::run_animation:callback {}", err);
}) })
.ok(); .ok();
lock.config.display_enabled = true; self.0.lock().await.config.display_enabled = true;
lock.config.builtin_anims = settings; self.0.lock().await.config.builtin_anims = settings;
lock.config.write(); self.0.lock().await.config.write();
} }
#[zbus(property)] #[zbus(property)]
async fn enable_display(&self) -> bool { async fn enable_display(&self) -> bool {
let lock = self.0.lock().await; self.0.lock().await.config.display_enabled
lock.config.display_enabled
} }
/// Set whether the AniMe is enabled at all /// Set whether the AniMe is enabled at all
#[zbus(property)] #[zbus(property)]
async fn set_enable_display(&self, enabled: bool) { async fn set_enable_display(&self, enabled: bool) {
let mut lock = self.0.lock().await; self.0
lock.node .lock()
.await
.node
.write_bytes(&pkt_set_enable_display(enabled)) .write_bytes(&pkt_set_enable_display(enabled))
.map_err(|err| { .map_err(|err| {
warn!("ctrl_anime::run_animation:callback {}", err); warn!("ctrl_anime::run_animation:callback {}", err);
}) })
.ok(); .ok();
lock.config.display_enabled = enabled; self.0.lock().await.config.display_enabled = enabled;
lock.config.write(); self.0.lock().await.config.write();
} }
#[zbus(property)] #[zbus(property)]
async fn off_when_unplugged(&self) -> bool { async fn off_when_unplugged(&self) -> bool {
let lock = self.0.lock().await; self.0.lock().await.config.off_when_unplugged
lock.config.off_when_unplugged
} }
/// Set if to turn the AniMe Matrix off when external power is unplugged /// Set if to turn the AniMe Matrix off when external power is unplugged
#[zbus(property)] #[zbus(property)]
async fn set_off_when_unplugged(&self, enabled: bool) { async fn set_off_when_unplugged(&self, enabled: bool) {
let mut lock = self.0.lock().await;
let manager = get_logind_manager().await; let manager = get_logind_manager().await;
let pow = manager.on_external_power().await.unwrap_or_default(); let pow = manager.on_external_power().await.unwrap_or_default();
lock.node self.0
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display(!pow && !enabled)) .write_bytes(&pkt_set_enable_display(!pow && !enabled))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_lid_closed {}", err); warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
}) })
.ok(); .ok();
lock.config.off_when_unplugged = enabled; self.0.lock().await.config.off_when_unplugged = enabled;
lock.config.write(); self.0.lock().await.config.write();
} }
#[zbus(property)] #[zbus(property)]
async fn off_when_suspended(&self) -> bool { async fn off_when_suspended(&self) -> bool {
let lock = self.0.lock().await; self.0.lock().await.config.off_when_suspended
lock.config.off_when_suspended
} }
/// Set if to turn the AniMe Matrix off when the laptop is suspended /// Set if to turn the AniMe Matrix off when the laptop is suspended
#[zbus(property)] #[zbus(property)]
async fn set_off_when_suspended(&self, enabled: bool) { async fn set_off_when_suspended(&self, enabled: bool) {
let mut lock = self.0.lock().await; self.0.lock().await.config.off_when_suspended = enabled;
lock.config.off_when_suspended = enabled; self.0.lock().await.config.write();
lock.config.write();
} }
#[zbus(property)] #[zbus(property)]
async fn off_when_lid_closed(&self) -> bool { async fn off_when_lid_closed(&self) -> bool {
let lock = self.0.lock().await; self.0.lock().await.config.off_when_lid_closed
lock.config.off_when_lid_closed
} }
/// Set if to turn the AniMe Matrix off when the lid is closed /// Set if to turn the AniMe Matrix off when the lid is closed
#[zbus(property)] #[zbus(property)]
async fn set_off_when_lid_closed(&self, enabled: bool) { async fn set_off_when_lid_closed(&self, enabled: bool) {
let mut lock = self.0.lock().await;
let manager = get_logind_manager().await; let manager = get_logind_manager().await;
let lid = manager.lid_closed().await.unwrap_or_default(); let lid = manager.lid_closed().await.unwrap_or_default();
lock.node self.0
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display(lid && !enabled)) .write_bytes(&pkt_set_enable_display(lid && !enabled))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_lid_closed {}", err); warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
}) })
.ok(); .ok();
lock.config.off_when_lid_closed = enabled; self.0.lock().await.config.off_when_lid_closed = enabled;
lock.config.write(); self.0.lock().await.config.write();
} }
/// The main loop is the base system set action if the user isn't running /// The main loop is the base system set action if the user isn't running
/// the user daemon /// the user daemon
async fn run_main_loop(&self, start: bool) { async fn run_main_loop(&self, start: bool) {
if start { if start {
let lock = self.0.lock().await; self.0
lock.thread_exit.store(true, Ordering::SeqCst); .lock()
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false).await; .await
.thread_exit
.store(true, Ordering::SeqCst);
CtrlAnime::run_thread(
self.0.clone(),
self.0.lock().await.cache.system.clone(),
false,
)
.await;
} }
} }
/// Get the device state as stored by asusd /// Get the device state as stored by asusd
// #[zbus(property)] // #[zbus(property)]
async fn device_state(&self) -> DeviceState { async fn device_state(&self) -> DeviceState {
let lock = self.0.lock().await; DeviceState::from(&self.0.lock().await.config)
DeviceState::from(&lock.config)
} }
} }
@@ -272,36 +307,53 @@ impl crate::CtrlTask for CtrlAnimeZbus {
// on_sleep // on_sleep
let inner = inner1.clone(); let inner = inner1.clone();
async move { async move {
let lock = inner.lock().await; let config = inner.lock().await.config.clone();
if lock.config.display_enabled { if config.display_enabled {
lock.thread_exit.store(true, Ordering::Release); // ensure clean slate inner
.lock()
.await
.thread_exit
.store(true, Ordering::Release); // ensure clean slate
lock.node inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display( .write_bytes(&pkt_set_enable_display(
!(sleeping && lock.config.off_when_suspended), !(sleeping && config.off_when_suspended),
)) ))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_suspended {}", err); warn!("create_sys_event_tasks::off_when_suspended {}", err);
}) })
.ok(); .ok();
if lock.config.builtin_anims_enabled { if config.builtin_anims_enabled {
lock.node inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_powersave_anim( .write_bytes(&pkt_set_enable_powersave_anim(
!(sleeping && lock.config.off_when_suspended), !(sleeping && config.off_when_suspended),
)) ))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_suspended {}", err); warn!("create_sys_event_tasks::off_when_suspended {}", err);
}) })
.ok(); .ok();
} else if !sleeping && !lock.config.builtin_anims_enabled { } else if !sleeping && !config.builtin_anims_enabled {
// Run custom wake animation // Run custom wake animation
lock.node inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_powersave_anim(false)) .write_bytes(&pkt_set_enable_powersave_anim(false))
.ok(); // ensure builtins are disabled .ok(); // ensure builtins are disabled
CtrlAnime::run_thread(inner.clone(), lock.cache.wake.clone(), true) CtrlAnime::run_thread(
.await; inner.clone(),
inner.lock().await.cache.wake.clone(),
true,
)
.await;
} }
} }
} }
@@ -310,14 +362,26 @@ impl crate::CtrlTask for CtrlAnimeZbus {
// on_shutdown // on_shutdown
let inner = inner2.clone(); let inner = inner2.clone();
async move { async move {
let lock = inner.lock().await; let AnimeConfig {
if lock.config.display_enabled && !lock.config.builtin_anims_enabled { display_enabled,
builtin_anims_enabled,
..
} = inner.lock().await.config;
if display_enabled && !builtin_anims_enabled {
if shutting_down { if shutting_down {
CtrlAnime::run_thread(inner.clone(), lock.cache.shutdown.clone(), true) CtrlAnime::run_thread(
.await; inner.clone(),
inner.lock().await.cache.shutdown.clone(),
true,
)
.await;
} else { } else {
CtrlAnime::run_thread(inner.clone(), lock.cache.boot.clone(), true) CtrlAnime::run_thread(
.await; inner.clone(),
inner.lock().await.cache.boot.clone(),
true,
)
.await;
} }
} }
} }
@@ -326,17 +390,27 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner = inner3.clone(); let inner = inner3.clone();
// on lid change // on lid change
async move { async move {
let lock = inner.lock().await; let AnimeConfig {
if lock.config.off_when_lid_closed { off_when_lid_closed,
if lock.config.builtin_anims_enabled { builtin_anims_enabled,
lock.node ..
} = inner.lock().await.config;
if off_when_lid_closed {
if builtin_anims_enabled {
inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_powersave_anim(!lid_closed)) .write_bytes(&pkt_set_enable_powersave_anim(!lid_closed))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_suspended {}", err); warn!("create_sys_event_tasks::off_when_suspended {}", err);
}) })
.ok(); .ok();
} }
lock.node inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display(!lid_closed)) .write_bytes(&pkt_set_enable_display(!lid_closed))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_lid_closed {}", err); warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
@@ -349,25 +423,39 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner = inner4.clone(); let inner = inner4.clone();
// on power change // on power change
async move { async move {
let lock = inner.lock().await; let AnimeConfig {
if lock.config.off_when_unplugged { off_when_unplugged,
if lock.config.builtin_anims_enabled { builtin_anims_enabled,
lock.node brightness_on_battery,
..
} = inner.lock().await.config;
if off_when_unplugged {
if builtin_anims_enabled {
inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_powersave_anim(power_plugged)) .write_bytes(&pkt_set_enable_powersave_anim(power_plugged))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_suspended {}", err); warn!("create_sys_event_tasks::off_when_suspended {}", err);
}) })
.ok(); .ok();
} }
lock.node inner
.lock()
.await
.node
.write_bytes(&pkt_set_enable_display(power_plugged)) .write_bytes(&pkt_set_enable_display(power_plugged))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_unplugged {}", err); warn!("create_sys_event_tasks::off_when_unplugged {}", err);
}) })
.ok(); .ok();
} else { } else {
lock.node inner
.write_bytes(&pkt_set_brightness(lock.config.brightness_on_battery)) .lock()
.await
.node
.write_bytes(&pkt_set_brightness(brightness_on_battery))
.map_err(|err| { .map_err(|err| {
warn!("create_sys_event_tasks::off_when_unplugged {}", err); warn!("create_sys_event_tasks::off_when_unplugged {}", err);
}) })

View File

@@ -44,6 +44,11 @@ pub struct CtrlSlash {
impl CtrlSlash { impl CtrlSlash {
#[inline] #[inline]
pub fn new(config: SlashConfig) -> Result<CtrlSlash, RogError> { pub fn new(config: SlashConfig) -> Result<CtrlSlash, RogError> {
let slash_type = get_slash_type()?;
if matches!(slash_type, SlashType::Unknown | SlashType::Unsupported) {
return Err(RogError::Slash(SlashError::NoDevice));
}
let usb = USBRaw::new(rog_slash::usb::PROD_ID).ok(); let usb = USBRaw::new(rog_slash::usb::PROD_ID).ok();
let hid = HidRaw::new(rog_slash::usb::PROD_ID_STR).ok(); let hid = HidRaw::new(rog_slash::usb::PROD_ID_STR).ok();
let node = if usb.is_some() { let node = if usb.is_some() {
@@ -54,11 +59,6 @@ impl CtrlSlash {
return Err(RogError::NotSupported); return Err(RogError::NotSupported);
}; };
let slash_type = get_slash_type()?;
if slash_type == SlashType::Unknown {
return Err(RogError::Slash(SlashError::NoDevice));
}
let ctrl = CtrlSlash { let ctrl = CtrlSlash {
node, node,
config, config,

View File

@@ -199,16 +199,7 @@ pub trait CtrlTask {
/// ///
/// The closures can potentially block, so execution time should be the /// The closures can potentially block, so execution time should be the
/// minimal possible such as save a variable. /// minimal possible such as save a variable.
fn create_sys_event_tasks< fn create_sys_event_tasks<Fut1, Fut2, Fut3, Fut4, F1, F2, F3, F4>(
Fut1,
Fut2,
Fut3,
Fut4,
F1: Send + 'static,
F2: Send + 'static,
F3: Send + 'static,
F4: Send + 'static,
>(
&self, &self,
mut on_prepare_for_sleep: F1, mut on_prepare_for_sleep: F1,
mut on_prepare_for_shutdown: F2, mut on_prepare_for_shutdown: F2,
@@ -216,10 +207,10 @@ pub trait CtrlTask {
mut on_external_power_change: F4, mut on_external_power_change: F4,
) -> impl Future<Output = ()> + Send ) -> impl Future<Output = ()> + Send
where where
F1: FnMut(bool) -> Fut1, F1: FnMut(bool) -> Fut1 + Send + 'static,
F2: FnMut(bool) -> Fut2, F2: FnMut(bool) -> Fut2 + Send + 'static,
F3: FnMut(bool) -> Fut3, F3: FnMut(bool) -> Fut3 + Send + 'static,
F4: FnMut(bool) -> Fut4, F4: FnMut(bool) -> Fut4 + Send + 'static,
Fut1: Future<Output = ()> + Send, Fut1: Future<Output = ()> + Send,
Fut2: Future<Output = ()> + Send, Fut2: Future<Output = ()> + Send,
Fut3: Future<Output = ()> + Send, Fut3: Future<Output = ()> + Send,

View File

@@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-04-18 02:40+0000\n" "POT-Creation-Date: 2024-05-04 22:54+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -122,7 +122,6 @@ impl FanCurveProfiles {
Ok(FanCurvePU::which_fans(&device)) Ok(FanCurvePU::which_fans(&device))
} }
///
pub fn read_from_dev_profile( pub fn read_from_dev_profile(
&mut self, &mut self,
profile: ThrottlePolicy, profile: ThrottlePolicy,

View File

@@ -13,6 +13,7 @@ use crate::error::SlashError;
pub enum SlashType { pub enum SlashType {
GA403, GA403,
Unknown, Unknown,
Unsupported,
} }
impl FromStr for SlashType { impl FromStr for SlashType {

View File

@@ -35,8 +35,7 @@ pub fn get_slash_type() -> Result<SlashType, SlashError> {
if board_name.contains("GA403") { if board_name.contains("GA403") {
return Ok(SlashType::GA403); return Ok(SlashType::GA403);
} }
log::warn!("AniMe Slash device found but not yet supported, will default to a GA403 layout"); Ok(SlashType::Unsupported)
Ok(SlashType::Unknown)
} }
/// Get the two device initialization packets. These are required for device /// Get the two device initialization packets. These are required for device