|
@@ -561,6 +561,52 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void sil_init_controller(struct pci_dev *pdev,
|
|
|
+ int n_ports, unsigned long host_flags,
|
|
|
+ void __iomem *mmio_base)
|
|
|
+{
|
|
|
+ u8 cls;
|
|
|
+ u32 tmp;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Initialize FIFO PCI bus arbitration */
|
|
|
+ cls = sil_get_device_cache_line(pdev);
|
|
|
+ if (cls) {
|
|
|
+ cls >>= 3;
|
|
|
+ cls++; /* cls = (line_size/8)+1 */
|
|
|
+ for (i = 0; i < n_ports; i++)
|
|
|
+ writew(cls << 8 | cls,
|
|
|
+ mmio_base + sil_port[i].fifo_cfg);
|
|
|
+ } else
|
|
|
+ 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 (host_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
|
|
|
+ int cnt;
|
|
|
+
|
|
|
+ for (i = 0, cnt = 0; i < 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 (n_ports == 4) {
|
|
|
+ /* flip the magic "make 4 ports work" bit */
|
|
|
+ tmp = readl(mmio_base + sil_port[2].bmdma);
|
|
|
+ if ((tmp & SIL_INTR_STEERING) == 0)
|
|
|
+ writel(tmp | SIL_INTR_STEERING,
|
|
|
+ mmio_base + sil_port[2].bmdma);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
{
|
|
|
static int printed_version;
|
|
@@ -570,8 +616,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
int rc;
|
|
|
unsigned int i;
|
|
|
int pci_dev_busy = 0;
|
|
|
- u32 tmp;
|
|
|
- u8 cls;
|
|
|
|
|
|
if (!printed_version++)
|
|
|
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
|
|
@@ -630,42 +674,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
ata_std_ports(&probe_ent->port[i]);
|
|
|
}
|
|
|
|
|
|
- /* Initialize FIFO PCI bus arbitration */
|
|
|
- cls = sil_get_device_cache_line(pdev);
|
|
|
- if (cls) {
|
|
|
- cls >>= 3;
|
|
|
- cls++; /* cls = (line_size/8)+1 */
|
|
|
- for (i = 0; i < probe_ent->n_ports; i++)
|
|
|
- writew(cls << 8 | cls,
|
|
|
- mmio_base + sil_port[i].fifo_cfg);
|
|
|
- } else
|
|
|
- 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) {
|
|
|
- /* flip the magic "make 4 ports work" bit */
|
|
|
- tmp = readl(mmio_base + sil_port[2].bmdma);
|
|
|
- if ((tmp & SIL_INTR_STEERING) == 0)
|
|
|
- writel(tmp | SIL_INTR_STEERING,
|
|
|
- mmio_base + sil_port[2].bmdma);
|
|
|
- }
|
|
|
+ sil_init_controller(pdev, probe_ent->n_ports, probe_ent->host_flags,
|
|
|
+ mmio_base);
|
|
|
|
|
|
pci_set_master(pdev);
|
|
|
|