diff options
| author | sakumisu <[email protected]> | 2022-03-17 16:40:54 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2022-03-17 16:40:54 +0800 |
| commit | fd574baeb728f2da39b5b2ea366f12b23bd4db59 (patch) | |
| tree | a679bb7be21731ef3b87a39e9933c14e4245e674 /port | |
| parent | 080ebc729731e10da769af7f81f38b0ee24403d5 (diff) | |
fix critical section wrong use
Diffstat (limited to 'port')
| -rw-r--r-- | port/ehci/usb_ehci.c | 34 | ||||
| -rw-r--r-- | port/synopsys/usb_hc_synopsys.c | 87 |
2 files changed, 49 insertions, 72 deletions
diff --git a/port/ehci/usb_ehci.c b/port/ehci/usb_ehci.c index 8e6e1175..0da339ae 100644 --- a/port/ehci/usb_ehci.c +++ b/port/ehci/usb_ehci.c @@ -750,7 +750,7 @@ static struct usb_ehci_qh_s *usb_ehci_qh_create(struct usb_ehci_epinfo_s *epinfo #ifndef CONFIG_USBHOST_INT_DISABLE if (epinfo->xfrtype == USB_ENDPOINT_TYPE_INTERRUPT) { - regval |= ((uint32_t)epinfo->interval << QH_EPCAPS_SSMASK_SHIFT); + regval |= ((uint32_t)1 << QH_EPCAPS_SSMASK_SHIFT); } #endif @@ -1831,8 +1831,11 @@ static inline void usb_ehci_portsc_bottomhalf(void) /* Handle port connection status change (CSC) events */ if ((portsc & EHCI_PORTSC_CSC) != 0) { - /* Check current connect status */ - if ((portsc & (EHCI_PORTSC_CCS | EHCI_PORTSC_PE)) != 0) { + /* Debounce */ + usb_osal_msleep(25); + /* Check current connect status*/ + portsc = usb_ehci_getreg(&HCOR->portsc[rhpndx]); + if ((portsc & EHCI_PORTSC_CCS) == EHCI_PORTSC_CCS) { /* Connected ... Did we just become connected? */ if (!g_ehci.connected) { g_ehci.connected = 1; @@ -2032,7 +2035,12 @@ int usb_hc_init(void) uintptr_t physaddr1; uintptr_t physaddr2; - memset(&g_ehci, 0, sizeof(struct usb_ehci_s)); + g_ehci.connected = 0; + g_ehci.qhfree = NULL; + g_ehci.qtdfree = NULL; + + usb_slist_init(&g_ehci.epinfo_list); + /* Initialize the list of free Queue Head (QH) structures */ for (uint8_t i = 0; i < CONFIG_USB_EHCI_QH_NUM; i++) { @@ -2257,21 +2265,16 @@ int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uin int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) { - int ret; struct usb_ehci_epinfo_s *epinfo; struct usbh_hubport *hport; DEBUGASSERT(ep_cfg != NULL && ep_cfg->hport != NULL); - ret = usb_osal_mutex_take(g_ehci.exclsem); - if (ret < 0) { - return ret; - } - hport = ep_cfg->hport; /* new roothub ep info */ if (((ep_cfg->ep_type & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_CONTROL) && (hport->parent == NULL)) { + memset(&g_ehci.ep0, 0, sizeof(struct usb_ehci_epinfo_s)); epinfo = &g_ehci.ep0[hport->port - 1]; } else { /* new exteranl hub ep info */ @@ -2294,28 +2297,21 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) epinfo->hport = hport; epinfo->iocsem = usb_osal_sem_create(0); + usb_slist_add_tail(&g_ehci.epinfo_list, &epinfo->list); *ep = epinfo; - usb_slist_add_tail(&g_ehci.epinfo_list, &epinfo->list); - usb_osal_mutex_give(g_ehci.exclsem); + return 0; } int usbh_ep_free(usbh_epinfo_t ep) { - int ret; struct usb_ehci_epinfo_s *epinfo = (struct usb_ehci_epinfo_s *)ep; - ret = usb_osal_mutex_take(g_ehci.exclsem); - if (ret < 0) { - return ret; - } - usb_osal_sem_delete(epinfo->iocsem); usb_slist_remove(&g_ehci.epinfo_list, &epinfo->list); usb_free(epinfo); - usb_osal_mutex_give(g_ehci.exclsem); return 0; } diff --git a/port/synopsys/usb_hc_synopsys.c b/port/synopsys/usb_hc_synopsys.c index 3a76ff30..ff5f97e5 100644 --- a/port/synopsys/usb_hc_synopsys.c +++ b/port/synopsys/usb_hc_synopsys.c @@ -73,7 +73,6 @@ struct usb_synopsys_priv { * Allocate a channel. * ****************************************************************************/ - static int usb_synopsys_chan_alloc(struct usb_synopsys_priv *priv) { int chidx; @@ -119,7 +118,6 @@ static void usb_synopsys_chan_free(struct usb_synopsys_priv *priv, int chidx) * Free all channels. * ****************************************************************************/ - static inline void usb_synopsys_chan_freeall(struct usb_synopsys_priv *priv) { uint8_t chidx; @@ -145,7 +143,6 @@ static inline void usb_synopsys_chan_freeall(struct usb_synopsys_priv *priv) * started. * ****************************************************************************/ - static int usb_synopsys_chan_waitsetup(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan) { @@ -189,7 +186,6 @@ static int usb_synopsys_chan_waitsetup(struct usb_synopsys_priv *priv, * Might be called from the level of an interrupt handler * ****************************************************************************/ - #ifdef CONFIG_USBHOST_ASYNCH static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan, @@ -221,7 +217,7 @@ static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv, #endif /**************************************************************************** - * Name: stm32_chan_wait + * Name: usb_synopsys_chan_wait * * Description: * Wait for a transfer on a channel to complete. @@ -230,7 +226,6 @@ static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv, * Called from a normal thread context * ****************************************************************************/ - static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan) { int ret; @@ -254,7 +249,7 @@ static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_syn } /**************************************************************************** - * Name: stm32_chan_wakeup + * Name: usb_synopsys_chan_wakeup * * Description: * A channel transfer has completed... wakeup any threads waiting for the @@ -265,7 +260,6 @@ static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_syn * the channel. Interrupts are disabled. * ****************************************************************************/ - static void usb_synopsys_chan_wakeup(struct usb_synopsys_priv *priv, struct usb_synopsys_chan *chan) { usbh_asynch_callback_t callback; @@ -323,7 +317,9 @@ __WEAK void usb_hc_low_level_init(void) int usb_hc_init(void) { - memset(&g_usbhost, 0, sizeof(struct usb_synopsys_priv)); + g_usbhost.sof_timer = 0; + g_usbhost.connected = 0; + g_usbhost.pscwait = 0; #if defined(CONFIG_USB_HS) || defined(CONFIG_USB_HS_IN_FULL) g_usbhost.handle = &hhcd_USB_OTG_HS; g_usbhost.handle->Instance = USB_OTG_HS; @@ -334,15 +330,6 @@ int usb_hc_init(void) g_usbhost.exclsem = usb_osal_mutex_create(); - for (uint8_t i = 0; i < CONFIG_USBHOST_CHANNELS; i++) { - struct usb_synopsys_chan *chan = &g_usbhost.chan[i]; - - /* The waitsem semaphore is used for signaling and, hence, should not - * have priority inheritance enabled. - */ - chan->waitsem = usb_osal_sem_create(0); - } - g_usbhost.handle->Init.Host_channels = CONFIG_USBHOST_CHANNELS; g_usbhost.handle->Init.speed = HCD_SPEED_FULL; g_usbhost.handle->Init.dma_enable = DISABLE; @@ -405,32 +392,32 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) struct usb_synopsys_ctrlinfo *ep0; struct usbh_hubport *hport; int chidx; - int ret; uint8_t speed; - ret = usb_osal_mutex_take(g_usbhost.exclsem); - if (ret < 0) { - return ret; - } - hport = ep_cfg->hport; if (hport->speed == USB_SPEED_FULL) { speed = 1; } else if (hport->speed == USB_SPEED_LOW) { speed = 2; + } else if (hport->speed == USB_SPEED_HIGH) { + speed = 0; } if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) { ep0 = usb_malloc(sizeof(struct usb_synopsys_ctrlinfo)); + memset(ep0, 0, sizeof(struct usb_synopsys_ctrlinfo)); ep0->outndx = usb_synopsys_chan_alloc(&g_usbhost); ep0->inndx = usb_synopsys_chan_alloc(&g_usbhost); chan = &priv->chan[ep0->outndx]; - chan->interval = 0; + memset(chan, 0, sizeof(struct usb_synopsys_chan)); + chan->waitsem = usb_osal_sem_create(0); + chan = &priv->chan[ep0->inndx]; - chan->interval = 0; + memset(chan, 0, sizeof(struct usb_synopsys_chan)); + chan->waitsem = usb_osal_sem_create(0); HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps); @@ -441,7 +428,9 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) chidx = usb_synopsys_chan_alloc(&g_usbhost); chan = &priv->chan[chidx]; + memset(chan, 0, sizeof(struct usb_synopsys_chan)); chan->interval = ep_cfg->ep_interval; + chan->waitsem = usb_osal_sem_create(0); HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, speed, ep_cfg->ep_type, ep_cfg->ep_mps); @@ -450,27 +439,22 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg) *ep = (usbh_epinfo_t)chidx; } - usb_osal_mutex_give(g_usbhost.exclsem); return 0; } int usbh_ep_free(usbh_epinfo_t ep) { - int ret; - - ret = usb_osal_mutex_take(g_usbhost.exclsem); - if (ret < 0) { - return ret; - } if ((uintptr_t)ep < CONFIG_USBHOST_CHANNELS) { usb_synopsys_chan_free(&g_usbhost, (int)ep); + usb_osal_sem_delete(g_usbhost.chan[ep].waitsem); } else { struct usb_synopsys_ctrlinfo *ep0 = (struct usb_synopsys_ctrlinfo *)ep; usb_synopsys_chan_free(&g_usbhost, ep0->inndx); usb_synopsys_chan_free(&g_usbhost, ep0->outndx); + usb_osal_sem_delete(g_usbhost.chan[ep0->inndx].waitsem); + usb_osal_sem_delete(g_usbhost.chan[ep0->outndx].waitsem); } - usb_osal_mutex_give(g_usbhost.exclsem); return 0; } @@ -770,6 +754,10 @@ int usb_ep_cancel(usbh_epinfo_t ep) uint32_t flags; struct usb_synopsys_chan *chan; struct usb_synopsys_priv *priv = &g_usbhost; +#ifdef CONFIG_USBHOST_ASYNCH + usbh_asynch_callback_t callback; + void *arg; +#endif uint8_t chidx = (uint8_t)ep; @@ -778,6 +766,16 @@ int usb_ep_cancel(usbh_epinfo_t ep) flags = usb_osal_enter_critical_section(); chan->result = -ESHUTDOWN; +#ifdef CONFIG_USBHOST_ASYNCH + /* Extract the callback information */ + callback = chan->callback; + arg = chan->arg; + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; +#endif + usb_osal_leave_critical_section(flags); + /* Is there a thread waiting for this transfer to complete? */ if (chan->waiter) { @@ -786,29 +784,12 @@ int usb_ep_cancel(usbh_epinfo_t ep) usb_osal_sem_give(chan->waitsem); } #ifdef CONFIG_USBHOST_ASYNCH - /* No.. is an asynchronous callback expected when the transfer - * completes? - */ - - else if (chan->callback) { - usbh_asynch_callback_t callback; - void *arg; - - /* Extract the callback information */ - - callback = chan->callback; - arg = chan->arg; - - chan->callback = NULL; - chan->arg = NULL; - chan->xfrd = 0; - + /* No.. is an asynchronous callback expected when the transfer completes? */ + else if (callback) { /* Then perform the callback */ - callback(arg, -ESHUTDOWN); } #endif - usb_osal_leave_critical_section(flags); return 0; } |
