diff options
-rw-r--r-- | drivers/ieee1394/ieee1394-ioctl.h | 2 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 43 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.h | 3 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.c | 20 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.h | 10 |
5 files changed, 78 insertions, 0 deletions
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h index 8f207508ed1d..46878fef136c 100644 --- a/drivers/ieee1394/ieee1394-ioctl.h +++ b/drivers/ieee1394/ieee1394-ioctl.h | |||
@@ -100,5 +100,7 @@ | |||
100 | _IO ('#', 0x28) | 100 | _IO ('#', 0x28) |
101 | #define RAW1394_IOC_ISO_RECV_FLUSH \ | 101 | #define RAW1394_IOC_ISO_RECV_FLUSH \ |
102 | _IO ('#', 0x29) | 102 | _IO ('#', 0x29) |
103 | #define RAW1394_IOC_GET_CYCLE_TIMER \ | ||
104 | _IOR ('#', 0x30, struct raw1394_cycle_timer) | ||
103 | 105 | ||
104 | #endif /* __IEEE1394_IOCTL_H */ | 106 | #endif /* __IEEE1394_IOCTL_H */ |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1521e57e124b..d791d08c743c 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -33,7 +33,10 @@ | |||
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <linux/suspend.h> | 34 | #include <linux/suspend.h> |
35 | #include <linux/kthread.h> | 35 | #include <linux/kthread.h> |
36 | #include <linux/preempt.h> | ||
37 | #include <linux/time.h> | ||
36 | 38 | ||
39 | #include <asm/system.h> | ||
37 | #include <asm/byteorder.h> | 40 | #include <asm/byteorder.h> |
38 | 41 | ||
39 | #include "ieee1394_types.h" | 42 | #include "ieee1394_types.h" |
@@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *host, int type) | |||
186 | } | 189 | } |
187 | } | 190 | } |
188 | 191 | ||
192 | /** | ||
193 | * hpsb_read_cycle_timer - read cycle timer register and system time | ||
194 | * @host: host whose isochronous cycle timer register is read | ||
195 | * @cycle_timer: address of bitfield to return the register contents | ||
196 | * @local_time: address to return the system time | ||
197 | * | ||
198 | * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This | ||
199 | * format is also read from non-OHCI controllers. * @local_time contains the | ||
200 | * system time in microseconds since the Epoch, read at the moment when the | ||
201 | * cycle timer was read. | ||
202 | * | ||
203 | * Return value: 0 for success or error number otherwise. | ||
204 | */ | ||
205 | int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer, | ||
206 | u64 *local_time) | ||
207 | { | ||
208 | int ctr; | ||
209 | struct timeval tv; | ||
210 | unsigned long flags; | ||
211 | |||
212 | if (!host || !cycle_timer || !local_time) | ||
213 | return -EINVAL; | ||
214 | |||
215 | preempt_disable(); | ||
216 | local_irq_save(flags); | ||
217 | |||
218 | ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0); | ||
219 | if (ctr) | ||
220 | do_gettimeofday(&tv); | ||
221 | |||
222 | local_irq_restore(flags); | ||
223 | preempt_enable(); | ||
224 | |||
225 | if (!ctr) | ||
226 | return -EIO; | ||
227 | *cycle_timer = ctr; | ||
228 | *local_time = tv.tv_sec * 1000000ULL + tv.tv_usec; | ||
229 | return 0; | ||
230 | } | ||
189 | 231 | ||
190 | int hpsb_bus_reset(struct hpsb_host *host) | 232 | int hpsb_bus_reset(struct hpsb_host *host) |
191 | { | 233 | { |
@@ -1190,6 +1232,7 @@ EXPORT_SYMBOL(hpsb_alloc_packet); | |||
1190 | EXPORT_SYMBOL(hpsb_free_packet); | 1232 | EXPORT_SYMBOL(hpsb_free_packet); |
1191 | EXPORT_SYMBOL(hpsb_send_packet); | 1233 | EXPORT_SYMBOL(hpsb_send_packet); |
1192 | EXPORT_SYMBOL(hpsb_reset_bus); | 1234 | EXPORT_SYMBOL(hpsb_reset_bus); |
1235 | EXPORT_SYMBOL(hpsb_read_cycle_timer); | ||
1193 | EXPORT_SYMBOL(hpsb_bus_reset); | 1236 | EXPORT_SYMBOL(hpsb_bus_reset); |
1194 | EXPORT_SYMBOL(hpsb_selfid_received); | 1237 | EXPORT_SYMBOL(hpsb_selfid_received); |
1195 | EXPORT_SYMBOL(hpsb_selfid_complete); | 1238 | EXPORT_SYMBOL(hpsb_selfid_complete); |
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index 536ba3f580fd..bd29d8ef5bbd 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h | |||
@@ -127,6 +127,9 @@ int hpsb_send_packet_and_wait(struct hpsb_packet *packet); | |||
127 | * progress, 0 otherwise. */ | 127 | * progress, 0 otherwise. */ |
128 | int hpsb_reset_bus(struct hpsb_host *host, int type); | 128 | int hpsb_reset_bus(struct hpsb_host *host, int type); |
129 | 129 | ||
130 | int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer, | ||
131 | u64 *local_time); | ||
132 | |||
130 | /* | 133 | /* |
131 | * The following functions are exported for host driver module usage. All of | 134 | * The following functions are exported for host driver module usage. All of |
132 | * them are safe to use in interrupt contexts, although some are quite | 135 | * them are safe to use in interrupt contexts, although some are quite |
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index a77a832828c8..5d08d7450f96 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -2669,6 +2669,18 @@ static void raw1394_iso_shutdown(struct file_info *fi) | |||
2669 | fi->iso_state = RAW1394_ISO_INACTIVE; | 2669 | fi->iso_state = RAW1394_ISO_INACTIVE; |
2670 | } | 2670 | } |
2671 | 2671 | ||
2672 | static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr) | ||
2673 | { | ||
2674 | struct raw1394_cycle_timer ct; | ||
2675 | int err; | ||
2676 | |||
2677 | err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); | ||
2678 | if (!err) | ||
2679 | if (copy_to_user(uaddr, &ct, sizeof(ct))) | ||
2680 | err = -EFAULT; | ||
2681 | return err; | ||
2682 | } | ||
2683 | |||
2672 | /* mmap the rawiso xmit/recv buffer */ | 2684 | /* mmap the rawiso xmit/recv buffer */ |
2673 | static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) | 2685 | static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) |
2674 | { | 2686 | { |
@@ -2777,6 +2789,14 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, | |||
2777 | break; | 2789 | break; |
2778 | } | 2790 | } |
2779 | 2791 | ||
2792 | /* state-independent commands */ | ||
2793 | switch(cmd) { | ||
2794 | case RAW1394_IOC_GET_CYCLE_TIMER: | ||
2795 | return raw1394_read_cycle_timer(fi, argp); | ||
2796 | default: | ||
2797 | break; | ||
2798 | } | ||
2799 | |||
2780 | return -EINVAL; | 2800 | return -EINVAL; |
2781 | } | 2801 | } |
2782 | 2802 | ||
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h index 35bfc38f013c..7bd22ee1afbb 100644 --- a/drivers/ieee1394/raw1394.h +++ b/drivers/ieee1394/raw1394.h | |||
@@ -178,4 +178,14 @@ struct raw1394_iso_status { | |||
178 | __s16 xmit_cycle; | 178 | __s16 xmit_cycle; |
179 | }; | 179 | }; |
180 | 180 | ||
181 | /* argument to RAW1394_IOC_GET_CYCLE_TIMER ioctl */ | ||
182 | struct raw1394_cycle_timer { | ||
183 | /* contents of Isochronous Cycle Timer register, | ||
184 | as in OHCI 1.1 clause 5.13 (also with non-OHCI hosts) */ | ||
185 | __u32 cycle_timer; | ||
186 | |||
187 | /* local time in microseconds since Epoch, | ||
188 | simultaneously read with cycle timer */ | ||
189 | __u64 local_time; | ||
190 | }; | ||
181 | #endif /* IEEE1394_RAW1394_H */ | 191 | #endif /* IEEE1394_RAW1394_H */ |