@@ -41,6 +41,7 @@ struct rp2040_hcd {
4141 volatile bool port_csc ;
4242 volatile bool port_pec ;
4343 volatile bool port_pe ;
44+ usb_osal_mutex_t ep0_mutex ;
4445 struct rp2040_pipe pipe_pool [1 + CONFIG_USBHOST_PIPE_NUM ];
4546} g_rp2040_hcd [CONFIG_USBHOST_MAX_BUS ];
4647
@@ -289,9 +290,16 @@ int usb_hc_init(struct usbh_bus *bus)
289290 g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [i ].waitsem = usb_osal_sem_create (0 );
290291 if (g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [i ].waitsem == NULL ) {
291292 USB_LOG_ERR ("Failed to create waitsem\r\n" );
293+ return - USB_ERR_NOMEM ;
292294 }
293295 }
294296
297+ g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex = usb_osal_mutex_create ();
298+ if (g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex == NULL ) {
299+ USB_LOG_ERR ("Failed to create ep0_mutex\r\n" );
300+ return - USB_ERR_NOMEM ;
301+ }
302+
295303 g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [0 ].endpoint_control = & usbh_dpram -> epx_ctrl ;
296304 g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [0 ].buffer_control = & usbh_dpram -> epx_buf_ctrl ;
297305 g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [0 ].data_buffer = & usbh_dpram -> epx_data [0 ];
@@ -355,6 +363,8 @@ int usb_hc_deinit(struct usbh_bus *bus)
355363 usb_osal_sem_delete (g_rp2040_hcd [bus -> hcd .hcd_id ].pipe_pool [i ].waitsem );
356364 }
357365
366+ usb_osal_mutex_delete (g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex );
367+
358368 return 0 ;
359369}
360370
@@ -502,6 +512,8 @@ int usbh_submit_urb(struct usbh_urb *urb)
502512
503513 if (USB_GET_ENDPOINT_TYPE (urb -> ep -> bmAttributes ) == USB_ENDPOINT_TYPE_CONTROL ) {
504514 chidx = 0 ;
515+ /* all the control transfers use the only one ep0 register, we need to lock */
516+ usb_osal_mutex_take (g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex );
505517 } else {
506518 chidx = rp2040_pipe_alloc (bus );
507519 if (chidx == -1 ) {
@@ -543,9 +555,16 @@ int usbh_submit_urb(struct usbh_urb *urb)
543555 ret = urb -> errorcode ;
544556 /* we can free pipe when waitsem is done */
545557 rp2040_pipe_free (pipe );
558+
559+ if (chidx == 0 ) {
560+ usb_osal_mutex_give (g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex );
561+ }
546562 }
547563 return ret ;
548564errout_timeout :
565+ if (chidx == 0 ) {
566+ usb_osal_mutex_give (g_rp2040_hcd [bus -> hcd .hcd_id ].ep0_mutex );
567+ }
549568 urb -> timeout = 0 ;
550569 usbh_kill_urb (urb );
551570 return ret ;
0 commit comments