usb: dont create background task for msc_host_install
What changed, and why it matters
This commit changes how Blockstream Jade handles USB mass-storage events. Previously, a separate background task was created to process USB events, which caused a visible "Processing..." freeze on the device. The fix moves event handling into the existing task and makes it run in smaller, more frequent chunks. There is no direct evidence in the commit that this fixes a security vulnerability; it appears to be a user-experience and stability improvement.
Treat as a routine stability/user-experience fix. If reviewing for security, verify that moving msc_host_handle_events into the same task does not introduce race conditions or missed events during device removal, and that the shorter timeout does not affect secure erase/lock operations that may depend on USB storage completion. No immediate security action is warranted based solely on this diff.
Security signals we found
No security-related keywords in commit title or message
No CVE, advisory, or researcher attribution in commit
Change is architectural/refactoring of USB event-loop concurrency
Potential stability improvement from avoiding background-task synchronization issues
No explicit bounds checks, input validation, or memory-safety changes visible
Evidence from the diff
The patch modifies main/usbhmsc/usbhmsc.c to disable the dedicated background task for msc_host_install (create_backround_task = false). It introduces a helper usb_host_lib_events() and updates handle_usb_events() to call both usb_host_lib_events() and msc_host_handle_events() in shorter 50-tick loops, checking the subtask enable flag between them. It also adds a final 1-tick event drain before asserting the subtask is disabled. The change is framed by the commit message as eliminating a UI freeze, not as a security fix.
Changed components
Blockstream Jade firmware USB mass-storage host drivermain/usbhmsc/usbhmsc.cUSB host library event loop integrationInspect captured patch +32 / −18
diff --git a/main/usbhmsc/usbhmsc.c b/main/usbhmsc/usbhmsc.c
index 18d21bb..c7e67ac 100644
--- a/main/usbhmsc/usbhmsc.c
+++ b/main/usbhmsc/usbhmsc.c
@@ -88,29 +88,46 @@ static void msc_event_cb(const msc_host_event_t* event, void* arg)
}
}
+static void usb_host_lib_events(const uint32_t timeout)
+{
+ uint32_t event_flags;
+ const esp_err_t err = usb_host_lib_handle_events(timeout, &event_flags);
+
+ if (err == ESP_ERR_TIMEOUT) {
+ return;
+ }
+
+ JADE_ERROR_CHECK(err);
+
+ if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
+ xEventGroupSetBits(usb_flags, HOST_NO_CLIENT);
+ }
+ if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
+ xEventGroupSetBits(usb_flags, HOST_ALL_FREE);
+ }
+}
+
static void handle_usb_events(void* args)
{
while (true) {
- uint32_t event_flags;
- const esp_err_t err = usb_host_lib_handle_events(100 / portTICK_PERIOD_MS, &event_flags);
+ usb_host_lib_events(50 / portTICK_PERIOD_MS);
+
if (!usbstorage_is_enabled_subtask) {
break;
}
- if (err == ESP_ERR_TIMEOUT) {
- continue;
- }
- JADE_ERROR_CHECK(err);
+ msc_host_handle_events(50 / portTICK_PERIOD_MS);
- if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
- usb_host_device_free_all();
- xEventGroupSetBits(usb_flags, HOST_NO_CLIENT);
- }
- if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
- xEventGroupSetBits(usb_flags, HOST_ALL_FREE);
+ if (!usbstorage_is_enabled_subtask) {
+ break;
}
}
+ // msc_host_uninstall will cause the USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS event
+ // so lets clear any last events
+ uint32_t event_flags;
+ usb_host_lib_handle_events(1, &event_flags);
+
JADE_ASSERT(!usbstorage_is_enabled);
xSemaphoreGive(aux_task_semaphore);
@@ -145,10 +162,7 @@ static void usbstorage_task(void* ignore)
JADE_ASSERT(aux_task);
const msc_host_driver_config_t msc_config = {
- .create_backround_task = true,
- .task_priority = 5,
- .core_id = JADE_CORE_SECONDARY,
- .stack_size = 2048 * 2,
+ .create_backround_task = false,
.callback = msc_event_cb,
};
@@ -200,7 +214,7 @@ static void usbstorage_task(void* ignore)
done = !usbstorage_is_enabled;
break;
} else if (!ebt && requires_host_uninstall && !usb_device_installed) {
- USB_LOGI(500, "msc_host_uninstall..");
+ USB_LOGI(500, "msc_host_uninstall.. (1)");
esp_err_t err = msc_host_uninstall();
if (err == ESP_OK) {
requires_host_uninstall = false;
@@ -215,7 +229,7 @@ static void usbstorage_task(void* ignore)
// This may fail if the user removes the device at the right time
if (requires_host_uninstall) {
- USB_LOGI(500, "msc_host_uninstall..");
+ USB_LOGI(500, "msc_host_uninstall.. (2)");
const esp_err_t err = msc_host_uninstall();
if (err != ESP_OK) {
USB_LOGE(5000, "msc_host_uninstall failed %d", err);
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.