From c1677e02df3ebbbd1edb0ee7d3d38e431c0953be Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Thu, 3 Oct 2024 22:59:39 +0200 Subject: [PATCH] zephyr: keep the endpoint queues free during suspend --- c2usb/port/zephyr/udc_mac.cpp | 17 ++++++++++++++++- c2usb/port/zephyr/udc_mac.hpp | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/c2usb/port/zephyr/udc_mac.cpp b/c2usb/port/zephyr/udc_mac.cpp index 9a22821..8a412b7 100644 --- a/c2usb/port/zephyr/udc_mac.cpp +++ b/c2usb/port/zephyr/udc_mac.cpp @@ -368,6 +368,7 @@ int udc_mac::process_event(const udc_event& event) process_ep_event(event.buf); break; case UDC_EVT_RESET: + cancel_all_transfers(); bus_reset(); break; case UDC_EVT_SUSPEND: @@ -375,6 +376,7 @@ int udc_mac::process_event(const udc_event& event) break; case UDC_EVT_RESUME: case UDC_EVT_VBUS_READY: + cancel_all_transfers(); set_power_state(power::state::L0_ON); break; case UDC_EVT_VBUS_REMOVED: @@ -583,6 +585,19 @@ usb::endpoint::address udc_mac::ep_handle_to_address(ep_handle eph) const return endpoint::address(udc_get_buf_info(ep_handle_to_buf(eph))->ep); } +void udc_mac::cancel_all_transfers() +{ + for (auto* buf : ep_bufs_) + { + endpoint::address addr{udc_get_buf_info(buf)->ep}; + if (busy_flags_.test(addr)) + { + [[maybe_unused]] auto ret = udc_ep_dequeue(dev_, addr); + busy_flags_.clear(addr); + } + } +} + usb::df::ep_handle udc_mac::ep_open(const usb::df::config::endpoint& ep) { auto ret = udc_ep_enable(dev_, ep.address(), ep.bmAttributes, ep.wMaxPacketSize, ep.bInterval); @@ -611,7 +626,7 @@ usb::result udc_mac::ep_transfer(usb::df::ep_handle eph, const transfer& t, usb: return result::BUSY; } #endif - if (busy_flags_.test_and_set(addr)) + if ((power_state() != power::state::L0_ON) or busy_flags_.test_and_set(addr)) { return result::BUSY; } diff --git a/c2usb/port/zephyr/udc_mac.hpp b/c2usb/port/zephyr/udc_mac.hpp index 3146ac9..06e8384 100644 --- a/c2usb/port/zephyr/udc_mac.hpp +++ b/c2usb/port/zephyr/udc_mac.hpp @@ -84,6 +84,7 @@ class udc_mac : public df::mac usb::result ep_clear_stall(endpoint::address addr); usb::result ep_transfer(usb::df::ep_handle eph, const usb::df::transfer& t, usb::direction dir); + void cancel_all_transfers(); usb::df::ep_handle ep_open(const usb::df::config::endpoint& ep) override; usb::result ep_send(usb::df::ep_handle eph, const std::span& data) override; usb::result ep_receive(usb::df::ep_handle eph, const std::span& data) override;