32
32
#include <linux/kernel.h>
33
33
#include <linux/module.h>
34
34
#include <linux/uaccess.h>
35
+ #include <linux/uio.h>
35
36
#include <drm/drm_dp_helper.h>
36
37
#include <drm/drm_crtc.h>
37
38
#include <drm/drmP.h>
@@ -140,101 +141,83 @@ static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
140
141
return fixed_size_llseek (file , offset , whence , AUX_MAX_OFFSET );
141
142
}
142
143
143
- static ssize_t auxdev_read (struct file * file , char __user * buf , size_t count ,
144
- loff_t * offset )
144
+ static ssize_t auxdev_read_iter (struct kiocb * iocb , struct iov_iter * to )
145
145
{
146
- size_t bytes_pending , num_bytes_processed = 0 ;
147
- struct drm_dp_aux_dev * aux_dev = file -> private_data ;
146
+ struct drm_dp_aux_dev * aux_dev = iocb -> ki_filp -> private_data ;
147
+ loff_t pos = iocb -> ki_pos ;
148
148
ssize_t res = 0 ;
149
149
150
150
if (!atomic_inc_not_zero (& aux_dev -> usecount ))
151
151
return - ENODEV ;
152
152
153
- bytes_pending = min ((loff_t )count , AUX_MAX_OFFSET - (* offset ));
154
-
155
- if (!access_ok (VERIFY_WRITE , buf , bytes_pending )) {
156
- res = - EFAULT ;
157
- goto out ;
158
- }
153
+ iov_iter_truncate (to , AUX_MAX_OFFSET - pos );
159
154
160
- while (bytes_pending > 0 ) {
161
- uint8_t localbuf [DP_AUX_MAX_PAYLOAD_BYTES ];
162
- ssize_t todo = min_t ( size_t , bytes_pending , sizeof (localbuf ));
155
+ while (iov_iter_count ( to ) ) {
156
+ uint8_t buf [DP_AUX_MAX_PAYLOAD_BYTES ];
157
+ ssize_t todo = min ( iov_iter_count ( to ), sizeof (buf ));
163
158
164
159
if (signal_pending (current )) {
165
- res = num_bytes_processed ?
166
- num_bytes_processed : - ERESTARTSYS ;
167
- goto out ;
160
+ res = - ERESTARTSYS ;
161
+ break ;
168
162
}
169
163
170
- res = drm_dp_dpcd_read (aux_dev -> aux , * offset , localbuf , todo );
171
- if (res <= 0 ) {
172
- res = num_bytes_processed ? num_bytes_processed : res ;
173
- goto out ;
174
- }
175
- if (__copy_to_user (buf + num_bytes_processed , localbuf , res )) {
176
- res = num_bytes_processed ?
177
- num_bytes_processed : - EFAULT ;
178
- goto out ;
164
+ res = drm_dp_dpcd_read (aux_dev -> aux , pos , buf , todo );
165
+ if (res <= 0 )
166
+ break ;
167
+
168
+ if (copy_to_iter (buf , res , to ) != res ) {
169
+ res = - EFAULT ;
170
+ break ;
179
171
}
180
- bytes_pending -= res ;
181
- * offset += res ;
182
- num_bytes_processed += res ;
183
- res = num_bytes_processed ;
172
+
173
+ pos += res ;
184
174
}
185
175
186
- out :
176
+ if (pos != iocb -> ki_pos )
177
+ res = pos - iocb -> ki_pos ;
178
+ iocb -> ki_pos = pos ;
179
+
187
180
atomic_dec (& aux_dev -> usecount );
188
181
wake_up_atomic_t (& aux_dev -> usecount );
189
182
return res ;
190
183
}
191
184
192
- static ssize_t auxdev_write (struct file * file , const char __user * buf ,
193
- size_t count , loff_t * offset )
185
+ static ssize_t auxdev_write_iter (struct kiocb * iocb , struct iov_iter * from )
194
186
{
195
- size_t bytes_pending , num_bytes_processed = 0 ;
196
- struct drm_dp_aux_dev * aux_dev = file -> private_data ;
187
+ struct drm_dp_aux_dev * aux_dev = iocb -> ki_filp -> private_data ;
188
+ loff_t pos = iocb -> ki_pos ;
197
189
ssize_t res = 0 ;
198
190
199
191
if (!atomic_inc_not_zero (& aux_dev -> usecount ))
200
192
return - ENODEV ;
201
193
202
- bytes_pending = min ((loff_t )count , AUX_MAX_OFFSET - * offset );
203
-
204
- if (!access_ok (VERIFY_READ , buf , bytes_pending )) {
205
- res = - EFAULT ;
206
- goto out ;
207
- }
194
+ iov_iter_truncate (from , AUX_MAX_OFFSET - pos );
208
195
209
- while (bytes_pending > 0 ) {
210
- uint8_t localbuf [DP_AUX_MAX_PAYLOAD_BYTES ];
211
- ssize_t todo = min_t ( size_t , bytes_pending , sizeof (localbuf ));
196
+ while (iov_iter_count ( from ) ) {
197
+ uint8_t buf [DP_AUX_MAX_PAYLOAD_BYTES ];
198
+ ssize_t todo = min ( iov_iter_count ( from ), sizeof (buf ));
212
199
213
200
if (signal_pending (current )) {
214
- res = num_bytes_processed ?
215
- num_bytes_processed : - ERESTARTSYS ;
216
- goto out ;
201
+ res = - ERESTARTSYS ;
202
+ break ;
217
203
}
218
204
219
- if (__copy_from_user (localbuf ,
220
- buf + num_bytes_processed , todo )) {
221
- res = num_bytes_processed ?
222
- num_bytes_processed : - EFAULT ;
223
- goto out ;
205
+ if (!copy_from_iter_full (buf , todo , from )) {
206
+ res = - EFAULT ;
207
+ break ;
224
208
}
225
209
226
- res = drm_dp_dpcd_write (aux_dev -> aux , * offset , localbuf , todo );
227
- if (res <= 0 ) {
228
- res = num_bytes_processed ? num_bytes_processed : res ;
229
- goto out ;
230
- }
231
- bytes_pending -= res ;
232
- * offset += res ;
233
- num_bytes_processed += res ;
234
- res = num_bytes_processed ;
210
+ res = drm_dp_dpcd_write (aux_dev -> aux , pos , buf , todo );
211
+ if (res <= 0 )
212
+ break ;
213
+
214
+ pos += res ;
235
215
}
236
216
237
- out :
217
+ if (pos != iocb -> ki_pos )
218
+ res = pos - iocb -> ki_pos ;
219
+ iocb -> ki_pos = pos ;
220
+
238
221
atomic_dec (& aux_dev -> usecount );
239
222
wake_up_atomic_t (& aux_dev -> usecount );
240
223
return res ;
@@ -251,8 +234,8 @@ static int auxdev_release(struct inode *inode, struct file *file)
251
234
static const struct file_operations auxdev_fops = {
252
235
.owner = THIS_MODULE ,
253
236
.llseek = auxdev_llseek ,
254
- .read = auxdev_read ,
255
- .write = auxdev_write ,
237
+ .read_iter = auxdev_read_iter ,
238
+ .write_iter = auxdev_write_iter ,
256
239
.open = auxdev_open ,
257
240
.release = auxdev_release ,
258
241
};
0 commit comments