diff options
-rw-r--r-- | drivers/scsi/sata_sil.c | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 70dbfb8a7d51..6033f796397f 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -561,6 +561,52 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
561 | } | 561 | } |
562 | } | 562 | } |
563 | 563 | ||
564 | static void sil_init_controller(struct pci_dev *pdev, | ||
565 | int n_ports, unsigned long host_flags, | ||
566 | void __iomem *mmio_base) | ||
567 | { | ||
568 | u8 cls; | ||
569 | u32 tmp; | ||
570 | int i; | ||
571 | |||
572 | /* Initialize FIFO PCI bus arbitration */ | ||
573 | cls = sil_get_device_cache_line(pdev); | ||
574 | if (cls) { | ||
575 | cls >>= 3; | ||
576 | cls++; /* cls = (line_size/8)+1 */ | ||
577 | for (i = 0; i < n_ports; i++) | ||
578 | writew(cls << 8 | cls, | ||
579 | mmio_base + sil_port[i].fifo_cfg); | ||
580 | } else | ||
581 | dev_printk(KERN_WARNING, &pdev->dev, | ||
582 | "cache line size not set. Driver may not function\n"); | ||
583 | |||
584 | /* Apply R_ERR on DMA activate FIS errata workaround */ | ||
585 | if (host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | ||
586 | int cnt; | ||
587 | |||
588 | for (i = 0, cnt = 0; i < n_ports; i++) { | ||
589 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | ||
590 | if ((tmp & 0x3) != 0x01) | ||
591 | continue; | ||
592 | if (!cnt) | ||
593 | dev_printk(KERN_INFO, &pdev->dev, | ||
594 | "Applying R_ERR on DMA activate " | ||
595 | "FIS errata fix\n"); | ||
596 | writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); | ||
597 | cnt++; | ||
598 | } | ||
599 | } | ||
600 | |||
601 | if (n_ports == 4) { | ||
602 | /* flip the magic "make 4 ports work" bit */ | ||
603 | tmp = readl(mmio_base + sil_port[2].bmdma); | ||
604 | if ((tmp & SIL_INTR_STEERING) == 0) | ||
605 | writel(tmp | SIL_INTR_STEERING, | ||
606 | mmio_base + sil_port[2].bmdma); | ||
607 | } | ||
608 | } | ||
609 | |||
564 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 610 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
565 | { | 611 | { |
566 | static int printed_version; | 612 | static int printed_version; |
@@ -570,8 +616,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
570 | int rc; | 616 | int rc; |
571 | unsigned int i; | 617 | unsigned int i; |
572 | int pci_dev_busy = 0; | 618 | int pci_dev_busy = 0; |
573 | u32 tmp; | ||
574 | u8 cls; | ||
575 | 619 | ||
576 | if (!printed_version++) | 620 | if (!printed_version++) |
577 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 621 | 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) | |||
630 | ata_std_ports(&probe_ent->port[i]); | 674 | ata_std_ports(&probe_ent->port[i]); |
631 | } | 675 | } |
632 | 676 | ||
633 | /* Initialize FIFO PCI bus arbitration */ | 677 | sil_init_controller(pdev, probe_ent->n_ports, probe_ent->host_flags, |
634 | cls = sil_get_device_cache_line(pdev); | 678 | mmio_base); |
635 | if (cls) { | ||
636 | cls >>= 3; | ||
637 | cls++; /* cls = (line_size/8)+1 */ | ||
638 | for (i = 0; i < probe_ent->n_ports; i++) | ||
639 | writew(cls << 8 | cls, | ||
640 | mmio_base + sil_port[i].fifo_cfg); | ||
641 | } else | ||
642 | dev_printk(KERN_WARNING, &pdev->dev, | ||
643 | "cache line size not set. Driver may not function\n"); | ||
644 | |||
645 | /* Apply R_ERR on DMA activate FIS errata workaround */ | ||
646 | if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | ||
647 | int cnt; | ||
648 | |||
649 | for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) { | ||
650 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | ||
651 | if ((tmp & 0x3) != 0x01) | ||
652 | continue; | ||
653 | if (!cnt) | ||
654 | dev_printk(KERN_INFO, &pdev->dev, | ||
655 | "Applying R_ERR on DMA activate " | ||
656 | "FIS errata fix\n"); | ||
657 | writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); | ||
658 | cnt++; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | if (ent->driver_data == sil_3114) { | ||
663 | /* flip the magic "make 4 ports work" bit */ | ||
664 | tmp = readl(mmio_base + sil_port[2].bmdma); | ||
665 | if ((tmp & SIL_INTR_STEERING) == 0) | ||
666 | writel(tmp | SIL_INTR_STEERING, | ||
667 | mmio_base + sil_port[2].bmdma); | ||
668 | } | ||
669 | 679 | ||
670 | pci_set_master(pdev); | 680 | pci_set_master(pdev); |
671 | 681 | ||