summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2013-12-09 15:55:36 -0800
committerFelipe Balbi <balbi@ti.com>2013-12-09 22:44:06 -0600
commit7fa6803483ed215f9c73780194d49719a060bf1c (patch)
treeca7774b3bd43507aaf7b4f1c2b533582c2e8a079
parent0b2d2bbade59ab2067f326d6dbc2628bee227fd5 (diff)
usb: gadget: f_fs: remove loop from I/O function
When endpoint changes (due to it being disabled or alt setting changed), mimic the action as if the change happened after the request has been queued, instead of retrying with the new endpoint. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Cc: David Cohen <david.a.cohen@linux.intel.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/f_fs.c94
1 files changed, 40 insertions, 54 deletions
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 774e8b89cdb5..1222cf9b62d3 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -758,73 +758,59 @@ static ssize_t ffs_epfile_io(struct file *file,
ssize_t ret;
int halt;
- goto first_try;
- do {
- spin_unlock_irq(&epfile->ffs->eps_lock);
- mutex_unlock(&epfile->mutex);
+ /* Are we still active? */
+ if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
+ ret = -ENODEV;
+ goto error;
+ }
-first_try:
- /* Are we still active? */
- if (WARN_ON(epfile->ffs->state != FFS_ACTIVE)) {
- ret = -ENODEV;
+ /* Wait for endpoint to be enabled */
+ ep = epfile->ep;
+ if (!ep) {
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
goto error;
}
- /* Wait for endpoint to be enabled */
- ep = epfile->ep;
- if (!ep) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- goto error;
- }
-
- if (wait_event_interruptible(epfile->wait,
- (ep = epfile->ep))) {
- ret = -EINTR;
- goto error;
- }
- }
-
- /* Do we halt? */
- halt = !read == !epfile->in;
- if (halt && epfile->isoc) {
- ret = -EINVAL;
+ ret = wait_event_interruptible(epfile->wait, (ep = epfile->ep));
+ if (ret) {
+ ret = -EINTR;
goto error;
}
+ }
- /* Allocate & copy */
- if (!halt && !data) {
- data = kzalloc(len, GFP_KERNEL);
- if (unlikely(!data))
- return -ENOMEM;
+ /* Do we halt? */
+ halt = !read == !epfile->in;
+ if (halt && epfile->isoc) {
+ ret = -EINVAL;
+ goto error;
+ }
- if (!read &&
- unlikely(__copy_from_user(data, buf, len))) {
- ret = -EFAULT;
- goto error;
- }
- }
+ /* Allocate & copy */
+ if (!halt) {
+ data = kmalloc(len, GFP_KERNEL);
+ if (unlikely(!data))
+ return -ENOMEM;
- /* We will be using request */
- ret = ffs_mutex_lock(&epfile->mutex,
- file->f_flags & O_NONBLOCK);
- if (unlikely(ret))
+ if (!read && unlikely(copy_from_user(data, buf, len))) {
+ ret = -EFAULT;
goto error;
+ }
+ }
- /*
- * We're called from user space, we can use _irq rather then
- * _irqsave
- */
- spin_lock_irq(&epfile->ffs->eps_lock);
+ /* We will be using request */
+ ret = ffs_mutex_lock(&epfile->mutex, file->f_flags & O_NONBLOCK);
+ if (unlikely(ret))
+ goto error;
- /*
- * While we were acquiring mutex endpoint got disabled
- * or changed?
- */
- } while (unlikely(epfile->ep != ep));
+ spin_lock_irq(&epfile->ffs->eps_lock);
- /* Halt */
- if (unlikely(halt)) {
+ if (epfile->ep != ep) {
+ /* In the meantime, endpoint got disabled or changed. */
+ ret = -ESHUTDOWN;
+ spin_unlock_irq(&epfile->ffs->eps_lock);
+ } else if (halt) {
+ /* Halt */
if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep))
usb_ep_set_halt(ep->ep);
spin_unlock_irq(&epfile->ffs->eps_lock);