mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 22:20:01 +08:00
driver/usbdev: Use small lock to protect usbdev fs
Use spin lock to replace enter_critical_section Signed-off-by: yangsong8 <yangsong8@xiaomi.com>
This commit is contained in:
+26
-23
@@ -85,6 +85,7 @@ struct usbdev_fs_ep_s
|
||||
struct sq_queue_s reqq; /* Available request containers */
|
||||
FAR struct usbdev_fs_req_s *reqbuffer; /* Request buffer */
|
||||
FAR struct pollfd *fds[CONFIG_USBDEV_FS_NPOLLWAITERS];
|
||||
spinlock_t spinlock;
|
||||
|
||||
/* These member is valid for endpoint 0 */
|
||||
|
||||
@@ -289,7 +290,7 @@ static void usbdev_fs_rdcomplete(FAR struct usbdev_ep_s *ep,
|
||||
|
||||
/* Queue request and notify readers */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave_nopreempt(&fs_ep->spinlock);
|
||||
|
||||
/* Put request on RX pending queue */
|
||||
|
||||
@@ -298,7 +299,7 @@ static void usbdev_fs_rdcomplete(FAR struct usbdev_ep_s *ep,
|
||||
|
||||
usbdev_fs_notify(fs_ep, POLLIN);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore_nopreempt(&fs_ep->spinlock, flags);
|
||||
return;
|
||||
|
||||
case -ESHUTDOWN: /* Disconnection */
|
||||
@@ -351,7 +352,7 @@ static void usbdev_fs_wrcomplete(FAR struct usbdev_ep_s *ep,
|
||||
|
||||
/* Return the write request to the free list */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave_nopreempt(&fs_ep->spinlock);
|
||||
sq_addlast(&container->node, &fs_ep->reqq);
|
||||
|
||||
/* Check for termination condition */
|
||||
@@ -383,7 +384,7 @@ static void usbdev_fs_wrcomplete(FAR struct usbdev_ep_s *ep,
|
||||
break;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore_nopreempt(&fs_ep->spinlock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -402,13 +403,13 @@ static int usbdev_fs_blocking_io(FAR struct usbdev_fs_ep_s *fs_ep,
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&fs_ep->spinlock);
|
||||
|
||||
if (!sq_empty(queue))
|
||||
{
|
||||
/* Queue not empty after all */
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ static int usbdev_fs_blocking_io(FAR struct usbdev_fs_ep_s *fs_ep,
|
||||
sem.next = *list;
|
||||
*list = &sem;
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
|
||||
nxmutex_unlock(&fs_ep->lock);
|
||||
|
||||
@@ -435,7 +436,7 @@ static int usbdev_fs_blocking_io(FAR struct usbdev_fs_ep_s *fs_ep,
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&fs_ep->spinlock);
|
||||
|
||||
FAR usbdev_fs_waiter_sem_t *cur_sem = *list;
|
||||
|
||||
@@ -457,7 +458,7 @@ static int usbdev_fs_blocking_io(FAR struct usbdev_fs_ep_s *fs_ep,
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
nxmutex_unlock(&fs_ep->lock);
|
||||
}
|
||||
|
||||
@@ -645,10 +646,10 @@ static ssize_t usbdev_fs_read(FAR struct file *filep, FAR char *buffer,
|
||||
memcpy(buffer, &ctrl_container->req, retlen);
|
||||
}
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&fs_ep->spinlock);
|
||||
sq_remfirst(queue);
|
||||
sq_addlast(&ctrl_container->node, &fs_ep->ctrlreqq_free);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -691,9 +692,9 @@ static ssize_t usbdev_fs_read(FAR struct file *filep, FAR char *buffer,
|
||||
|
||||
/* FIXME use atomic queue primitives ? */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&fs_ep->spinlock);
|
||||
sq_remfirst(queue);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
|
||||
ret = usbdev_fs_submit_rdreq(fs_ep->ep, container);
|
||||
if (ret < 0)
|
||||
@@ -783,12 +784,12 @@ static ssize_t usbdev_fs_write(FAR struct file *filep,
|
||||
|
||||
/* Get available TX request slot */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&fs_ep->spinlock);
|
||||
|
||||
container = container_of(sq_remfirst(&fs_ep->reqq),
|
||||
struct usbdev_fs_req_s, node);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&fs_ep->spinlock, flags);
|
||||
|
||||
req = container->req;
|
||||
|
||||
@@ -872,7 +873,7 @@ static int usbdev_fs_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
|
||||
/* FIXME only parts of this function required interrupt disabled */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave_nopreempt(&fs_ep->spinlock);
|
||||
|
||||
/* This is a request to set up the poll. Find an available
|
||||
* slot for the poll structure reference
|
||||
@@ -934,7 +935,7 @@ static int usbdev_fs_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
poll_notify(fs_ep->fds, CONFIG_USBDEV_FS_NPOLLWAITERS, eventset);
|
||||
|
||||
exit_leave_critical:
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore_nopreempt(&fs_ep->spinlock, flags);
|
||||
errout:
|
||||
nxmutex_unlock(&fs_ep->lock);
|
||||
return ret;
|
||||
@@ -952,10 +953,9 @@ static void usbdev_fs_connect(FAR struct usbdev_fs_dev_s *fs, int connect)
|
||||
{
|
||||
FAR struct usbdev_devinfo_s *devinfo = &fs->devinfo;
|
||||
FAR struct usbdev_fs_ep_s *fs_ep;
|
||||
irqstate_t flags;
|
||||
uint16_t cnt;
|
||||
|
||||
irqstate_t flags = enter_critical_section();
|
||||
|
||||
if (connect)
|
||||
{
|
||||
/* Notify poll/select with POLLPRI */
|
||||
@@ -963,7 +963,9 @@ static void usbdev_fs_connect(FAR struct usbdev_fs_dev_s *fs, int connect)
|
||||
for (cnt = 0; cnt < devinfo->nendpoints + 1; cnt++)
|
||||
{
|
||||
fs_ep = &fs->eps[cnt];
|
||||
flags = spin_lock_irqsave_nopreempt(&fs_ep->spinlock);
|
||||
poll_notify(fs_ep->fds, CONFIG_USBDEV_FS_NPOLLWAITERS, POLLPRI);
|
||||
spin_unlock_irqrestore_nopreempt(&fs_ep->spinlock, flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -973,11 +975,11 @@ static void usbdev_fs_connect(FAR struct usbdev_fs_dev_s *fs, int connect)
|
||||
for (cnt = 0; cnt < devinfo->nendpoints + 1; cnt++)
|
||||
{
|
||||
fs_ep = &fs->eps[cnt];
|
||||
flags = spin_lock_irqsave_nopreempt(&fs_ep->spinlock);
|
||||
usbdev_fs_notify(fs_ep, POLLERR | POLLHUP);
|
||||
spin_unlock_irqrestore_nopreempt(&fs_ep->spinlock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1004,6 +1006,7 @@ static int usbdev_fs_ep_bind(FAR struct usbdev_s *dev, uint8_t epno,
|
||||
/* Initialize fs ep lock */
|
||||
|
||||
nxmutex_init(&fs_ep->lock);
|
||||
spin_lock_init(&fs_ep->spinlock);
|
||||
|
||||
/* Initialize request queue */
|
||||
|
||||
@@ -1487,8 +1490,8 @@ static int usbdev_fs_classsetup(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
else
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
FAR struct usbdev_fs_ep_s *ep0 = &fs->eps[0];
|
||||
irqstate_t flags = spin_lock_irqsave_nopreempt(&ep0->spinlock);
|
||||
|
||||
if (!sq_empty(&ep0->ctrlreqq_free))
|
||||
{
|
||||
@@ -1508,7 +1511,7 @@ static int usbdev_fs_classsetup(FAR struct usbdevclass_driver_s *driver,
|
||||
uerr("Failed to find free control request for ep0");
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore_nopreempt(&ep0->spinlock, flags);
|
||||
}
|
||||
|
||||
/* Returning a negative value will cause a STALL */
|
||||
|
||||
Reference in New Issue
Block a user