mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
Merge "USB: f_fs: Set ffs->func to NULL after disabling endpoint in set_alt()"
This commit is contained in:
commit
bff3607241
1 changed files with 32 additions and 8 deletions
|
|
@ -167,6 +167,7 @@ struct ffs_epfile {
|
|||
|
||||
struct ffs_data *ffs;
|
||||
struct ffs_ep *ep; /* P: ffs->eps_lock */
|
||||
atomic_t opened;
|
||||
|
||||
struct dentry *dentry;
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ struct ffs_epfile {
|
|||
unsigned char in; /* P: ffs->eps_lock */
|
||||
unsigned char isoc; /* P: ffs->eps_lock */
|
||||
|
||||
unsigned char _pad;
|
||||
bool invalid;
|
||||
};
|
||||
|
||||
struct ffs_buffer {
|
||||
|
|
@ -1044,6 +1045,16 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
|||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
/*
|
||||
* epfile->invalid is set when EPs are disabled. Userspace
|
||||
* might have stale threads continuing to do I/O and may be
|
||||
* unaware of that especially if we block here. Instead return
|
||||
* an error immediately here and don't allow any more I/O
|
||||
* until the epfile is reopened.
|
||||
*/
|
||||
if (epfile->invalid)
|
||||
return -ENODEV;
|
||||
|
||||
ret = wait_event_interruptible(
|
||||
epfile->ffs->wait, (ep = epfile->ep));
|
||||
if (ret)
|
||||
|
|
@ -1246,15 +1257,16 @@ ffs_epfile_open(struct inode *inode, struct file *file)
|
|||
|
||||
ENTER();
|
||||
|
||||
ffs_log("%s: state %d setup_state %d flag %lu", epfile->name,
|
||||
epfile->ffs->state, epfile->ffs->setup_state,
|
||||
epfile->ffs->flags);
|
||||
ffs_log("%s: state %d setup_state %d flag %lu opened %u",
|
||||
epfile->name, epfile->ffs->state, epfile->ffs->setup_state,
|
||||
epfile->ffs->flags, atomic_read(&epfile->opened));
|
||||
|
||||
if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
|
||||
return -ENODEV;
|
||||
|
||||
file->private_data = epfile;
|
||||
ffs_data_opened(epfile->ffs);
|
||||
atomic_inc(&epfile->opened);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1395,9 +1407,12 @@ ffs_epfile_release(struct inode *inode, struct file *file)
|
|||
ENTER();
|
||||
|
||||
__ffs_epfile_read_buffer_free(epfile);
|
||||
ffs_log("%s: state %d setup_state %d flag %lu", epfile->name,
|
||||
epfile->ffs->state, epfile->ffs->setup_state,
|
||||
epfile->ffs->flags);
|
||||
ffs_log("%s: state %d setup_state %d flag %lu opened %u",
|
||||
epfile->name, epfile->ffs->state, epfile->ffs->setup_state,
|
||||
epfile->ffs->flags, atomic_read(&epfile->opened));
|
||||
|
||||
if (atomic_dec_and_test(&epfile->opened))
|
||||
epfile->invalid = false;
|
||||
|
||||
ffs_data_closed(epfile->ffs);
|
||||
|
||||
|
|
@ -1427,6 +1442,10 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
|
|||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
/* don't allow any I/O until file is reopened */
|
||||
if (epfile->invalid)
|
||||
return -ENODEV;
|
||||
|
||||
ret = wait_event_interruptible(
|
||||
epfile->ffs->wait, (ep = epfile->ep));
|
||||
if (ret)
|
||||
|
|
@ -2091,6 +2110,8 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
|
|||
ffs_epfiles_destroy(epfiles, i - 1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
atomic_set(&epfile->opened, 0);
|
||||
}
|
||||
|
||||
ffs->epfiles = epfiles;
|
||||
|
|
@ -2137,6 +2158,7 @@ static void ffs_func_eps_disable(struct ffs_function *func)
|
|||
++ep;
|
||||
|
||||
if (epfile) {
|
||||
epfile->invalid = true; /* until file is reopened */
|
||||
epfile->ep = NULL;
|
||||
__ffs_epfile_read_buffer_free(epfile);
|
||||
++epfile;
|
||||
|
|
@ -3539,8 +3561,10 @@ static int ffs_func_set_alt(struct usb_function *f,
|
|||
return intf;
|
||||
}
|
||||
|
||||
if (ffs->func)
|
||||
if (ffs->func) {
|
||||
ffs_func_eps_disable(ffs->func);
|
||||
ffs->func = NULL;
|
||||
}
|
||||
|
||||
if (ffs->state == FFS_DEACTIVATED) {
|
||||
ffs->state = FFS_CLOSING;
|
||||
|
|
|
|||
Loading…
Reference in a new issue