Skip to content

Commit

Permalink
firewire: ohci: access bus_seconds atomically
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefan Richter committed Jun 5, 2009
1 parent e41f8d7 commit 3dcdc50
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions drivers/firewire/fw-ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>

#include <asm/atomic.h>
#include <asm/page.h>
#include <asm/system.h>

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 3dcdc50

Please sign in to comment.