@@ -170,25 +170,20 @@ static ALWAYS_INLINE void usbfsotg_resume_tx(const struct device *dev)
170170 base -> CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK ;
171171}
172172
173- /* Initiate a new transfer, must not be used for control endpoint OUT */
174- static int usbfsotg_xfer_start ( const struct device * dev ,
175- struct udc_ep_config * const cfg )
173+ static int usbfsotg_xfer_continue ( const struct device * dev ,
174+ struct udc_ep_config * const cfg ,
175+ struct net_buf * const buf )
176176{
177177 const struct usbfsotg_config * config = dev -> config ;
178178 USB_Type * base = config -> base ;
179179 struct usbfsotg_bd * bd ;
180- struct net_buf * buf ;
181180 uint8_t * data_ptr ;
182181 size_t len ;
183182
184- buf = udc_buf_peek (dev , cfg -> addr );
185- if (buf == NULL ) {
186- return - ENODATA ;
187- }
188-
189183 bd = usbfsotg_get_ebd (dev , cfg , false);
190- if (usbfsotg_bd_is_busy (bd )) {
191- LOG_DBG ("ep 0x%02x buf busy" , cfg -> addr );
184+ if (unlikely (usbfsotg_bd_is_busy (bd ))) {
185+ LOG_ERR ("ep 0x%02x buf busy" , cfg -> addr );
186+ __ASSERT_NO_MSG (false);
192187 return - EBUSY ;
193188 }
194189
@@ -213,6 +208,20 @@ static int usbfsotg_xfer_start(const struct device *dev,
213208 return 0 ;
214209}
215210
211+ /* Initiate a new transfer, must not be used for control endpoint OUT */
212+ static int usbfsotg_xfer_next (const struct device * dev ,
213+ struct udc_ep_config * const cfg )
214+ {
215+ struct net_buf * buf ;
216+
217+ buf = udc_buf_peek (dev , cfg -> addr );
218+ if (buf == NULL ) {
219+ return - ENODATA ;
220+ }
221+
222+ return usbfsotg_xfer_continue (dev , cfg , buf );
223+ }
224+
216225static inline int usbfsotg_ctrl_feed_start (const struct device * dev ,
217226 struct net_buf * const buf )
218227{
@@ -465,9 +474,11 @@ static void xfer_work_handler(struct k_work *item)
465474 break ;
466475 case USBFSOTG_EVT_DOUT :
467476 err = work_handler_out (ev -> dev , ev -> ep );
477+ udc_ep_set_busy (ev -> dev , ev -> ep , false);
468478 break ;
469479 case USBFSOTG_EVT_DIN :
470480 err = work_handler_in (ev -> dev , ev -> ep );
481+ udc_ep_set_busy (ev -> dev , ev -> ep , false);
471482 break ;
472483 case USBFSOTG_EVT_CLEAR_HALT :
473484 err = usbfsotg_ep_clear_halt (ev -> dev , ep_cfg );
@@ -481,8 +492,10 @@ static void xfer_work_handler(struct k_work *item)
481492 }
482493
483494 /* Peek next transer */
484- if (ev -> ep != USB_CONTROL_EP_OUT ) {
485- usbfsotg_xfer_start (ev -> dev , ep_cfg );
495+ if (ev -> ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy (ev -> dev , ev -> ep )) {
496+ if (usbfsotg_xfer_next (ev -> dev , ep_cfg ) == 0 ) {
497+ udc_ep_set_busy (ev -> dev , ev -> ep , true);
498+ }
486499 }
487500
488501xfer_work_error :
@@ -576,7 +589,7 @@ static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev,
576589 if (ep == USB_CONTROL_EP_OUT ) {
577590 usbfsotg_ctrl_feed_start (dev , buf );
578591 } else {
579- usbfsotg_xfer_start (dev , ep_cfg );
592+ usbfsotg_xfer_continue (dev , ep_cfg , buf );
580593 }
581594 } else {
582595 if (ep == USB_CONTROL_EP_OUT ) {
@@ -600,10 +613,10 @@ static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev,
600613
601614 net_buf_pull (buf , len );
602615 if (buf -> len ) {
603- usbfsotg_xfer_start (dev , ep_cfg );
616+ usbfsotg_xfer_continue (dev , ep_cfg , buf );
604617 } else {
605618 if (udc_ep_buf_has_zlp (buf )) {
606- usbfsotg_xfer_start (dev , ep_cfg );
619+ usbfsotg_xfer_continue (dev , ep_cfg , buf );
607620 udc_ep_buf_clear_zlp (buf );
608621 break ;
609622 }
@@ -718,6 +731,8 @@ static int usbfsotg_ep_dequeue(const struct device *dev,
718731 udc_submit_event (dev , UDC_EVT_EP_REQUEST , - ECONNABORTED , buf );
719732 }
720733
734+ udc_ep_set_busy (dev , cfg -> addr , false);
735+
721736 return 0 ;
722737}
723738
0 commit comments