diff options
| -rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 16 |
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); |
