提交 201ce859 编写于 作者: T Tejun Heo 提交者: Jeff Garzik

[PATCH] sata_sil: disable hotplug interrupts on two ATI IXPs

Some SATA controllers embedded in ATI IXPs seem to have broken
SATA_IRQ bit in their bmdma2 registers which is always stuck at 1.
This makes the driver believe that there has been a hotplug event and
freeze the port whenever there's an interrupt thus failing all
commands.

This patch disables SATA_IRQ for those controllers.
Signed-off-by: NTejun Heo <htejun@gmail.com>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 88574551
...@@ -52,6 +52,7 @@ enum { ...@@ -52,6 +52,7 @@ enum {
/* /*
* host flags * host flags
*/ */
SIL_FLAG_NO_SATA_IRQ = (1 << 28),
SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29),
SIL_FLAG_MOD15WRITE = (1 << 30), SIL_FLAG_MOD15WRITE = (1 << 30),
...@@ -62,8 +63,9 @@ enum { ...@@ -62,8 +63,9 @@ enum {
* Controller IDs * Controller IDs
*/ */
sil_3112 = 0, sil_3112 = 0,
sil_3512 = 1, sil_3112_no_sata_irq = 1,
sil_3114 = 2, sil_3512 = 2,
sil_3114 = 3,
/* /*
* Register offsets * Register offsets
...@@ -123,8 +125,8 @@ static const struct pci_device_id sil_pci_tbl[] = { ...@@ -123,8 +125,8 @@ static const struct pci_device_id sil_pci_tbl[] = {
{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 },
{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
{ 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq },
{ } /* terminate list */ { } /* terminate list */
}; };
...@@ -217,6 +219,16 @@ static const struct ata_port_info sil_port_info[] = { ...@@ -217,6 +219,16 @@ static const struct ata_port_info sil_port_info[] = {
.udma_mask = 0x3f, /* udma0-5 */ .udma_mask = 0x3f, /* udma0-5 */
.port_ops = &sil_ops, .port_ops = &sil_ops,
}, },
/* sil_3112_no_sata_irq */
{
.sht = &sil_sht,
.host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE |
SIL_FLAG_NO_SATA_IRQ,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x3f, /* udma0-5 */
.port_ops = &sil_ops,
},
/* sil_3512 */ /* sil_3512 */
{ {
.sht = &sil_sht, .sht = &sil_sht,
...@@ -437,6 +449,10 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance, ...@@ -437,6 +449,10 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance,
if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED))
continue; continue;
/* turn off SATA_IRQ if not supported */
if (ap->flags & SIL_FLAG_NO_SATA_IRQ)
bmdma2 &= ~SIL_DMA_SATA_IRQ;
if (bmdma2 == 0xffffffff || if (bmdma2 == 0xffffffff ||
!(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ))) !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ)))
continue; continue;
...@@ -474,8 +490,9 @@ static void sil_thaw(struct ata_port *ap) ...@@ -474,8 +490,9 @@ static void sil_thaw(struct ata_port *ap)
ata_chk_status(ap); ata_chk_status(ap);
ata_bmdma_irq_clear(ap); ata_bmdma_irq_clear(ap);
/* turn on SATA IRQ */ /* turn on SATA IRQ if supported */
writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))
writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien);
/* turn on IRQ */ /* turn on IRQ */
tmp = readl(mmio_base + SIL_SYSCFG); tmp = readl(mmio_base + SIL_SYSCFG);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册