@@ -64,6 +64,43 @@ static int pps_cdev_fasync(int fd, struct file *file, int on)
64
64
return fasync_helper (fd , file , on , & pps -> async_queue );
65
65
}
66
66
67
+ static int pps_cdev_pps_fetch (struct pps_device * pps , struct pps_fdata * fdata )
68
+ {
69
+ unsigned int ev = pps -> last_ev ;
70
+ int err = 0 ;
71
+
72
+ /* Manage the timeout */
73
+ if (fdata -> timeout .flags & PPS_TIME_INVALID )
74
+ err = wait_event_interruptible (pps -> queue ,
75
+ ev != pps -> last_ev );
76
+ else {
77
+ unsigned long ticks ;
78
+
79
+ dev_dbg (pps -> dev , "timeout %lld.%09d\n" ,
80
+ (long long ) fdata -> timeout .sec ,
81
+ fdata -> timeout .nsec );
82
+ ticks = fdata -> timeout .sec * HZ ;
83
+ ticks += fdata -> timeout .nsec / (NSEC_PER_SEC / HZ );
84
+
85
+ if (ticks != 0 ) {
86
+ err = wait_event_interruptible_timeout (
87
+ pps -> queue ,
88
+ ev != pps -> last_ev ,
89
+ ticks );
90
+ if (err == 0 )
91
+ return - ETIMEDOUT ;
92
+ }
93
+ }
94
+
95
+ /* Check for pending signals */
96
+ if (err == - ERESTARTSYS ) {
97
+ dev_dbg (pps -> dev , "pending signal caught\n" );
98
+ return - EINTR ;
99
+ }
100
+
101
+ return 0 ;
102
+ }
103
+
67
104
static long pps_cdev_ioctl (struct file * file ,
68
105
unsigned int cmd , unsigned long arg )
69
106
{
@@ -144,44 +181,16 @@ static long pps_cdev_ioctl(struct file *file,
144
181
145
182
case PPS_FETCH : {
146
183
struct pps_fdata fdata ;
147
- unsigned int ev ;
148
184
149
185
dev_dbg (pps -> dev , "PPS_FETCH\n" );
150
186
151
187
err = copy_from_user (& fdata , uarg , sizeof (struct pps_fdata ));
152
188
if (err )
153
189
return - EFAULT ;
154
190
155
- ev = pps -> last_ev ;
156
-
157
- /* Manage the timeout */
158
- if (fdata .timeout .flags & PPS_TIME_INVALID )
159
- err = wait_event_interruptible (pps -> queue ,
160
- ev != pps -> last_ev );
161
- else {
162
- unsigned long ticks ;
163
-
164
- dev_dbg (pps -> dev , "timeout %lld.%09d\n" ,
165
- (long long ) fdata .timeout .sec ,
166
- fdata .timeout .nsec );
167
- ticks = fdata .timeout .sec * HZ ;
168
- ticks += fdata .timeout .nsec / (NSEC_PER_SEC / HZ );
169
-
170
- if (ticks != 0 ) {
171
- err = wait_event_interruptible_timeout (
172
- pps -> queue ,
173
- ev != pps -> last_ev ,
174
- ticks );
175
- if (err == 0 )
176
- return - ETIMEDOUT ;
177
- }
178
- }
179
-
180
- /* Check for pending signals */
181
- if (err == - ERESTARTSYS ) {
182
- dev_dbg (pps -> dev , "pending signal caught\n" );
183
- return - EINTR ;
184
- }
191
+ err = pps_cdev_pps_fetch (pps , & fdata );
192
+ if (err )
193
+ return err ;
185
194
186
195
/* Return the fetched timestamp */
187
196
spin_lock_irq (& pps -> lock );
@@ -246,8 +255,47 @@ static long pps_cdev_ioctl(struct file *file,
246
255
static long pps_cdev_compat_ioctl (struct file * file ,
247
256
unsigned int cmd , unsigned long arg )
248
257
{
258
+ struct pps_device * pps = file -> private_data ;
259
+ void __user * uarg = (void __user * ) arg ;
260
+
249
261
cmd = _IOC (_IOC_DIR (cmd ), _IOC_TYPE (cmd ), _IOC_NR (cmd ), sizeof (void * ));
250
262
263
+ if (cmd == PPS_FETCH ) {
264
+ struct pps_fdata_compat compat ;
265
+ struct pps_fdata fdata ;
266
+ int err ;
267
+
268
+ dev_dbg (pps -> dev , "PPS_FETCH\n" );
269
+
270
+ err = copy_from_user (& compat , uarg , sizeof (struct pps_fdata_compat ));
271
+ if (err )
272
+ return - EFAULT ;
273
+
274
+ memcpy (& fdata .timeout , & compat .timeout ,
275
+ sizeof (struct pps_ktime_compat ));
276
+
277
+ err = pps_cdev_pps_fetch (pps , & fdata );
278
+ if (err )
279
+ return err ;
280
+
281
+ /* Return the fetched timestamp */
282
+ spin_lock_irq (& pps -> lock );
283
+
284
+ compat .info .assert_sequence = pps -> assert_sequence ;
285
+ compat .info .clear_sequence = pps -> clear_sequence ;
286
+ compat .info .current_mode = pps -> current_mode ;
287
+
288
+ memcpy (& compat .info .assert_tu , & pps -> assert_tu ,
289
+ sizeof (struct pps_ktime_compat ));
290
+ memcpy (& compat .info .clear_tu , & pps -> clear_tu ,
291
+ sizeof (struct pps_ktime_compat ));
292
+
293
+ spin_unlock_irq (& pps -> lock );
294
+
295
+ return copy_to_user (uarg , & compat ,
296
+ sizeof (struct pps_fdata_compat )) ? - EFAULT : 0 ;
297
+ }
298
+
251
299
return pps_cdev_ioctl (file , cmd , arg );
252
300
}
253
301
#else
0 commit comments