|
@@ -49,6 +49,7 @@
|
|
#define DRV_VERSION "0.9"
|
|
#define DRV_VERSION "0.9"
|
|
|
|
|
|
enum {
|
|
enum {
|
|
|
|
+ SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29),
|
|
SIL_FLAG_MOD15WRITE = (1 << 30),
|
|
SIL_FLAG_MOD15WRITE = (1 << 30),
|
|
|
|
|
|
sil_3112 = 0,
|
|
sil_3112 = 0,
|
|
@@ -202,7 +203,8 @@ static const struct ata_port_info sil_port_info[] = {
|
|
{
|
|
{
|
|
.sht = &sil_sht,
|
|
.sht = &sil_sht,
|
|
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
|
.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 */
|
|
.pio_mask = 0x1f, /* pio0-4 */
|
|
.mwdma_mask = 0x07, /* mwdma0-2 */
|
|
.mwdma_mask = 0x07, /* mwdma0-2 */
|
|
.udma_mask = 0x3f, /* udma0-5 */
|
|
.udma_mask = 0x3f, /* udma0-5 */
|
|
@@ -212,7 +214,8 @@ static const struct ata_port_info sil_port_info[] = {
|
|
{
|
|
{
|
|
.sht = &sil_sht,
|
|
.sht = &sil_sht,
|
|
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
|
|
.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 */
|
|
.pio_mask = 0x1f, /* pio0-4 */
|
|
.mwdma_mask = 0x07, /* mwdma0-2 */
|
|
.mwdma_mask = 0x07, /* mwdma0-2 */
|
|
.udma_mask = 0x3f, /* udma0-5 */
|
|
.udma_mask = 0x3f, /* udma0-5 */
|
|
@@ -229,12 +232,13 @@ static const struct {
|
|
unsigned long scr; /* SATA control register block */
|
|
unsigned long scr; /* SATA control register block */
|
|
unsigned long sien; /* SATA Interrupt Enable register */
|
|
unsigned long sien; /* SATA Interrupt Enable register */
|
|
unsigned long xfer_mode;/* data transfer mode register */
|
|
unsigned long xfer_mode;/* data transfer mode register */
|
|
|
|
+ unsigned long sfis_cfg; /* SATA FIS reception config register */
|
|
} sil_port[] = {
|
|
} sil_port[] = {
|
|
/* port 0 ... */
|
|
/* 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 */
|
|
/* ... 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,
|
|
dev_printk(KERN_WARNING, &pdev->dev,
|
|
"cache line size not set. Driver may not function\n");
|
|
"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) {
|
|
if (ent->driver_data == sil_3114) {
|
|
irq_mask = SIL_MASK_4PORT;
|
|
irq_mask = SIL_MASK_4PORT;
|
|
|
|
|