Skip to content

Commit

Permalink
Merge branch 'for-linus' of ssh://master.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/ieee1394/linux1394-2.6

* 'for-linus' of ssh://master.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  ieee1394: fix another deadlock in nodemgr
  ieee1394: cycle timer read extension for raw1394
  • Loading branch information
Linus Torvalds committed Feb 19, 2007
2 parents 5c56f46 + a65421e commit 920841d
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 1 deletion.
2 changes: 2 additions & 0 deletions drivers/ieee1394/ieee1394-ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,7 @@
_IO ('#', 0x28)
#define RAW1394_IOC_ISO_RECV_FLUSH \
_IO ('#', 0x29)
#define RAW1394_IOC_GET_CYCLE_TIMER \
_IOR ('#', 0x30, struct raw1394_cycle_timer)

#endif /* __IEEE1394_IOCTL_H */
43 changes: 43 additions & 0 deletions drivers/ieee1394/ieee1394_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
#include <linux/skbuff.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
#include <linux/preempt.h>
#include <linux/time.h>

#include <asm/system.h>
#include <asm/byteorder.h>

#include "ieee1394_types.h"
Expand Down Expand Up @@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *host, int type)
}
}

/**
* hpsb_read_cycle_timer - read cycle timer register and system time
* @host: host whose isochronous cycle timer register is read
* @cycle_timer: address of bitfield to return the register contents
* @local_time: address to return the system time
*
* The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
* format is also read from non-OHCI controllers. * @local_time contains the
* system time in microseconds since the Epoch, read at the moment when the
* cycle timer was read.
*
* Return value: 0 for success or error number otherwise.
*/
int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
u64 *local_time)
{
int ctr;
struct timeval tv;
unsigned long flags;

if (!host || !cycle_timer || !local_time)
return -EINVAL;

preempt_disable();
local_irq_save(flags);

ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
if (ctr)
do_gettimeofday(&tv);

local_irq_restore(flags);
preempt_enable();

if (!ctr)
return -EIO;
*cycle_timer = ctr;
*local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
return 0;
}

int hpsb_bus_reset(struct hpsb_host *host)
{
Expand Down Expand Up @@ -1190,6 +1232,7 @@ EXPORT_SYMBOL(hpsb_alloc_packet);
EXPORT_SYMBOL(hpsb_free_packet);
EXPORT_SYMBOL(hpsb_send_packet);
EXPORT_SYMBOL(hpsb_reset_bus);
EXPORT_SYMBOL(hpsb_read_cycle_timer);
EXPORT_SYMBOL(hpsb_bus_reset);
EXPORT_SYMBOL(hpsb_selfid_received);
EXPORT_SYMBOL(hpsb_selfid_complete);
Expand Down
3 changes: 3 additions & 0 deletions drivers/ieee1394/ieee1394_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ int hpsb_send_packet_and_wait(struct hpsb_packet *packet);
* progress, 0 otherwise. */
int hpsb_reset_bus(struct hpsb_host *host, int type);

int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
u64 *local_time);

/*
* The following functions are exported for host driver module usage. All of
* them are safe to use in interrupt contexts, although some are quite
Expand Down
3 changes: 2 additions & 1 deletion drivers/ieee1394/nodemgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,8 @@ static int nodemgr_host_thread(void *__hi)
for (;;) {
/* Sleep until next bus reset */
set_current_state(TASK_INTERRUPTIBLE);
if (get_hpsb_generation(host) == generation)
if (get_hpsb_generation(host) == generation &&
!kthread_should_stop())
schedule();
__set_current_state(TASK_RUNNING);

Expand Down
20 changes: 20 additions & 0 deletions drivers/ieee1394/raw1394.c
Original file line number Diff line number Diff line change
Expand Up @@ -2669,6 +2669,18 @@ static void raw1394_iso_shutdown(struct file_info *fi)
fi->iso_state = RAW1394_ISO_INACTIVE;
}

static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
{
struct raw1394_cycle_timer ct;
int err;

err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
if (!err)
if (copy_to_user(uaddr, &ct, sizeof(ct)))
err = -EFAULT;
return err;
}

/* mmap the rawiso xmit/recv buffer */
static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
{
Expand Down Expand Up @@ -2777,6 +2789,14 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
break;
}

/* state-independent commands */
switch(cmd) {
case RAW1394_IOC_GET_CYCLE_TIMER:
return raw1394_read_cycle_timer(fi, argp);
default:
break;
}

return -EINVAL;
}

Expand Down
10 changes: 10 additions & 0 deletions drivers/ieee1394/raw1394.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,14 @@ struct raw1394_iso_status {
__s16 xmit_cycle;
};

/* argument to RAW1394_IOC_GET_CYCLE_TIMER ioctl */
struct raw1394_cycle_timer {
/* contents of Isochronous Cycle Timer register,
as in OHCI 1.1 clause 5.13 (also with non-OHCI hosts) */
__u32 cycle_timer;

/* local time in microseconds since Epoch,
simultaneously read with cycle timer */
__u64 local_time;
};
#endif /* IEEE1394_RAW1394_H */

0 comments on commit 920841d

Please sign in to comment.