From 0ee304d5802dc62746f13f12d4cb4ec4ed285f66 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 25 Feb 2006 13:52:30 +0900 Subject: [PATCH] sata_sil: add board ID for 3512 3512 is slightly different from 3112 errata-wise. Differentiate it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/scsi/sata_sil.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/sata_sil.c') diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 17f74d3c10e7..510c2e0bd90e 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -53,7 +53,8 @@ enum { sil_3112 = 0, sil_3112_m15w = 1, - sil_3114 = 2, + sil_3512 = 2, + sil_3114 = 3, SIL_FIFO_R0 = 0x40, SIL_FIFO_W0 = 0x41, @@ -90,7 +91,7 @@ static void sil_post_set_mode (struct ata_port *ap); static const struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, - { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, @@ -185,7 +186,8 @@ static const struct ata_port_info sil_port_info[] = { .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, - }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ + }, + /* sil_3112_15w - keep it sync'd w/ sil_3112 */ { .sht = &sil_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | @@ -195,7 +197,18 @@ static const struct ata_port_info sil_port_info[] = { .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, - }, /* sil_3114 */ + }, + /* sil_3512 */ + { + .sht = &sil_sht, + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_SRST | ATA_FLAG_MMIO, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x3f, /* udma0-5 */ + .port_ops = &sil_ops, + }, + /* sil_3114 */ { .sht = &sil_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | -- cgit v1.2.3-59-g8ed1b From e4e10e3e7995f5bd481d2720bf30d3a661d110ca Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 25 Feb 2006 13:52:30 +0900 Subject: [PATCH] sata_sil: implement R_ERR on DMA activate FIS errata fix Silicon Image has disclosed a new sil3114/3152 errata and workaround which causes the controller to return R_ERR on DMA activate FIS if the FIS is received while the next PRD is being fetched. This patch implements the workaround. This errata results in lock up and doesn't trigger if m15w workaround is in effect. We stopped applying m15w to 3512 and 3114 in 2.6.14-rc1 which makes 3512/3114 lock up with some drives on all kernel versions since 2.6.14-rc1 upto now (2.6.16-rc4). This patch should fix the regression. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/scsi/sata_sil.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/sata_sil.c') diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 510c2e0bd90e..9face3c6aa21 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -49,6 +49,7 @@ #define DRV_VERSION "0.9" enum { + SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), sil_3112 = 0, @@ -202,7 +203,8 @@ static const struct ata_port_info sil_port_info[] = { { .sht = &sil_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + ATA_FLAG_SRST | ATA_FLAG_MMIO | + SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -212,7 +214,8 @@ static const struct ata_port_info sil_port_info[] = { { .sht = &sil_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + ATA_FLAG_SRST | ATA_FLAG_MMIO | + SIL_FLAG_RERR_ON_DMA_ACT, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ @@ -229,12 +232,13 @@ static const struct { unsigned long scr; /* SATA control register block */ unsigned long sien; /* SATA Interrupt Enable register */ unsigned long xfer_mode;/* data transfer mode register */ + unsigned long sfis_cfg; /* SATA FIS reception config register */ } sil_port[] = { /* port 0 ... */ - { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, - { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, - { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, - { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, + { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, + { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, + { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, + { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, /* ... port 3 */ }; @@ -484,6 +488,23 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_WARNING, &pdev->dev, "cache line size not set. Driver may not function\n"); + /* Apply R_ERR on DMA activate FIS errata workaround */ + if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { + int cnt; + + for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) { + tmp = readl(mmio_base + sil_port[i].sfis_cfg); + if ((tmp & 0x3) != 0x01) + continue; + if (!cnt) + dev_printk(KERN_INFO, &pdev->dev, + "Applying R_ERR on DMA activate " + "FIS errata fix\n"); + writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); + cnt++; + } + } + if (ent->driver_data == sil_3114) { irq_mask = SIL_MASK_4PORT; -- cgit v1.2.3-59-g8ed1b