mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
Use small lock to protect usbdev and endpoint in AVR.
Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
This commit is contained in:
@@ -34,8 +34,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/spinlock.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/usb/usb.h>
|
#include <nuttx/usb/usb.h>
|
||||||
@@ -252,6 +254,10 @@ struct avr_usbdev_s
|
|||||||
/* The endpoint list */
|
/* The endpoint list */
|
||||||
|
|
||||||
struct avr_ep_s eplist[AVR_NENDPOINTS];
|
struct avr_ep_s eplist[AVR_NENDPOINTS];
|
||||||
|
|
||||||
|
/* Spinlock */
|
||||||
|
|
||||||
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -2294,14 +2300,16 @@ static int avr_epdisable(FAR struct usbdev_ep_s *ep)
|
|||||||
|
|
||||||
usbtrace(TRACE_EPDISABLE, privep->ep.eplog);
|
usbtrace(TRACE_EPDISABLE, privep->ep.eplog);
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
|
|
||||||
/* Disable the endpoint */
|
/* Disable the endpoint */
|
||||||
|
|
||||||
avr_epreset(privep, -ESHUTDOWN);
|
avr_epreset(privep, -ESHUTDOWN);
|
||||||
g_usbdev.stalled = true;
|
g_usbdev.stalled = true;
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2447,7 +2455,8 @@ static int avr_epsubmit(FAR struct usbdev_ep_s *ep,
|
|||||||
|
|
||||||
/* Disable Interrupts */
|
/* Disable Interrupts */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
|
|
||||||
/* If we are stalled, then drop all requests on the floor */
|
/* If we are stalled, then drop all requests on the floor */
|
||||||
|
|
||||||
@@ -2508,7 +2517,8 @@ static int avr_epsubmit(FAR struct usbdev_ep_s *ep,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2542,9 +2552,11 @@ static int avr_epcancel(FAR struct usbdev_ep_s *ep,
|
|||||||
* all requests ...
|
* all requests ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
avr_cancelrequests(privep, -ESHUTDOWN);
|
avr_cancelrequests(privep, -ESHUTDOWN);
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2562,7 +2574,7 @@ static int avr_epstall(FAR struct usbdev_ep_s *ep, bool resume)
|
|||||||
|
|
||||||
/* STALL or RESUME the endpoint */
|
/* STALL or RESUME the endpoint */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
if (resume)
|
if (resume)
|
||||||
{
|
{
|
||||||
/* Clear stall and reset the data toggle */
|
/* Clear stall and reset the data toggle */
|
||||||
@@ -2579,7 +2591,7 @@ static int avr_epstall(FAR struct usbdev_ep_s *ep, bool resume)
|
|||||||
g_usbdev.stalled = true;
|
g_usbdev.stalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2650,7 +2662,7 @@ static FAR struct usbdev_ep_s *avr_allocep(FAR struct usbdev_s *dev,
|
|||||||
{
|
{
|
||||||
/* Yes.. now see if any of the request endpoints are available */
|
/* Yes.. now see if any of the request endpoints are available */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
|
||||||
/* Select the lowest bit in the set of matching, available endpoints */
|
/* Select the lowest bit in the set of matching, available endpoints */
|
||||||
|
|
||||||
@@ -2684,14 +2696,14 @@ static FAR struct usbdev_ep_s *avr_allocep(FAR struct usbdev_s *dev,
|
|||||||
|
|
||||||
/* And return the pointer to the standard endpoint structure */
|
/* And return the pointer to the standard endpoint structure */
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
return &privep->ep;
|
return &privep->ep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shouldn't get here */
|
/* Shouldn't get here */
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
usbtrace(TRACE_DEVERROR(AVR_TRACEERR_NOEP), (uint16_t) epno);
|
usbtrace(TRACE_DEVERROR(AVR_TRACEERR_NOEP), (uint16_t) epno);
|
||||||
@@ -2716,12 +2728,12 @@ static void avr_freeep(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep)
|
|||||||
|
|
||||||
/* Mark the endpoint as available */
|
/* Mark the endpoint as available */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
epmask = (1 << privep->ep.eplog);
|
epmask = (1 << privep->ep.eplog);
|
||||||
g_usbdev.epavail |= epmask;
|
g_usbdev.epavail |= epmask;
|
||||||
g_usbdev.epinset &= ~epmask;
|
g_usbdev.epinset &= ~epmask;
|
||||||
g_usbdev.epoutset &= ~epmask;
|
g_usbdev.epoutset &= ~epmask;
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -2754,9 +2766,11 @@ static int avr_wakeup(struct usbdev_s *dev)
|
|||||||
|
|
||||||
usbtrace(TRACE_DEVWAKEUP, 0);
|
usbtrace(TRACE_DEVWAKEUP, 0);
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
avr_genwakeup();
|
avr_genwakeup();
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2821,6 +2835,10 @@ void avr_usbinitialize(void)
|
|||||||
{
|
{
|
||||||
usbtrace(TRACE_DEVINIT, 0);
|
usbtrace(TRACE_DEVINIT, 0);
|
||||||
|
|
||||||
|
/* Initialize driver lock */
|
||||||
|
|
||||||
|
spin_lock_init(&g_usbdev.lock);
|
||||||
|
|
||||||
/* Initialize the device state structure */
|
/* Initialize the device state structure */
|
||||||
|
|
||||||
memset(&g_usbdev, 0, sizeof(struct avr_usbdev_s));
|
memset(&g_usbdev, 0, sizeof(struct avr_usbdev_s));
|
||||||
@@ -2891,7 +2909,8 @@ void avr_usbuninitialize(void)
|
|||||||
|
|
||||||
/* Disconnect device */
|
/* Disconnect device */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
avr_pullup(&g_usbdev.usbdev, false);
|
avr_pullup(&g_usbdev.usbdev, false);
|
||||||
g_usbdev.usbdev.speed = USB_SPEED_UNKNOWN;
|
g_usbdev.usbdev.speed = USB_SPEED_UNKNOWN;
|
||||||
|
|
||||||
@@ -2903,7 +2922,8 @@ void avr_usbuninitialize(void)
|
|||||||
/* Shutdown the USB controller hardware */
|
/* Shutdown the USB controller hardware */
|
||||||
|
|
||||||
avr_usbshutdown();
|
avr_usbshutdown();
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -3018,8 +3038,10 @@ void avr_pollvbus(void)
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||||
|
sched_lock();
|
||||||
avr_genvbus();
|
avr_genvbus();
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||||
|
sched_unlock();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user