summaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorClemens Ladisch2010-11-30 08:24:32 +0100
committerStefan Richter2010-12-13 20:39:14 +0100
commit8327b37b18addfc6f8cf41a2f1a4490b656377b9 (patch)
treeff9f3ccefccc5ab3b6bf0b5b7690af6a451230cc /drivers/firewire/ohci.c
parentfirewire: ohci: flush MMIO writes in the interrupt handler (diff)
downloadkernel-qcow2-linux-8327b37b18addfc6f8cf41a2f1a4490b656377b9.tar.gz
kernel-qcow2-linux-8327b37b18addfc6f8cf41a2f1a4490b656377b9.tar.xz
kernel-qcow2-linux-8327b37b18addfc6f8cf41a2f1a4490b656377b9.zip
firewire: ohci: properly clear posted write errors
To remove the error information from the controller's queue and to allow more posted writes, the driver has to read the failed posted write address before clearing the postedWriteErr interrupt bit. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> (Stefan R:) The spec is somewhat fuzzy about the actual requirements. To err on the safe side, let's do these two read accesses. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 276324d741df..0031ec6e1f00 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1790,8 +1790,12 @@ static irqreturn_t irq_handler(int irq, void *data)
if (!event || !~event)
return IRQ_NONE;
- /* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */
- reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
+ /*
+ * busReset and postedWriteErr must not be cleared yet
+ * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
+ */
+ reg_write(ohci, OHCI1394_IntEventClear,
+ event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
log_irqs(event);
if (event & OHCI1394_selfIDComplete)
@@ -1831,8 +1835,13 @@ static irqreturn_t irq_handler(int irq, void *data)
fw_error("Register access failure - "
"please notify linux1394-devel@lists.sf.net\n");
- if (unlikely(event & OHCI1394_postedWriteErr))
+ if (unlikely(event & OHCI1394_postedWriteErr)) {
+ reg_read(ohci, OHCI1394_PostedWriteAddressHi);
+ reg_read(ohci, OHCI1394_PostedWriteAddressLo);
+ reg_write(ohci, OHCI1394_IntEventClear,
+ OHCI1394_postedWriteErr);
fw_error("PCI posted write error\n");
+ }
if (unlikely(event & OHCI1394_cycleTooLong)) {
if (printk_ratelimit())