3232#include <linux/kernel.h>
3333#include <linux/module.h>
3434#include <linux/uaccess.h>
35+ #include <linux/uio.h>
3536#include <drm/drm_dp_helper.h>
3637#include <drm/drm_crtc.h>
3738#include <drm/drmP.h>
@@ -140,101 +141,83 @@ static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
140141 return fixed_size_llseek (file , offset , whence , AUX_MAX_OFFSET );
141142}
142143
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 )
145145{
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 ;
148148 ssize_t res = 0 ;
149149
150150 if (!atomic_inc_not_zero (& aux_dev -> usecount ))
151151 return - ENODEV ;
152152
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 );
159154
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 ));
163158
164159 if (signal_pending (current )) {
165- res = num_bytes_processed ?
166- num_bytes_processed : - ERESTARTSYS ;
167- goto out ;
160+ res = - ERESTARTSYS ;
161+ break ;
168162 }
169163
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 ;
179171 }
180- bytes_pending -= res ;
181- * offset += res ;
182- num_bytes_processed += res ;
183- res = num_bytes_processed ;
172+
173+ pos += res ;
184174 }
185175
186- out :
176+ if (pos != iocb -> ki_pos )
177+ res = pos - iocb -> ki_pos ;
178+ iocb -> ki_pos = pos ;
179+
187180 atomic_dec (& aux_dev -> usecount );
188181 wake_up_atomic_t (& aux_dev -> usecount );
189182 return res ;
190183}
191184
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 )
194186{
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 ;
197189 ssize_t res = 0 ;
198190
199191 if (!atomic_inc_not_zero (& aux_dev -> usecount ))
200192 return - ENODEV ;
201193
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 );
208195
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 ));
212199
213200 if (signal_pending (current )) {
214- res = num_bytes_processed ?
215- num_bytes_processed : - ERESTARTSYS ;
216- goto out ;
201+ res = - ERESTARTSYS ;
202+ break ;
217203 }
218204
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 ;
224208 }
225209
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 ;
235215 }
236216
237- out :
217+ if (pos != iocb -> ki_pos )
218+ res = pos - iocb -> ki_pos ;
219+ iocb -> ki_pos = pos ;
220+
238221 atomic_dec (& aux_dev -> usecount );
239222 wake_up_atomic_t (& aux_dev -> usecount );
240223 return res ;
@@ -251,8 +234,8 @@ static int auxdev_release(struct inode *inode, struct file *file)
251234static const struct file_operations auxdev_fops = {
252235 .owner = THIS_MODULE ,
253236 .llseek = auxdev_llseek ,
254- .read = auxdev_read ,
255- .write = auxdev_write ,
237+ .read_iter = auxdev_read_iter ,
238+ .write_iter = auxdev_write_iter ,
256239 .open = auxdev_open ,
257240 .release = auxdev_release ,
258241};
0 commit comments