@@ -59,7 +59,6 @@ static struct ffs_data *__must_check ffs_data_new(const char *dev_name)
5959 __attribute__((malloc ));
6060
6161/* Opened counter handling. */
62- static void ffs_data_opened (struct ffs_data * ffs );
6362static void ffs_data_closed (struct ffs_data * ffs );
6463
6564/* Called with ffs->mutex held; take over ownership of data. */
@@ -636,23 +635,25 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf,
636635 return ret ;
637636}
638637
638+
639+ static void ffs_data_reset (struct ffs_data * ffs );
640+
639641static int ffs_ep0_open (struct inode * inode , struct file * file )
640642{
641643 struct ffs_data * ffs = inode -> i_sb -> s_fs_info ;
642- int ret ;
643644
644- /* Acquire mutex */
645- ret = ffs_mutex_lock (& ffs -> mutex , file -> f_flags & O_NONBLOCK );
646- if (ret < 0 )
647- return ret ;
648-
649- ffs_data_opened (ffs );
645+ spin_lock_irq (& ffs -> eps_lock );
650646 if (ffs -> state == FFS_CLOSING ) {
651- ffs_data_closed (ffs );
652- mutex_unlock (& ffs -> mutex );
647+ spin_unlock_irq (& ffs -> eps_lock );
653648 return - EBUSY ;
654649 }
655- mutex_unlock (& ffs -> mutex );
650+ if (!ffs -> opened ++ && ffs -> state == FFS_DEACTIVATED ) {
651+ ffs -> state = FFS_CLOSING ;
652+ spin_unlock_irq (& ffs -> eps_lock );
653+ ffs_data_reset (ffs );
654+ } else {
655+ spin_unlock_irq (& ffs -> eps_lock );
656+ }
656657 file -> private_data = ffs ;
657658
658659 return stream_open (inode , file );
@@ -1202,15 +1203,10 @@ ffs_epfile_open(struct inode *inode, struct file *file)
12021203{
12031204 struct ffs_data * ffs = inode -> i_sb -> s_fs_info ;
12041205 struct ffs_epfile * epfile ;
1205- int ret ;
1206-
1207- /* Acquire mutex */
1208- ret = ffs_mutex_lock (& ffs -> mutex , file -> f_flags & O_NONBLOCK );
1209- if (ret < 0 )
1210- return ret ;
12111206
1212- if (!atomic_inc_not_zero (& ffs -> opened )) {
1213- mutex_unlock (& ffs -> mutex );
1207+ spin_lock_irq (& ffs -> eps_lock );
1208+ if (!ffs -> opened ) {
1209+ spin_unlock_irq (& ffs -> eps_lock );
12141210 return - ENODEV ;
12151211 }
12161212 /*
@@ -1220,11 +1216,11 @@ ffs_epfile_open(struct inode *inode, struct file *file)
12201216 */
12211217 epfile = smp_load_acquire (& inode -> i_private );
12221218 if (unlikely (ffs -> state != FFS_ACTIVE || !epfile )) {
1223- mutex_unlock (& ffs -> mutex );
1224- ffs_data_closed (ffs );
1219+ spin_unlock_irq (& ffs -> eps_lock );
12251220 return - ENODEV ;
12261221 }
1227- mutex_unlock (& ffs -> mutex );
1222+ ffs -> opened ++ ;
1223+ spin_unlock_irq (& ffs -> eps_lock );
12281224
12291225 file -> private_data = epfile ;
12301226 return stream_open (inode , file );
@@ -2092,8 +2088,6 @@ static int ffs_fs_init_fs_context(struct fs_context *fc)
20922088 return 0 ;
20932089}
20942090
2095- static void ffs_data_reset (struct ffs_data * ffs );
2096-
20972091static void
20982092ffs_fs_kill_sb (struct super_block * sb )
20992093{
@@ -2150,15 +2144,6 @@ static void ffs_data_get(struct ffs_data *ffs)
21502144 refcount_inc (& ffs -> ref );
21512145}
21522146
2153- static void ffs_data_opened (struct ffs_data * ffs )
2154- {
2155- if (atomic_add_return (1 , & ffs -> opened ) == 1 &&
2156- ffs -> state == FFS_DEACTIVATED ) {
2157- ffs -> state = FFS_CLOSING ;
2158- ffs_data_reset (ffs );
2159- }
2160- }
2161-
21622147static void ffs_data_put (struct ffs_data * ffs )
21632148{
21642149 if (refcount_dec_and_test (& ffs -> ref )) {
@@ -2176,28 +2161,29 @@ static void ffs_data_put(struct ffs_data *ffs)
21762161
21772162static void ffs_data_closed (struct ffs_data * ffs )
21782163{
2179- if (atomic_dec_and_test (& ffs -> opened )) {
2180- if (ffs -> no_disconnect ) {
2181- struct ffs_epfile * epfiles ;
2182- unsigned long flags ;
2183-
2184- ffs -> state = FFS_DEACTIVATED ;
2185- spin_lock_irqsave (& ffs -> eps_lock , flags );
2186- epfiles = ffs -> epfiles ;
2187- ffs -> epfiles = NULL ;
2188- spin_unlock_irqrestore (& ffs -> eps_lock ,
2189- flags );
2190-
2191- if (epfiles )
2192- ffs_epfiles_destroy (ffs -> sb , epfiles ,
2193- ffs -> eps_count );
2194-
2195- if (ffs -> setup_state == FFS_SETUP_PENDING )
2196- __ffs_ep0_stall (ffs );
2197- } else {
2198- ffs -> state = FFS_CLOSING ;
2199- ffs_data_reset (ffs );
2200- }
2164+ spin_lock_irq (& ffs -> eps_lock );
2165+ if (-- ffs -> opened ) { // not the last opener?
2166+ spin_unlock_irq (& ffs -> eps_lock );
2167+ return ;
2168+ }
2169+ if (ffs -> no_disconnect ) {
2170+ struct ffs_epfile * epfiles ;
2171+
2172+ ffs -> state = FFS_DEACTIVATED ;
2173+ epfiles = ffs -> epfiles ;
2174+ ffs -> epfiles = NULL ;
2175+ spin_unlock_irq (& ffs -> eps_lock );
2176+
2177+ if (epfiles )
2178+ ffs_epfiles_destroy (ffs -> sb , epfiles ,
2179+ ffs -> eps_count );
2180+
2181+ if (ffs -> setup_state == FFS_SETUP_PENDING )
2182+ __ffs_ep0_stall (ffs );
2183+ } else {
2184+ ffs -> state = FFS_CLOSING ;
2185+ spin_unlock_irq (& ffs -> eps_lock );
2186+ ffs_data_reset (ffs );
22012187 }
22022188}
22032189
@@ -2214,7 +2200,7 @@ static struct ffs_data *ffs_data_new(const char *dev_name)
22142200 }
22152201
22162202 refcount_set (& ffs -> ref , 1 );
2217- atomic_set ( & ffs -> opened , 0 ) ;
2203+ ffs -> opened = 0 ;
22182204 ffs -> state = FFS_READ_DESCRIPTORS ;
22192205 mutex_init (& ffs -> mutex );
22202206 spin_lock_init (& ffs -> eps_lock );
@@ -2266,6 +2252,7 @@ static void ffs_data_reset(struct ffs_data *ffs)
22662252{
22672253 ffs_data_clear (ffs );
22682254
2255+ spin_lock_irq (& ffs -> eps_lock );
22692256 ffs -> raw_descs_data = NULL ;
22702257 ffs -> raw_descs = NULL ;
22712258 ffs -> raw_strings = NULL ;
@@ -2289,6 +2276,7 @@ static void ffs_data_reset(struct ffs_data *ffs)
22892276 ffs -> ms_os_descs_ext_prop_count = 0 ;
22902277 ffs -> ms_os_descs_ext_prop_name_len = 0 ;
22912278 ffs -> ms_os_descs_ext_prop_data_len = 0 ;
2279+ spin_unlock_irq (& ffs -> eps_lock );
22922280}
22932281
22942282
@@ -3756,6 +3744,7 @@ static int ffs_func_set_alt(struct usb_function *f,
37563744{
37573745 struct ffs_function * func = ffs_func_from_usb (f );
37583746 struct ffs_data * ffs = func -> ffs ;
3747+ unsigned long flags ;
37593748 int ret = 0 , intf ;
37603749
37613750 if (alt > MAX_ALT_SETTINGS )
@@ -3768,12 +3757,15 @@ static int ffs_func_set_alt(struct usb_function *f,
37683757 if (ffs -> func )
37693758 ffs_func_eps_disable (ffs -> func );
37703759
3760+ spin_lock_irqsave (& ffs -> eps_lock , flags );
37713761 if (ffs -> state == FFS_DEACTIVATED ) {
37723762 ffs -> state = FFS_CLOSING ;
3763+ spin_unlock_irqrestore (& ffs -> eps_lock , flags );
37733764 INIT_WORK (& ffs -> reset_work , ffs_reset_work );
37743765 schedule_work (& ffs -> reset_work );
37753766 return - ENODEV ;
37763767 }
3768+ spin_unlock_irqrestore (& ffs -> eps_lock , flags );
37773769
37783770 if (ffs -> state != FFS_ACTIVE )
37793771 return - ENODEV ;
@@ -3791,16 +3783,20 @@ static void ffs_func_disable(struct usb_function *f)
37913783{
37923784 struct ffs_function * func = ffs_func_from_usb (f );
37933785 struct ffs_data * ffs = func -> ffs ;
3786+ unsigned long flags ;
37943787
37953788 if (ffs -> func )
37963789 ffs_func_eps_disable (ffs -> func );
37973790
3791+ spin_lock_irqsave (& ffs -> eps_lock , flags );
37983792 if (ffs -> state == FFS_DEACTIVATED ) {
37993793 ffs -> state = FFS_CLOSING ;
3794+ spin_unlock_irqrestore (& ffs -> eps_lock , flags );
38003795 INIT_WORK (& ffs -> reset_work , ffs_reset_work );
38013796 schedule_work (& ffs -> reset_work );
38023797 return ;
38033798 }
3799+ spin_unlock_irqrestore (& ffs -> eps_lock , flags );
38043800
38053801 if (ffs -> state == FFS_ACTIVE ) {
38063802 ffs -> func = NULL ;
0 commit comments