summaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorThomas Reitmayr <treitmayr@devbase.at>2009-01-24 22:24:58 +0300
committerJeff Garzik <jgarzik@redhat.com>2009-01-26 14:37:37 +0300
commit5d0fb2e730e2085021cf5c8b6d14983e92aea75b (patch)
tree2beeb862b227cde918199b1decbed6ddfab3bc51 /drivers/ata
parentcd12e1f7a2c28917c89d65c0d4a52d3919b4c125 (diff)
downloadlinux-5d0fb2e730e2085021cf5c8b6d14983e92aea75b.tar.xz
sata_mv: Properly initialize main irq mask
I noticed that during initialization sata_mv.c assumes that the main interrupt mask has its default value of 0. The function mv_platform_probe(..) initializes a shadow irq mask with 0 assuming that's the value of the controller's register. Now mv_set_main_irq_mask(..) only writes the controller's register if the new value differs from the "shadowed" value. This is fatal when trying to disable all interrupts in mv_init_host(..), i.e. the following function call does not write anything to the main irq mask register: mv_set_main_irq_mask(host, ~0, 0); The effect I see on my machine (QNAP TS-109 II) with booting via kexec (with Linux as a 2nd-stage boot loader) is that if the sata_mv module was still loaded when performing kexec, then the new kernel's sata_mv module starts up with interrupts enabled. This results in an unhandled IRQ and breaks the boot process. The unhandled interrupt itself might also be fixed by Lennert's patch proposed at http://markmail.org/message/kwvzxstnlsa3s26w which I did not try yet. However I still propose to additionally initialize the shadow variable with the current contents of the main irq mask register to get both in sync and allow proper disabling the main irq mask. This fixes the unhandled irq on my machine. Signed-off-by: Thomas Reitmayr <treitmayr@devbase.at> Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 874b60b2e20f..9e9fb9594781 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -3059,6 +3059,9 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
}
+ /* initialize shadow irq mask with register's value */
+ hpriv->main_irq_mask = readl(hpriv->main_irq_mask_addr);
+
/* global interrupt mask: 0 == mask everything */
mv_set_main_irq_mask(host, ~0, 0);