aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-04 21:08:43 +0200
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-05 16:26:17 +0200
commit3dcdc50079bc2c9dbc6524518976353f743f7ec8 (patch)
treeec620a55e21631efee6622f12338fae59b41d1ae
parente41f8d709c31b42129a34305a99d29c38aff75c4 (diff)
firewire: ohci: access bus_seconds atomically
In the unlikely event that card->driver->get_bus_time() is called during a cycle64Seconds interrupt, we could read garbage unless atomic accesses are used. The switch to atomic ops requires to change the 64 seconds counter from unsigned to signed, but this shouldn't matter to the end result. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/fw-ohci.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 1180d0be0bb..1b6590f9254 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
+#include <asm/atomic.h>
#include <asm/page.h>
#include <asm/system.h>
@@ -178,7 +179,7 @@ struct fw_ohci {
int node_id;
int generation;
int request_generation; /* for timestamping incoming requests */
- u32 bus_seconds;
+ atomic_t bus_seconds;
bool use_dualbuffer;
bool old_uninorth;
@@ -1434,7 +1435,7 @@ static irqreturn_t irq_handler(int irq, void *data)
if (event & OHCI1394_cycle64Seconds) {
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
if ((cycle_time & 0x80000000) == 0)
- ohci->bus_seconds++;
+ atomic_inc(&ohci->bus_seconds);
}
return IRQ_HANDLED;
@@ -1770,7 +1771,7 @@ static u64 ohci_get_bus_time(struct fw_card *card)
u64 bus_time;
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
- bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time;
+ bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time;
return bus_time;
}