aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-06-12 05:45:55 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-12 09:37:21 -0400
commitd4c85325a817d3351e61c4be64b437116e8483b4 (patch)
tree6a97a2e92a3068782cca7d139456e695c82935ec
parentaeb2ecd6096182cc080d37679080c0f088dcd4a4 (diff)
[PATCH] sata_sil: update device hotplug handling, take #2
SIEN on some 3112 controllers doesn't mask SATA IRQ properly. IRQ stays asserted even after SIEN is masked and IRQ is acked. Also, even while frozen, any SATA PHY event including hardreset raises SATA IRQ. Clearing SError seems to be the only way to deassert SATA IRQ. This patch makes sil_host_intr() clear SError on SATA IRQs and ignore SATA IRQs reported while frozen so that hardreset doesn't trigger hotplug event (which ends up hardresetting again). In such cases, the port still gets re-frozen to minimize the danger of screaming interrupts. This results in one nil EH repeat on controllers with broken SIEN but other than that does no harm. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/scsi/sata_sil.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index a7e99a1def2f..bc9f918a7f28 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -344,7 +344,25 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
344 u8 status; 344 u8 status;
345 345
346 if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) { 346 if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
347 ata_ehi_hotplugged(&ap->eh_info); 347 u32 serror;
348
349 /* SIEN doesn't mask SATA IRQs on some 3112s. Those
350 * controllers continue to assert IRQ as long as
351 * SError bits are pending. Clear SError immediately.
352 */
353 serror = sil_scr_read(ap, SCR_ERROR);
354 sil_scr_write(ap, SCR_ERROR, serror);
355
356 /* Trigger hotplug and accumulate SError only if the
357 * port isn't already frozen. Otherwise, PHY events
358 * during hardreset makes controllers with broken SIEN
359 * repeat probing needlessly.
360 */
361 if (!(ap->flags & ATA_FLAG_FROZEN)) {
362 ata_ehi_hotplugged(&ap->eh_info);
363 ap->eh_info.serror |= serror;
364 }
365
348 goto freeze; 366 goto freeze;
349 } 367 }
350 368