summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/function/f_fs.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index cb92758a982c..cdcb3dcf5b95 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -138,6 +138,7 @@ struct ffs_epfile {
unsigned char isoc; /* P: ffs->eps_lock */
unsigned char _pad;
+ atomic_t opened;
};
/* ffs_io_data structure ***************************************************/
@@ -947,8 +948,19 @@ ffs_epfile_open(struct inode *inode, struct file *file)
if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
return -ENODEV;
+ smp_mb__before_atomic();
+ if (atomic_read(&epfile->opened)) {
+ pr_err("%s(): ep(%s) is already opened.\n",
+ __func__, epfile->name);
+ return -EBUSY;
+ }
+
+ smp_mb__before_atomic();
+ atomic_set(&epfile->opened, 1);
file->private_data = epfile;
ffs_data_opened(epfile->ffs);
+
+ smp_mb__before_atomic();
atomic_set(&epfile->error, 0);
return 0;
@@ -1065,6 +1077,8 @@ ffs_epfile_release(struct inode *inode, struct file *file)
ENTER();
+ smp_mb__before_atomic();
+ atomic_set(&epfile->opened, 0);
atomic_set(&epfile->error, 1);
ffs_data_closed(epfile->ffs);
file->private_data = NULL;
@@ -1662,6 +1676,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
epfile->ffs = ffs;
mutex_init(&epfile->mutex);
init_waitqueue_head(&epfile->wait);
+ atomic_set(&epfile->opened, 0);
if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]);
else
@@ -1708,6 +1723,7 @@ static void ffs_func_eps_disable(struct ffs_function *func)
spin_lock_irqsave(&func->ffs->eps_lock, flags);
do {
+ smp_mb__before_atomic();
if (epfile)
atomic_set(&epfile->error, 1);