Skip to content

Commit 29a3700

Browse files
committed
usb: implement transfer cancellation
Signed-off-by: Benedek Kupper <kupper.benedek@gmail.com>
1 parent 6a87d4c commit 29a3700

14 files changed

Lines changed: 103 additions & 88 deletions

File tree

c2usb/port/nxp/mcux_mac.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ usb::result mcux_mac::ep_cancel(ep_handle eph)
231231
{
232232
auto addr = ep_handle_to_address(eph);
233233
auto status = driver_.deviceCancel(handle(), addr);
234-
busy_flags_.clear(addr);
235234
return (status == kStatus_USB_Success) ? usb::result::ok : usb::result::not_connected;
236235
}
237236

@@ -269,10 +268,6 @@ void mcux_mac::process_ep_notification(const _usb_device_callback_message_struct
269268
{
270269
// wrong mapping
271270
}
272-
else if (message.length == UINT32_MAX)
273-
{
274-
// callback due to ep_cancel()
275-
}
276271
else if (addr.number() == 0)
277272
{
278273
transfer t{};
@@ -328,11 +323,13 @@ void mcux_mac::process_ep_notification(const _usb_device_callback_message_struct
328323
(t.size() == 0)); // work around bug in NXP code
329324
}
330325
}
331-
else
326+
else // other endpoints
332327
{
333328
busy_flags_.clear(addr);
334-
ep_transfer_complete(addr, create_ep_handle(addr),
335-
transfer(message.buffer, message.length));
329+
330+
bool success = (message.length != USB_CANCELLED_TRANSFER_LENGTH);
331+
ep_transfer_complete(addr, transfer(message.buffer, message.length * success, success,
332+
ep_address_to_handle(addr)));
336333
}
337334
}
338335

c2usb/port/nxp/mcux_mac.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class mcux_mac : public df::address_handle_mac
9292
usb::result ep_send(usb::df::ep_handle eph, const std::span<const uint8_t>& data) override;
9393
usb::result ep_receive(usb::df::ep_handle eph, const std::span<uint8_t>& data) override;
9494
usb::result ep_close(usb::df::ep_handle eph) override;
95-
usb::result ep_cancel(usb::df::ep_handle eph);
95+
usb::result ep_cancel(usb::df::ep_handle eph) override;
9696

9797
bool ep_is_stalled(usb::df::ep_handle eph) const override;
9898
usb::result ep_change_stall(usb::df::ep_handle eph, bool stall) override;

c2usb/port/zephyr/udc_mac.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -739,22 +739,19 @@ void udc_mac::process_ep_event(net_buf* buf)
739739
{
740740
busy_flags_.clear(addr);
741741

742-
if (info.err == 0)
742+
if (info.err != 0)
743743
{
744-
for (uint8_t i = 0; i < ep_bufs_.size(); ++i)
745-
{
746-
if (ep_bufs_[i] == buf)
747-
{
748-
return ep_transfer_complete(addr, create_ep_handle(i + 1),
749-
transfer(buf->data, buf->len));
750-
}
751-
}
752-
assert(ep_bufs_.size() == 0); // a net_buf was issued out of c2usb scope
744+
LOG_ERR("EP %x error:%d", info.ep, info.err);
753745
}
754-
else
746+
for (uint8_t i = 0; i < ep_bufs_.size(); ++i)
755747
{
756-
LOG_ERR("EP %x error:%d", info.ep, info.err);
748+
if (ep_bufs_[i] == buf)
749+
{
750+
return ep_transfer_complete(
751+
addr, transfer(buf->data, buf->len, info.err == 0, create_ep_handle(i + 1)));
752+
}
757753
}
754+
assert(ep_bufs_.size() == 0); // a net_buf was issued out of c2usb scope
758755
}
759756
}
760757

@@ -913,7 +910,7 @@ usb::result udc_mac::ep_close(usb::df::ep_handle eph)
913910
return usb::result(ret);
914911
}
915912
k_yield();
916-
return usb::result::OK;
913+
return usb::result::ok;
917914
}
918915

919916
usb::result udc_mac::ep_cancel(usb::df::ep_handle eph)

c2usb/port/zephyr/udc_mac.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class udc_mac : public df::mac
8282
usb::result ep_send(usb::df::ep_handle eph, const std::span<const uint8_t>& data) override;
8383
usb::result ep_receive(usb::df::ep_handle eph, const std::span<uint8_t>& data) override;
8484
usb::result ep_close(usb::df::ep_handle eph) override;
85-
usb::result ep_cancel(usb::df::ep_handle eph);
85+
usb::result ep_cancel(usb::df::ep_handle eph) override;
8686
bool ep_is_stalled(usb::df::ep_handle eph) const override;
8787
usb::result ep_change_stall(usb::df::ep_handle eph, bool stall) override;
8888
};

c2usb/usb/df/class/cdc_acm.cpp

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -130,36 +130,16 @@ void function::disable(const config::interface& iface)
130130
cdc::function::disable(iface);
131131
}
132132

133-
void function::transfer_complete(ep_handle eph, const transfer& t)
133+
void function::ep_callback(const transfer& t)
134134
{
135-
if (eph == ep_out_handle())
135+
if (t.endpoint() == ep_out_handle())
136136
{
137-
return data_received(t);
137+
return data_received(std::span<uint8_t>(t.data(), t.size() * t.success()));
138138
}
139-
if (eph == ep_in_handle())
139+
if (t.endpoint() == ep_in_handle())
140140
{
141-
#if 0
142-
auto len = t.size();
143-
if (len == 0)
144-
{
145-
if (tx_len_ > 0)
146-
{
147-
// if ZLP is finished, substitute original length
148-
len = tx_len_;
149-
tx_len_ = 0;
150-
}
151-
}
152-
else if ((len % in_ep_mps_) == 0)
153-
{
154-
// if length mod MPS == 0, split the transfer by sending ZLP
155-
tx_len_ = len;
156-
send_ep(eph, {});
157-
return;
158-
}
159-
return data_sent({const_cast<const uint8_t*>(t.data()), len});
160-
#endif
161141
bool needs_zlp = t.size() and (t.size() % in_ep_mps_) == 0;
162-
return data_sent(t, needs_zlp);
142+
return data_sent(std::span<const uint8_t>(t.data(), t.size() * t.success()), needs_zlp);
163143
}
164144
// notification sent
165145
}

c2usb/usb/df/class/cdc_acm.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class function : public cdc::function
7676
void control_data_complete(message& msg, const config::interface& iface) override;
7777
void enable(const config::interface& iface, uint8_t alt_sel) override;
7878
void disable(const config::interface& iface) override;
79-
void transfer_complete(ep_handle eph, const transfer& t) override;
79+
void ep_callback(const transfer& t) override;
8080

8181
auto& line_coding() const
8282
{

c2usb/usb/df/class/hid.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,16 @@ usb::result app_base_function::receive_report(const std::span<uint8_t>& data, re
8484
}
8585
}
8686

87-
void app_base_function::transfer_complete(ep_handle eph, const transfer& t)
87+
void app_base_function::ep_callback(const transfer& t)
8888
{
89-
if (eph == ep_in_handle())
89+
if (t.endpoint() == ep_in_handle())
9090
{
91-
app_.in_report_sent(t);
91+
return app_.in_report_sent(std::span<const uint8_t>(t.data(), t.size() * t.success()));
9292
}
93-
else
93+
if (t.endpoint() == ep_out_handle())
9494
{
95-
app_.set_report(report::type::OUTPUT, t);
95+
return app_.set_report(report::type::OUTPUT,
96+
std::span<const uint8_t>(t.data(), t.size() * t.success()));
9697
}
9798
}
9899

@@ -242,7 +243,7 @@ void function::control_data_complete(message& msg, [[maybe_unused]] const config
242243
{
243244
auto type = static_cast<report::type>(msg.request().wValue.high_byte());
244245
rx_buffers_[type] = {};
245-
app_.set_report(type, msg.data());
246+
app_.set_report(type, msg.data().to_span());
246247
break;
247248
}
248249
default:

c2usb/usb/df/class/hid.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class app_base_function : public df::named_function, public ::hid::transport
3838
result receive_report(const std::span<uint8_t>& data, ::hid::report::type type) override;
3939
::hid::transport::type transport_type() const override { return ::hid::transport::type::USB; }
4040

41-
void transfer_complete(ep_handle eph, const transfer& t) override;
41+
void ep_callback(const transfer& t) override;
4242

4343
::hid::application& app_;
4444
::hid::reports_receiver rx_buffers_{};

c2usb/usb/df/function.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,18 @@ usb::result function::stall_ep(ep_handle eph, bool stall)
211211
}
212212
}
213213

214+
usb::result function::cancel_ep(ep_handle eph)
215+
{
216+
if ((mac_ != nullptr) and eph.valid())
217+
{
218+
return mac_->ep_cancel(eph);
219+
}
220+
else
221+
{
222+
return usb::result::connection_reset;
223+
}
224+
}
225+
214226
message* function::pending_message()
215227
{
216228
if (mac_ != nullptr)

c2usb/usb/df/function.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ class function : public polymorphic
5151

5252
virtual std::string_view ms_compatible_id() const { return {}; }
5353

54-
virtual void transfer_complete([[maybe_unused]] ep_handle eph,
55-
[[maybe_unused]] const transfer& t)
56-
{}
54+
virtual void ep_callback([[maybe_unused]] const transfer& t) {}
5755

5856
protected:
5957
ep_handle open_ep(const config::endpoint& ep);
@@ -80,6 +78,7 @@ class function : public polymorphic
8078
result send_ep(ep_handle eph, const std::span<const uint8_t>& data);
8179
result receive_ep(ep_handle eph, const std::span<uint8_t>& data);
8280
result stall_ep(ep_handle eph, bool stall);
81+
result cancel_ep(ep_handle eph);
8382

8483
message* pending_message();
8584

0 commit comments

Comments
 (0)