aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-ohci.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-04 15:08:43 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-05 10:26:17 -0400
commit3dcdc50079bc2c9dbc6524518976353f743f7ec8 (patch)
treeec620a55e21631efee6622f12338fae59b41d1ae /drivers/firewire/fw-ohci.c
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>
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-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 1180d0be0bb4..1b6590f92543 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -31,6 +31,7 @@
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33 33
34#include <asm/atomic.h>
34#include <asm/page.h> 35#include <asm/page.h>
35#include <asm/system.h> 36#include <asm/system.h>
36 37
@@ -178,7 +179,7 @@ struct fw_ohci {
178 int node_id; 179 int node_id;
179 int generation; 180 int generation;
180 int request_generation; /* for timestamping incoming requests */ 181 int request_generation; /* for timestamping incoming requests */
181 u32 bus_seconds; 182 atomic_t bus_seconds;
182 183
183 bool use_dualbuffer; 184 bool use_dualbuffer;
184 bool old_uninorth; 185 bool old_uninorth;
@@ -1434,7 +1435,7 @@ static irqreturn_t irq_handler(int irq, void *data)
1434 if (event & OHCI1394_cycle64Seconds) { 1435 if (event & OHCI1394_cycle64Seconds) {
1435 cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); 1436 cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
1436 if ((cycle_time & 0x80000000) == 0) 1437 if ((cycle_time & 0x80000000) == 0)
1437 ohci->bus_seconds++; 1438 atomic_inc(&ohci->bus_seconds);
1438 } 1439 }
1439 1440
1440 return IRQ_HANDLED; 1441 return IRQ_HANDLED;
@@ -1770,7 +1771,7 @@ static u64 ohci_get_bus_time(struct fw_card *card)
1770 u64 bus_time; 1771 u64 bus_time;
1771 1772
1772 cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); 1773 cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
1773 bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time; 1774 bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time;
1774 1775
1775 return bus_time; 1776 return bus_time;
1776} 1777}