Skip to content

Commit

Permalink
usb: gadget: f_fs: remove loop from I/O function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michal Nazarewicz authored and Felipe Balbi committed Dec 10, 2013
1 parent 0b2d2bb commit 7fa6803
Showing 1 changed file with 40 additions and 54 deletions.
94 changes: 40 additions & 54 deletions drivers/usb/gadget/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7fa6803

Please sign in to comment.