aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_promise.c
diff options
context:
space:
mode:
authorMikael Pettersson <mikpe@it.uu.se>2009-09-15 09:07:32 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-09-17 16:46:12 -0400
commit0ae6654da437db4ae6333d232e718b570c7a3eac (patch)
tree519cbdefad34dc014fb25e2d2be3c926db7e0d43 /drivers/ata/sata_promise.c
parent4dc738ed2adf28f62f46dd53ef700a51603777f7 (diff)
sata_promise: disable hotplug on 1st gen chips
1st generation Promise SATA chips are prone to generating spurious hotplug events which can disrupt normal operation. This has been observed on 20376 and 20378 chips. This patch thus disables hotplug support on 1st gen chips while leaving it enabled for 2nd gen chips. The pdc_sata_hotplug_offset() function becomes redundant so it is removed. Tested on 1st gen 20376 and 20378 mainboard chips and on a 2nd gen SATA300 PCI card. Signed-off-by: Mikael Pettersson <mikpe@it.uu.se> Tested-by: Kurt Roeckx <kurt@roeckx.be> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r--drivers/ata/sata_promise.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index b1fd7d62071a..4d18d5a59afe 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -195,9 +195,12 @@ static struct ata_port_operations pdc_sata_ops = {
195 .hardreset = pdc_sata_hardreset, 195 .hardreset = pdc_sata_hardreset,
196}; 196};
197 197
198/* First-generation chips need a more restrictive ->check_atapi_dma op */ 198/* First-generation chips need a more restrictive ->check_atapi_dma op,
199 and ->freeze/thaw that ignore the hotplug controls. */
199static struct ata_port_operations pdc_old_sata_ops = { 200static struct ata_port_operations pdc_old_sata_ops = {
200 .inherits = &pdc_sata_ops, 201 .inherits = &pdc_sata_ops,
202 .freeze = pdc_freeze,
203 .thaw = pdc_thaw,
201 .check_atapi_dma = pdc_old_sata_check_atapi_dma, 204 .check_atapi_dma = pdc_old_sata_check_atapi_dma,
202}; 205};
203 206
@@ -626,11 +629,6 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
626 return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); 629 return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
627} 630}
628 631
629static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
630{
631 return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
632}
633
634static void pdc_freeze(struct ata_port *ap) 632static void pdc_freeze(struct ata_port *ap)
635{ 633{
636 void __iomem *ata_mmio = ap->ioaddr.cmd_addr; 634 void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
@@ -647,7 +645,7 @@ static void pdc_sata_freeze(struct ata_port *ap)
647{ 645{
648 struct ata_host *host = ap->host; 646 struct ata_host *host = ap->host;
649 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; 647 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
650 unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); 648 unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
651 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); 649 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
652 u32 hotplug_status; 650 u32 hotplug_status;
653 651
@@ -685,7 +683,7 @@ static void pdc_sata_thaw(struct ata_port *ap)
685{ 683{
686 struct ata_host *host = ap->host; 684 struct ata_host *host = ap->host;
687 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; 685 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
688 unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); 686 unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
689 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); 687 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
690 u32 hotplug_status; 688 u32 hotplug_status;
691 689
@@ -832,14 +830,14 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
832 spin_lock(&host->lock); 830 spin_lock(&host->lock);
833 831
834 /* read and clear hotplug flags for all ports */ 832 /* read and clear hotplug flags for all ports */
835 if (host->ports[0]->flags & PDC_FLAG_GEN_II) 833 if (host->ports[0]->flags & PDC_FLAG_GEN_II) {
836 hotplug_offset = PDC2_SATA_PLUG_CSR; 834 hotplug_offset = PDC2_SATA_PLUG_CSR;
837 else 835 hotplug_status = readl(host_mmio + hotplug_offset);
838 hotplug_offset = PDC_SATA_PLUG_CSR; 836 if (hotplug_status & 0xff)
839 hotplug_status = readl(host_mmio + hotplug_offset); 837 writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
840 if (hotplug_status & 0xff) 838 hotplug_status &= 0xff; /* clear uninteresting bits */
841 writel(hotplug_status | 0xff, host_mmio + hotplug_offset); 839 } else
842 hotplug_status &= 0xff; /* clear uninteresting bits */ 840 hotplug_status = 0;
843 841
844 /* reading should also clear interrupts */ 842 /* reading should also clear interrupts */
845 mask = readl(host_mmio + PDC_INT_SEQMASK); 843 mask = readl(host_mmio + PDC_INT_SEQMASK);
@@ -1034,9 +1032,11 @@ static void pdc_host_init(struct ata_host *host)
1034 tmp = readl(host_mmio + hotplug_offset); 1032 tmp = readl(host_mmio + hotplug_offset);
1035 writel(tmp | 0xff, host_mmio + hotplug_offset); 1033 writel(tmp | 0xff, host_mmio + hotplug_offset);
1036 1034
1037 /* unmask plug/unplug ints */
1038 tmp = readl(host_mmio + hotplug_offset); 1035 tmp = readl(host_mmio + hotplug_offset);
1039 writel(tmp & ~0xff0000, host_mmio + hotplug_offset); 1036 if (is_gen2) /* unmask plug/unplug ints */
1037 writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
1038 else /* mask plug/unplug ints */
1039 writel(tmp | 0xff0000, host_mmio + hotplug_offset);
1040 1040
1041 /* don't initialise TBG or SLEW on 2nd generation chips */ 1041 /* don't initialise TBG or SLEW on 2nd generation chips */
1042 if (is_gen2) 1042 if (is_gen2)