@@ -37,7 +37,7 @@ static void timeout_work(struct work_struct *work)
37
37
struct file_priv * priv = container_of (work , struct file_priv , work );
38
38
39
39
mutex_lock (& priv -> buffer_mutex );
40
- atomic_set ( & priv -> data_pending , 0 ) ;
40
+ priv -> data_pending = 0 ;
41
41
memset (priv -> data_buffer , 0 , sizeof (priv -> data_buffer ));
42
42
mutex_unlock (& priv -> buffer_mutex );
43
43
}
@@ -46,7 +46,6 @@ void tpm_common_open(struct file *file, struct tpm_chip *chip,
46
46
struct file_priv * priv )
47
47
{
48
48
priv -> chip = chip ;
49
- atomic_set (& priv -> data_pending , 0 );
50
49
mutex_init (& priv -> buffer_mutex );
51
50
timer_setup (& priv -> user_read_timer , user_reader_timeout , 0 );
52
51
INIT_WORK (& priv -> work , timeout_work );
@@ -58,29 +57,24 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
58
57
size_t size , loff_t * off )
59
58
{
60
59
struct file_priv * priv = file -> private_data ;
61
- ssize_t ret_size ;
62
- ssize_t orig_ret_size ;
60
+ ssize_t ret_size = 0 ;
63
61
int rc ;
64
62
65
63
del_singleshot_timer_sync (& priv -> user_read_timer );
66
64
flush_work (& priv -> work );
67
- ret_size = atomic_read (& priv -> data_pending );
68
- if (ret_size > 0 ) { /* relay data */
69
- orig_ret_size = ret_size ;
70
- if (size < ret_size )
71
- ret_size = size ;
65
+ mutex_lock (& priv -> buffer_mutex );
72
66
73
- mutex_lock (& priv -> buffer_mutex );
67
+ if (priv -> data_pending ) {
68
+ ret_size = min_t (ssize_t , size , priv -> data_pending );
74
69
rc = copy_to_user (buf , priv -> data_buffer , ret_size );
75
- memset (priv -> data_buffer , 0 , orig_ret_size );
70
+ memset (priv -> data_buffer , 0 , priv -> data_pending );
76
71
if (rc )
77
72
ret_size = - EFAULT ;
78
73
79
- mutex_unlock ( & priv -> buffer_mutex ) ;
74
+ priv -> data_pending = 0 ;
80
75
}
81
76
82
- atomic_set (& priv -> data_pending , 0 );
83
-
77
+ mutex_unlock (& priv -> buffer_mutex );
84
78
return ret_size ;
85
79
}
86
80
@@ -91,17 +85,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
91
85
size_t in_size = size ;
92
86
ssize_t out_size ;
93
87
88
+ if (in_size > TPM_BUFSIZE )
89
+ return - E2BIG ;
90
+
91
+ mutex_lock (& priv -> buffer_mutex );
92
+
94
93
/* Cannot perform a write until the read has cleared either via
95
94
* tpm_read or a user_read_timer timeout. This also prevents split
96
95
* buffered writes from blocking here.
97
96
*/
98
- if (atomic_read (& priv -> data_pending ) != 0 )
97
+ if (priv -> data_pending != 0 ) {
98
+ mutex_unlock (& priv -> buffer_mutex );
99
99
return - EBUSY ;
100
-
101
- if (in_size > TPM_BUFSIZE )
102
- return - E2BIG ;
103
-
104
- mutex_lock (& priv -> buffer_mutex );
100
+ }
105
101
106
102
if (copy_from_user
107
103
(priv -> data_buffer , (void __user * ) buf , in_size )) {
@@ -132,7 +128,7 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
132
128
return out_size ;
133
129
}
134
130
135
- atomic_set ( & priv -> data_pending , out_size ) ;
131
+ priv -> data_pending = out_size ;
136
132
mutex_unlock (& priv -> buffer_mutex );
137
133
138
134
/* Set a timeout by which the reader must come claim the result */
@@ -149,5 +145,5 @@ void tpm_common_release(struct file *file, struct file_priv *priv)
149
145
del_singleshot_timer_sync (& priv -> user_read_timer );
150
146
flush_work (& priv -> work );
151
147
file -> private_data = NULL ;
152
- atomic_set ( & priv -> data_pending , 0 ) ;
148
+ priv -> data_pending = 0 ;
153
149
}
0 commit comments