usb: Rework timeouts

- Rework all timeouts to be more relaxed when doing big data transfers.
- Fix a bug where async transfer would timeout sooner instead of infinite tries.

Both showed up in Arch Linux, because of it's huge latency USB stack latency that can reach 1-2s.

The rework will let every OS work without adding additional wait time in the gadget loops.
This commit is contained in:
CTCaer 2020-12-30 13:37:36 +02:00
parent 2c695e9a96
commit 4949331f4c
5 changed files with 50 additions and 46 deletions

View file

@ -309,7 +309,7 @@ static bool _fts_touch_read(touchpad_report_t *rpt)
static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len) static u8 _hid_transfer_start(usb_ctxt_t *usbs, u32 len)
{ {
u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED); u8 status = usb_ops.usb_device_ep1_in_write((u8 *)USB_EP_BULK_IN_BUF_ADDR, len, NULL, USB_XFER_SYNCED_CMD);
if (status == USB_ERROR_XFER_ERROR) if (status == USB_ERROR_XFER_ERROR)
{ {
usbs->set_text(usbs->label, "#FFDD00 Error:# EP IN transfer!"); usbs->set_text(usbs->label, "#FFDD00 Error:# EP IN transfer!");

View file

@ -315,13 +315,13 @@ static void ums_flush_endpoint(u32 ep)
usb_ops.usbd_flush_endpoint(ep); usb_ops.usbd_flush_endpoint(ep);
} }
static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, bool sync) static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt, u32 ep, u32 sync_timeout)
{ {
if (ep == bulk_ctxt->bulk_in) if (ep == bulk_ctxt->bulk_in)
{ {
bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_write( bulk_ctxt->bulk_in_status = usb_ops.usb_device_ep1_in_write(
bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length, bulk_ctxt->bulk_in_buf, bulk_ctxt->bulk_in_length,
&bulk_ctxt->bulk_in_length_actual, sync); &bulk_ctxt->bulk_in_length_actual, sync_timeout);
if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR) if (bulk_ctxt->bulk_in_status == USB_ERROR_XFER_ERROR)
{ {
@ -331,14 +331,14 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED) else if (bulk_ctxt->bulk_in_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP IN Buffer not aligned!"); ums->set_text(ums->label, "#FFDD00 Error:# EP IN Buffer not aligned!");
if (sync) if (sync_timeout)
bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY; bulk_ctxt->bulk_in_buf_state = BUF_STATE_EMPTY;
} }
else else
{ {
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read( bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_read(
bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length, bulk_ctxt->bulk_out_buf, bulk_ctxt->bulk_out_length,
&bulk_ctxt->bulk_out_length_actual, sync); &bulk_ctxt->bulk_out_length_actual, sync_timeout);
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{ {
@ -348,7 +348,7 @@ static void _ums_transfer_start(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED) else if (bulk_ctxt->bulk_out_status == USB2_ERROR_XFER_NOT_ALIGNED)
ums->set_text(ums->label, "#FFDD00 Error:# EP OUT Buffer not aligned!"); ums->set_text(ums->label, "#FFDD00 Error:# EP OUT Buffer not aligned!");
if (sync) if (sync_timeout)
bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL; bulk_ctxt->bulk_out_buf_state = BUF_STATE_FULL;
} }
} }
@ -386,7 +386,7 @@ static void _ums_transfer_finish(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt,
else else
{ {
bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish( bulk_ctxt->bulk_out_status = usb_ops.usb_device_ep1_out_reading_finish(
&bulk_ctxt->bulk_out_length_actual, 1000000); &bulk_ctxt->bulk_out_length_actual);
if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR) if (bulk_ctxt->bulk_out_status == USB_ERROR_XFER_ERROR)
{ {
@ -1407,7 +1407,7 @@ static int pad_with_zeros(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
u32 nsend = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE); u32 nsend = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE);
memset(bulk_ctxt->bulk_in_buf + current_len_to_keep, 0, nsend - current_len_to_keep); memset(bulk_ctxt->bulk_in_buf + current_len_to_keep, 0, nsend - current_len_to_keep);
bulk_ctxt->bulk_in_length = nsend; bulk_ctxt->bulk_in_length = nsend;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA);
ums->usb_amount_left -= nsend; ums->usb_amount_left -= nsend;
current_len_to_keep = 0; current_len_to_keep = 0;
} }
@ -1425,7 +1425,7 @@ static int throw_away_data(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
u32 amount = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE); u32 amount = MIN(ums->usb_amount_left, USB_EP_BUFFER_MAX_SIZE);
bulk_ctxt->bulk_out_length = amount; bulk_ctxt->bulk_out_length = amount;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_DATA);
ums->usb_amount_left -= amount; ums->usb_amount_left -= amount;
return UMS_RES_OK; return UMS_RES_OK;
@ -1472,7 +1472,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
// If there's no residue, simply send the last buffer. // If there's no residue, simply send the last buffer.
if (!ums->residue) if (!ums->residue)
{ {
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA);
/* For Bulk-only, if we're allowed to stall then send the /* For Bulk-only, if we're allowed to stall then send the
* short packet and halt the bulk-in endpoint. If we can't * short packet and halt the bulk-in endpoint. If we can't
@ -1480,7 +1480,7 @@ static int finish_reply(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
} }
else if (ums->can_stall) else if (ums->can_stall)
{ {
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_DATA);
rc = ums_set_stall(bulk_ctxt->bulk_in); rc = ums_set_stall(bulk_ctxt->bulk_in);
ums->set_text(ums->label, "#FFDD00 Error:# Residue. Stalled EP IN!"); ums->set_text(ums->label, "#FFDD00 Error:# Residue. Stalled EP IN!");
} }
@ -1661,7 +1661,7 @@ static int get_next_command(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN; bulk_ctxt->bulk_out_length = USB_BULK_CB_WRAP_LEN;
/* Queue a request to read a Bulk-only CBW */ /* Queue a request to read a Bulk-only CBW */
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_out, USB_XFER_SYNCED_CMD);
/* We will drain the buffer in software, which means we /* We will drain the buffer in software, which means we
* can reuse it for the next filling. No need to advance * can reuse it for the next filling. No need to advance
@ -1707,7 +1707,7 @@ static void send_status(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)
csw->Status = status; csw->Status = status;
bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN; bulk_ctxt->bulk_in_length = USB_BULK_CS_WRAP_LEN;
_ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED); _ums_transfer_start(ums, bulk_ctxt, bulk_ctxt->bulk_in, USB_XFER_SYNCED_CMD);
} }
static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt) static void handle_exception(usbd_gadget_ums_t *ums, bulk_ctxt_t *bulk_ctxt)

View file

@ -724,7 +724,7 @@ static usb_ep_status_t _usbd_get_ep_status(usb_ep_t endpoint)
return USB_EP_STATUS_IDLE; return USB_EP_STATUS_IDLE;
} }
static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, bool sync) static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_timeout)
{ {
if (!buf) if (!buf)
len = 0; len = 0;
@ -797,12 +797,12 @@ static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, bool sync)
int res = USB_RES_OK; int res = USB_RES_OK;
usb_ep_status_t ep_status; usb_ep_status_t ep_status;
if (sync) if (sync_timeout)
{ {
ep_status = _usbd_get_ep_status(endpoint); ep_status = _usbd_get_ep_status(endpoint);
if (ep_status == USB_EP_STATUS_ACTIVE) if (ep_status == USB_EP_STATUS_ACTIVE)
{ {
u32 retries = 1000000; // Timeout 2s. u32 retries = sync_timeout;
while (retries) while (retries)
{ {
ep_status = _usbd_get_ep_status(endpoint); ep_status = _usbd_get_ep_status(endpoint);
@ -834,7 +834,7 @@ out:
static int _usbd_ep_ack(usb_ep_t ep) static int _usbd_ep_ack(usb_ep_t ep)
{ {
return _usbd_ep_operation(ep, NULL, 0, true); return _usbd_ep_operation(ep, NULL, 0, USB_XFER_SYNCED_ENUM);
} }
static void _usbd_set_ep0_stall() static void _usbd_set_ep0_stall()
@ -1275,7 +1275,7 @@ static int _usbd_handle_ep0_control_transfer()
if (_wLength < size) if (_wLength < size)
size = _wLength; size = _wLength;
res = _usbd_ep_operation(USB_EP_CTRL_IN, usb_ep0_ctrl_buf, size, true); res = _usbd_ep_operation(USB_EP_CTRL_IN, usb_ep0_ctrl_buf, size, USB_XFER_SYNCED_ENUM);
if (!res) if (!res)
res = _usbd_ep_ack(USB_EP_CTRL_OUT); res = _usbd_ep_ack(USB_EP_CTRL_OUT);
} }
@ -1402,7 +1402,7 @@ static usb_ep_status_t _usbd_get_ep1_status(usb_dir_t dir)
return _usbd_get_ep_status(ep); return _usbd_get_ep_status(ep);
} }
int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, bool sync) int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_timeout)
{ {
if ((u32)buf % USB_EP_BUFFER_ALIGN) if ((u32)buf % USB_EP_BUFFER_ALIGN)
return USB2_ERROR_XFER_NOT_ALIGNED; return USB2_ERROR_XFER_NOT_ALIGNED;
@ -1410,9 +1410,9 @@ int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, bool sync)
if (len > USB_EP_BUFFER_MAX_SIZE) if (len > USB_EP_BUFFER_MAX_SIZE)
len = USB_EP_BUFFER_MAX_SIZE; len = USB_EP_BUFFER_MAX_SIZE;
int res = _usbd_ep_operation(USB_EP_BULK_OUT, buf, len, sync); int res = _usbd_ep_operation(USB_EP_BULK_OUT, buf, len, sync_timeout);
if (sync && bytes_read) if (sync_timeout && bytes_read)
*bytes_read = res ? 0 : len; *bytes_read = res ? 0 : len;
return res; return res;
@ -1435,7 +1435,7 @@ int usb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
{ {
u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE); u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE);
res = usb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED); res = usb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA);
if (res) if (res)
return res; return res;
@ -1455,7 +1455,7 @@ static int _usbd_get_ep1_out_bytes_read()
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16)); return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16));
} }
int usb_device_ep1_out_reading_finish(u32 *pending_bytes, int tries) int usb_device_ep1_out_reading_finish(u32 *pending_bytes)
{ {
usb_ep_status_t ep_status; usb_ep_status_t ep_status;
do do
@ -1480,7 +1480,7 @@ int usb_device_ep1_out_reading_finish(u32 *pending_bytes, int tries)
return USB_ERROR_XFER_ERROR; return USB_ERROR_XFER_ERROR;
} }
int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, bool sync) int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_timeout)
{ {
if ((u32)buf % USB_EP_BUFFER_ALIGN) if ((u32)buf % USB_EP_BUFFER_ALIGN)
return USB2_ERROR_XFER_NOT_ALIGNED; return USB2_ERROR_XFER_NOT_ALIGNED;
@ -1488,9 +1488,9 @@ int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, bool sync)
if (len > USB_EP_BUFFER_MAX_SIZE) if (len > USB_EP_BUFFER_MAX_SIZE)
len = USB_EP_BUFFER_MAX_SIZE; len = USB_EP_BUFFER_MAX_SIZE;
int res = _usbd_ep_operation(USB_EP_BULK_IN, buf, len, sync); int res = _usbd_ep_operation(USB_EP_BULK_IN, buf, len, sync_timeout);
if (sync && bytes_written) if (sync_timeout && bytes_written)
*bytes_written = res ? 0 : len; *bytes_written = res ? 0 : len;
return res; return res;

View file

@ -30,8 +30,12 @@
#define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD) #define USB_EP_BUFFER_MAX_SIZE (USB_EP_BUFFER_4_TD)
#define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE) #define USB_EP_BUFFER_ALIGN (USB_TD_BUFFER_PAGE_SIZE)
#define USB_XFER_START false #define USB_XFER_START 0
#define USB_XFER_SYNCED true #define USB_XFER_SYNCED_ENUM 1000000
#define USB_XFER_SYNCED_CMD 1000000
#define USB_XFER_SYNCED_DATA 2000000
#define USB_XFER_SYNCED_CLASS 5000000
#define USB_XFER_SYNCED -1
typedef enum _usb_hid_type typedef enum _usb_hid_type
{ {
@ -169,10 +173,10 @@ typedef struct _usb_ops_t
int (*usb_device_class_send_max_lun)(u8); int (*usb_device_class_send_max_lun)(u8);
int (*usb_device_class_send_hid_report)(); int (*usb_device_class_send_hid_report)();
int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, bool); int (*usb_device_ep1_out_read)(u8 *, u32, u32 *, u32);
int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *); int (*usb_device_ep1_out_read_big)(u8 *, u32, u32 *);
int (*usb_device_ep1_out_reading_finish)(u32 *, int); int (*usb_device_ep1_out_reading_finish)(u32 *);
int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, bool); int (*usb_device_ep1_in_write)(u8 *, u32, u32 *, u32);
int (*usb_device_ep1_in_writing_finish)(u32 *); int (*usb_device_ep1_in_writing_finish)(u32 *);
bool (*usb_device_get_suspended)(); bool (*usb_device_get_suspended)();
bool (*usb_device_get_port_in_sleep)(); bool (*usb_device_get_port_in_sleep)();

View file

@ -881,7 +881,7 @@ int xusb_device_init()
_xusbd_init_device_clocks(); _xusbd_init_device_clocks();
// Enable AHB redirect for access to IRAM for Event/EP ring buffers. // Enable AHB redirect for access to IRAM for Event/EP ring buffers.
mc_enable_ahb_redirect(); // can be skipped if IRAM is not used///////////////// mc_enable_ahb_redirect(); // Can be skipped if IRAM is not used.
// Enable XUSB device IPFS. // Enable XUSB device IPFS.
XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI; XUSB_DEV_DEV(XUSB_DEV_CONFIGURATION) |= DEV_CONFIGURATION_EN_FPCI;
@ -1803,7 +1803,7 @@ int xusb_device_enumerate(usb_gadget_type gadget)
u32 timer = get_tmr_ms() + 90000; u32 timer = get_tmr_ms() + 90000;
while (true) while (true)
{ {
int res = _xusb_ep_operation(1000000); // 2s timeout. int res = _xusb_ep_operation(USB_XFER_SYNCED_ENUM); // 2s timeout.
if (res && res != USB_ERROR_TIMEOUT) if (res && res != USB_ERROR_TIMEOUT)
return res; return res;
@ -1826,7 +1826,7 @@ void xusb_end(bool reset_ep, bool only_controller)
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL); CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB); CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = BIT(CLK_W_XUSB);
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB); CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB);
mc_disable_ahb_redirect();/////////////////// mc_disable_ahb_redirect(); // Can be skipped if IRAM is not used.
} }
int xusb_handle_ep0_ctrl_setup() int xusb_handle_ep0_ctrl_setup()
@ -1844,7 +1844,7 @@ int xusb_handle_ep0_ctrl_setup()
return USB_RES_OK; return USB_RES_OK;
} }
int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, bool sync) int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_tries)
{ {
if (len > USB_EP_BUFFER_MAX_SIZE) if (len > USB_EP_BUFFER_MAX_SIZE)
len = USB_EP_BUFFER_MAX_SIZE; len = USB_EP_BUFFER_MAX_SIZE;
@ -1855,10 +1855,10 @@ int xusb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, bool sync)
_xusb_issue_normal_trb(buf, len, USB_DIR_OUT); _xusb_issue_normal_trb(buf, len, USB_DIR_OUT);
usbd_xotg->tx_count[USB_DIR_OUT]++; usbd_xotg->tx_count[USB_DIR_OUT]++;
if (sync) if (sync_tries)
{ {
while (!res && usbd_xotg->tx_count[USB_DIR_OUT]) while (!res && usbd_xotg->tx_count[USB_DIR_OUT])
res = _xusb_ep_operation(1000000); // 2s timeout. res = _xusb_ep_operation(sync_tries);
if (bytes_read) if (bytes_read)
*bytes_read = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; *bytes_read = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT];
@ -1882,7 +1882,7 @@ int xusb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
{ {
u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE); u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE);
int res = xusb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED); int res = xusb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA);
if (res) if (res)
return res; return res;
@ -1894,11 +1894,11 @@ int xusb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
return USB_RES_OK; return USB_RES_OK;
} }
int xusb_device_ep1_out_reading_finish(u32 *pending_bytes, int tries) int xusb_device_ep1_out_reading_finish(u32 *pending_bytes)
{ {
int res = USB_RES_OK; int res = USB_RES_OK;
while (!res && usbd_xotg->tx_count[USB_DIR_OUT]) while (!res && usbd_xotg->tx_count[USB_DIR_OUT])
res = _xusb_ep_operation(tries); res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries.
if (pending_bytes) if (pending_bytes)
*pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT]; *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_OUT];
@ -1908,7 +1908,7 @@ int xusb_device_ep1_out_reading_finish(u32 *pending_bytes, int tries)
return res; return res;
} }
int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, bool sync) int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_tries)
{ {
if (len > USB_EP_BUFFER_MAX_SIZE) if (len > USB_EP_BUFFER_MAX_SIZE)
len = USB_EP_BUFFER_MAX_SIZE; len = USB_EP_BUFFER_MAX_SIZE;
@ -1921,10 +1921,10 @@ int xusb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, bool sync)
_xusb_issue_normal_trb(buf, len, USB_DIR_IN); _xusb_issue_normal_trb(buf, len, USB_DIR_IN);
usbd_xotg->tx_count[USB_DIR_IN]++; usbd_xotg->tx_count[USB_DIR_IN]++;
if (sync) if (sync_tries)
{ {
while (!res && usbd_xotg->tx_count[USB_DIR_IN]) while (!res && usbd_xotg->tx_count[USB_DIR_IN])
res = _xusb_ep_operation(1000000); // 2s timeout. res = _xusb_ep_operation(sync_tries);
if (bytes_written) if (bytes_written)
*bytes_written = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; *bytes_written = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN];
@ -1947,7 +1947,7 @@ int xusb_device_ep1_in_writing_finish(u32 *pending_bytes)
{ {
int res = USB_RES_OK; int res = USB_RES_OK;
while (!res && usbd_xotg->tx_count[USB_DIR_IN]) while (!res && usbd_xotg->tx_count[USB_DIR_IN])
res = _xusb_ep_operation(1000000); // 2s timeout. res = _xusb_ep_operation(USB_XFER_SYNCED); // Infinite retries.
if (pending_bytes) if (pending_bytes)
*pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN]; *pending_bytes = res ? 0 : usbd_xotg->bytes_remaining[USB_DIR_IN];
@ -1973,7 +1973,7 @@ bool xusb_device_class_send_max_lun(u8 max_lun)
// Wait for request and transfer start. // Wait for request and transfer start.
while (usbd_xotg->device_state != XUSB_LUN_CONFIGURED) while (usbd_xotg->device_state != XUSB_LUN_CONFIGURED)
{ {
_xusb_ep_operation(500000); _xusb_ep_operation(USB_XFER_SYNCED_CLASS);
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
return true; return true;
} }
@ -1991,7 +1991,7 @@ bool xusb_device_class_send_hid_report()
// Wait for request and transfer start. // Wait for request and transfer start.
while (usbd_xotg->device_state != XUSB_HID_CONFIGURED) while (usbd_xotg->device_state != XUSB_HID_CONFIGURED)
{ {
_xusb_ep_operation(500000); _xusb_ep_operation(USB_XFER_SYNCED_CLASS);
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
return true; return true;
} }