diff --git a/drivers/usbdev/usbdev_fs.c b/drivers/usbdev/usbdev_fs.c index feae8fbd47a..4e0e5fe6b41 100644 --- a/drivers/usbdev/usbdev_fs.c +++ b/drivers/usbdev/usbdev_fs.c @@ -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 */