]> err.no Git - linux-2.6/blobdiff - drivers/scsi/sata_sil.c
[PATCH] md: Set/get state of array via sysfs
[linux-2.6] / drivers / scsi / sata_sil.c
index 0898cbe6458c89f507c848e6c56e7eb7a152ec0c..bc9f918a7f286e2e07690cc5e64ec3376fd58aa3 100644 (file)
@@ -344,7 +344,25 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
        u8 status;
 
        if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
-               ata_ehi_hotplugged(&ap->eh_info);
+               u32 serror;
+
+               /* SIEN doesn't mask SATA IRQs on some 3112s.  Those
+                * controllers continue to assert IRQ as long as
+                * SError bits are pending.  Clear SError immediately.
+                */
+               serror = sil_scr_read(ap, SCR_ERROR);
+               sil_scr_write(ap, SCR_ERROR, serror);
+
+               /* Trigger hotplug and accumulate SError only if the
+                * port isn't already frozen.  Otherwise, PHY events
+                * during hardreset makes controllers with broken SIEN
+                * repeat probing needlessly.
+                */
+               if (!(ap->flags & ATA_FLAG_FROZEN)) {
+                       ata_ehi_hotplugged(&ap->eh_info);
+                       ap->eh_info.serror |= serror;
+               }
+
                goto freeze;
        }
 
@@ -419,7 +437,8 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance,
                if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED))
                        continue;
 
-               if (!(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ)))
+               if (bmdma2 == 0xffffffff ||
+                   !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ)))
                        continue;
 
                sil_host_intr(ap, bmdma2);