summaryrefslogtreecommitdiff
path: root/port
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-03-17 16:40:54 +0800
committersakumisu <[email protected]>2022-03-17 16:40:54 +0800
commitfd574baeb728f2da39b5b2ea366f12b23bd4db59 (patch)
treea679bb7be21731ef3b87a39e9933c14e4245e674 /port
parent080ebc729731e10da769af7f81f38b0ee24403d5 (diff)
fix critical section wrong use
Diffstat (limited to 'port')
-rw-r--r--port/ehci/usb_ehci.c34
-rw-r--r--port/synopsys/usb_hc_synopsys.c87
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;
}