@@ -349,7 +349,7 @@ static inline int dwc2_read_fifo(const struct device *dev, const uint8_t ep,
349
349
struct net_buf * const buf , const size_t size )
350
350
{
351
351
struct usb_dwc2_reg * const base = dwc2_get_base (dev );
352
- size_t len = MIN (size , net_buf_tailroom (buf ));
352
+ size_t len = buf ? MIN (size , net_buf_tailroom (buf )) : 0 ;
353
353
const size_t d = sizeof (uint32_t );
354
354
355
355
/* FIFO access is always in 32-bit words */
@@ -389,7 +389,7 @@ static void dwc2_prep_rx(const struct device *dev,
389
389
390
390
doeptsiz = (1 << USB_DWC2_DOEPTSIZ0_PKTCNT_POS ) | cfg -> mps ;
391
391
if (cfg -> addr == USB_CONTROL_EP_OUT ) {
392
- doeptsiz |= (1 << USB_DWC2_DOEPTSIZ0_SUPCNT_POS );
392
+ doeptsiz |= (3 << USB_DWC2_DOEPTSIZ0_SUPCNT_POS );
393
393
}
394
394
395
395
sys_write32 (doeptsiz , doeptsiz_reg );
@@ -650,7 +650,7 @@ static void dwc2_on_bus_reset(const struct device *dev)
650
650
}
651
651
}
652
652
653
- sys_write32 (0UL , (mem_addr_t )& base -> doepmsk );
653
+ sys_write32 (USB_DWC2_DOEPINT_SETUP , (mem_addr_t )& base -> doepmsk );
654
654
sys_set_bits ((mem_addr_t )& base -> gintmsk , USB_DWC2_GINTSTS_RXFLVL );
655
655
sys_set_bits ((mem_addr_t )& base -> diepmsk , USB_DWC2_DIEPINT_XFERCOMPL );
656
656
@@ -668,22 +668,36 @@ static void dwc2_handle_enumdone(const struct device *dev)
668
668
priv -> enumspd = usb_dwc2_get_dsts_enumspd (dsts );
669
669
}
670
670
671
- static inline int dwc2_read_fifo_setup (const struct device * dev )
671
+ static inline int dwc2_read_fifo_setup (const struct device * dev , uint8_t ep ,
672
+ const size_t size )
672
673
{
673
674
struct usb_dwc2_reg * const base = dwc2_get_base (dev );
674
675
struct udc_dwc2_data * const priv = udc_get_private (dev );
676
+ size_t offset ;
675
677
676
678
/* FIFO access is always in 32-bit words */
677
679
680
+ if (size != 8 ) {
681
+ LOG_ERR ("%d bytes SETUP" , size );
682
+ }
683
+
678
684
/*
679
685
* We store the setup packet temporarily in the driver's private data
680
686
* because there is always a race risk after the status stage OUT
681
687
* packet from the host and the new setup packet. This is fine in
682
688
* bottom-half processing because the events arrive in a queue and
683
689
* there will be a next net_buf for the setup packet.
684
690
*/
685
- sys_put_le32 (sys_read32 (UDC_DWC2_EP_FIFO (base , 0 )), priv -> setup );
686
- sys_put_le32 (sys_read32 (UDC_DWC2_EP_FIFO (base , 0 )), & priv -> setup [4 ]);
691
+ for (offset = 0 ; offset < MIN (size , 8 ); offset += 4 ) {
692
+ sys_put_le32 (sys_read32 (UDC_DWC2_EP_FIFO (base , ep )),
693
+ & priv -> setup [offset ]);
694
+ }
695
+
696
+ /* On protocol error simply discard extra data */
697
+ while (offset < size ) {
698
+ sys_read32 (UDC_DWC2_EP_FIFO (base , ep ));
699
+ offset += 4 ;
700
+ }
687
701
688
702
return 0 ;
689
703
}
@@ -706,26 +720,23 @@ static inline void dwc2_handle_rxflvl(const struct device *dev)
706
720
707
721
switch (pktsts ) {
708
722
case USB_DWC2_GRXSTSR_PKTSTS_SETUP :
709
- evt .type = DWC2_DRV_EVT_SETUP ;
710
-
711
- __ASSERT (evt .bcnt == 8 , "Incorrect setup packet length" );
712
- dwc2_read_fifo_setup (dev );
713
-
714
- k_msgq_put (& drv_msgq , & evt , K_NO_WAIT );
723
+ dwc2_read_fifo_setup (dev , evt .ep , evt .bcnt );
715
724
break ;
716
725
case USB_DWC2_GRXSTSR_PKTSTS_OUT_DATA :
717
726
evt .type = DWC2_DRV_EVT_DOUT ;
718
727
ep_cfg = udc_get_ep_cfg (dev , evt .ep );
719
728
720
729
buf = udc_buf_peek (dev , ep_cfg -> addr );
730
+
731
+ /* RxFIFO data must be retrieved even when buf is NULL */
732
+ dwc2_read_fifo (dev , evt .ep , buf , evt .bcnt );
733
+
721
734
if (buf == NULL ) {
722
735
LOG_ERR ("No buffer for ep 0x%02x" , ep_cfg -> addr );
723
736
udc_submit_event (dev , UDC_EVT_ERROR , - ENOBUFS );
724
737
break ;
725
738
}
726
739
727
- dwc2_read_fifo (dev , USB_CONTROL_EP_OUT , buf , evt .bcnt );
728
-
729
740
if (net_buf_tailroom (buf ) && evt .bcnt == ep_cfg -> mps ) {
730
741
dwc2_prep_rx (dev , ep_cfg , 0 );
731
742
} else {
@@ -734,9 +745,11 @@ static inline void dwc2_handle_rxflvl(const struct device *dev)
734
745
735
746
break ;
736
747
case USB_DWC2_GRXSTSR_PKTSTS_OUT_DATA_DONE :
737
- case USB_DWC2_GRXSTSR_PKTSTS_SETUP_DONE :
738
748
LOG_DBG ("RX pktsts DONE" );
739
749
break ;
750
+ case USB_DWC2_GRXSTSR_PKTSTS_SETUP_DONE :
751
+ LOG_DBG ("SETUP pktsts DONE" );
752
+ break ;
740
753
default :
741
754
break ;
742
755
}
@@ -813,7 +826,6 @@ static inline void dwc2_handle_oepint(const struct device *dev)
813
826
doepmsk = sys_read32 ((mem_addr_t )& base -> doepmsk );
814
827
daint = sys_read32 ((mem_addr_t )& base -> daint );
815
828
816
- /* No OUT interrupt expected in FIFO mode, just clear interrupt */
817
829
for (uint8_t n = 0U ; n < n_max ; n ++ ) {
818
830
mem_addr_t doepint_reg = (mem_addr_t )& base -> out_ep [n ].doepint ;
819
831
uint32_t doepint ;
@@ -826,6 +838,16 @@ static inline void dwc2_handle_oepint(const struct device *dev)
826
838
sys_write32 (status , doepint_reg );
827
839
828
840
LOG_DBG ("ep 0x%02x interrupt status: 0x%x" , n , status );
841
+
842
+ if (status & USB_DWC2_DOEPINT_SETUP ) {
843
+ struct dwc2_drv_event evt = {
844
+ .type = DWC2_DRV_EVT_SETUP ,
845
+ .ep = USB_CONTROL_EP_OUT ,
846
+ .bcnt = 8 ,
847
+ };
848
+
849
+ k_msgq_put (& drv_msgq , & evt , K_NO_WAIT );
850
+ }
829
851
}
830
852
}
831
853
0 commit comments