drivers: nordic: usbd: Fix long (fragmented) control OUT transfers

Fragmented long CTRL OUT transfers does not work properly, because
they were not handler properly by the shim. In such transfers,
a special call (nrfx_usbd_setup_data_clear()) must be performed
before every data packet and not just before the first one.
This patch adds a byte counter which is set while processing setup
packet (host->device only) to be able to decide whether there will
be more data packets coming (and to call_data_clear() or not).

Fixes #11232 .

Signed-off-by: Paweł Zadrożniak <pawel.zadrozniak@nordicsemi.no>
This commit is contained in:
Paweł Zadrożniak 2018-11-28 17:19:12 +01:00 committed by Carles Cufí
commit 1da367b5bf

View file

@ -241,6 +241,8 @@ struct nrf_usbd_ctx {
struct k_mutex drv_lock;
struct nrf_usbd_ep_ctx ep_ctx[CFG_EP_CNT];
u16_t ctrl_read_len;
};
@ -728,10 +730,17 @@ static inline void usbd_work_process_setup(struct nrf_usbd_ep_ctx *ep_ctx)
/* Inform the stack. */
ep_ctx->cfg.cb(ep_ctx->cfg.addr, USB_DC_EP_SETUP);
struct nrf_usbd_ctx *ctx = get_usbd_ctx();
if (((usbd_setup->bmRequestType & USB_BMREQUESTTYPE_MASK)
== USB_BMREQUESTTYPE_HOSTTODEVICE_MASK)
&& (usbd_setup->wLength)) {
struct nrf_usbd_ctx *ctx = get_usbd_ctx();
ctx->ctrl_read_len -= usbd_setup->wLength;
nrfx_usbd_setup_data_clear();
} else {
ctx->ctrl_read_len = 0;
}
}
@ -871,6 +880,7 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event)
break;
case NRFX_USBD_EP_OK: {
struct nrf_usbd_ctx *ctx = get_usbd_ctx();
struct usbd_ep_event *ev = usbd_evt_alloc();
nrfx_err_t err_code;
@ -888,6 +898,13 @@ static void usbd_event_transfer_ctrl(nrfx_usbd_evt_t const *const p_event)
}
LOG_DBG("ctrl read done: %d", ep_ctx->buf.len);
if (ctx->ctrl_read_len > ep_ctx->buf.len) {
ctx->ctrl_read_len -= ep_ctx->buf.len;
nrfx_usbd_setup_data_clear();
} else {
ctx->ctrl_read_len = 0;
}
usbd_evt_put(ev);
usbd_work_schedule();
}