summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWojciech Klimek <[email protected]>2026-05-28 21:27:11 +0200
committerWojciech Klimek <[email protected]>2026-05-29 11:39:07 +0200
commit84e3347badc7f9f5146b5f5eb129900f2fc59389 (patch)
treef81327ad869a08720f7edf1e0de97b029fa40171 /src
parent09f8208f5be1be4be5e2c0278960b202b7dc759d (diff)
Handle OUT transfer completion in MTP
Handle OUT transfer differently from IN to not prematurely change MTP phase when host sends short packet that is not end of MTP data phase. Only reaching container length or ZLP should change phase.
Diffstat (limited to 'src')
-rw-r--r--src/class/mtp/mtp_device.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c
index 0da984f4a..fd06b4601 100644
--- a/src/class/mtp/mtp_device.c
+++ b/src/class/mtp/mtp_device.c
@@ -441,9 +441,19 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
threshold = CFG_TUD_MTP_EP_BUFSIZE;
}
- // Check completion: ZLP, short packet, or total length reached
- const bool is_complete =
- (xferred_bytes == 0 || xferred_bytes < threshold || p_mtp->xferred_len >= p_mtp->total_len);
+ // Check completion for IN and OUT separately
+ bool is_complete;
+
+ if (is_data_in)
+ {
+ // IN completion: short packet, ZLP, or reaching total_len
+ is_complete = (xferred_bytes == 0 || xferred_bytes < threshold || p_mtp->xferred_len >= p_mtp->total_len);
+ }
+ else
+ {
+ // OUT completion: reaching total_len or ZLP
+ is_complete = (p_mtp->xferred_len >= p_mtp->total_len) || ((xferred_bytes == 0 && p_mtp->xferred_len > 0));
+ }
TU_LOG_DRV(" MTP Data %s CB: xferred_bytes=%lu, xferred_len/total_len=%lu/%lu, is_complete=%d\r\n",
is_data_in ? "IN" : "OUT", xferred_bytes, p_mtp->xferred_len, p_mtp->total_len, is_complete ? 1 : 0);