aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_promise.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r--drivers/ata/sata_promise.c109
1 files changed, 88 insertions, 21 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index f251a5f569d5..11c1afea2db2 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -46,7 +46,7 @@
46#include "sata_promise.h" 46#include "sata_promise.h"
47 47
48#define DRV_NAME "sata_promise" 48#define DRV_NAME "sata_promise"
49#define DRV_VERSION "2.11" 49#define DRV_VERSION "2.12"
50 50
51enum { 51enum {
52 PDC_MAX_PORTS = 4, 52 PDC_MAX_PORTS = 4,
@@ -145,7 +145,9 @@ static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
145static void pdc_irq_clear(struct ata_port *ap); 145static void pdc_irq_clear(struct ata_port *ap);
146static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc); 146static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
147static void pdc_freeze(struct ata_port *ap); 147static void pdc_freeze(struct ata_port *ap);
148static void pdc_sata_freeze(struct ata_port *ap);
148static void pdc_thaw(struct ata_port *ap); 149static void pdc_thaw(struct ata_port *ap);
150static void pdc_sata_thaw(struct ata_port *ap);
149static void pdc_pata_error_handler(struct ata_port *ap); 151static void pdc_pata_error_handler(struct ata_port *ap);
150static void pdc_sata_error_handler(struct ata_port *ap); 152static void pdc_sata_error_handler(struct ata_port *ap);
151static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); 153static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
@@ -180,8 +182,8 @@ static const struct ata_port_operations pdc_sata_ops = {
180 182
181 .qc_prep = pdc_qc_prep, 183 .qc_prep = pdc_qc_prep,
182 .qc_issue = pdc_qc_issue_prot, 184 .qc_issue = pdc_qc_issue_prot,
183 .freeze = pdc_freeze, 185 .freeze = pdc_sata_freeze,
184 .thaw = pdc_thaw, 186 .thaw = pdc_sata_thaw,
185 .error_handler = pdc_sata_error_handler, 187 .error_handler = pdc_sata_error_handler,
186 .post_internal_cmd = pdc_post_internal_cmd, 188 .post_internal_cmd = pdc_post_internal_cmd,
187 .cable_detect = pdc_sata_cable_detect, 189 .cable_detect = pdc_sata_cable_detect,
@@ -205,8 +207,8 @@ static const struct ata_port_operations pdc_old_sata_ops = {
205 207
206 .qc_prep = pdc_qc_prep, 208 .qc_prep = pdc_qc_prep,
207 .qc_issue = pdc_qc_issue_prot, 209 .qc_issue = pdc_qc_issue_prot,
208 .freeze = pdc_freeze, 210 .freeze = pdc_sata_freeze,
209 .thaw = pdc_thaw, 211 .thaw = pdc_sata_thaw,
210 .error_handler = pdc_sata_error_handler, 212 .error_handler = pdc_sata_error_handler,
211 .post_internal_cmd = pdc_post_internal_cmd, 213 .post_internal_cmd = pdc_post_internal_cmd,
212 .cable_detect = pdc_sata_cable_detect, 214 .cable_detect = pdc_sata_cable_detect,
@@ -631,6 +633,41 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
631 } 633 }
632} 634}
633 635
636static int pdc_is_sataii_tx4(unsigned long flags)
637{
638 const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
639 return (flags & mask) == mask;
640}
641
642static unsigned int pdc_port_no_to_ata_no(unsigned int port_no,
643 int is_sataii_tx4)
644{
645 static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
646 return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
647}
648
649static unsigned int pdc_sata_nr_ports(const struct ata_port *ap)
650{
651 return (ap->flags & PDC_FLAG_4_PORTS) ? 4 : 2;
652}
653
654static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
655{
656 const struct ata_host *host = ap->host;
657 unsigned int nr_ports = pdc_sata_nr_ports(ap);
658 unsigned int i;
659
660 for(i = 0; i < nr_ports && host->ports[i] != ap; ++i)
661 ;
662 BUG_ON(i >= nr_ports);
663 return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
664}
665
666static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
667{
668 return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
669}
670
634static void pdc_freeze(struct ata_port *ap) 671static void pdc_freeze(struct ata_port *ap)
635{ 672{
636 void __iomem *mmio = ap->ioaddr.cmd_addr; 673 void __iomem *mmio = ap->ioaddr.cmd_addr;
@@ -643,6 +680,29 @@ static void pdc_freeze(struct ata_port *ap)
643 readl(mmio + PDC_CTLSTAT); /* flush */ 680 readl(mmio + PDC_CTLSTAT); /* flush */
644} 681}
645 682
683static void pdc_sata_freeze(struct ata_port *ap)
684{
685 struct ata_host *host = ap->host;
686 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
687 unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
688 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
689 u32 hotplug_status;
690
691 /* Disable hotplug events on this port.
692 *
693 * Locking:
694 * 1) hotplug register accesses must be serialised via host->lock
695 * 2) ap->lock == &ap->host->lock
696 * 3) ->freeze() and ->thaw() are called with ap->lock held
697 */
698 hotplug_status = readl(host_mmio + hotplug_offset);
699 hotplug_status |= 0x11 << (ata_no + 16);
700 writel(hotplug_status, host_mmio + hotplug_offset);
701 readl(host_mmio + hotplug_offset); /* flush */
702
703 pdc_freeze(ap);
704}
705
646static void pdc_thaw(struct ata_port *ap) 706static void pdc_thaw(struct ata_port *ap)
647{ 707{
648 void __iomem *mmio = ap->ioaddr.cmd_addr; 708 void __iomem *mmio = ap->ioaddr.cmd_addr;
@@ -658,6 +718,26 @@ static void pdc_thaw(struct ata_port *ap)
658 readl(mmio + PDC_CTLSTAT); /* flush */ 718 readl(mmio + PDC_CTLSTAT); /* flush */
659} 719}
660 720
721static void pdc_sata_thaw(struct ata_port *ap)
722{
723 struct ata_host *host = ap->host;
724 void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
725 unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
726 unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
727 u32 hotplug_status;
728
729 pdc_thaw(ap);
730
731 /* Enable hotplug events on this port.
732 * Locking: see pdc_sata_freeze().
733 */
734 hotplug_status = readl(host_mmio + hotplug_offset);
735 hotplug_status |= 0x11 << ata_no;
736 hotplug_status &= ~(0x11 << (ata_no + 16));
737 writel(hotplug_status, host_mmio + hotplug_offset);
738 readl(host_mmio + hotplug_offset); /* flush */
739}
740
661static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset) 741static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
662{ 742{
663 if (!(ap->pflags & ATA_PFLAG_FROZEN)) 743 if (!(ap->pflags & ATA_PFLAG_FROZEN))
@@ -765,19 +845,6 @@ static void pdc_irq_clear(struct ata_port *ap)
765 readl(mmio + PDC_INT_SEQMASK); 845 readl(mmio + PDC_INT_SEQMASK);
766} 846}
767 847
768static int pdc_is_sataii_tx4(unsigned long flags)
769{
770 const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
771 return (flags & mask) == mask;
772}
773
774static unsigned int pdc_port_no_to_ata_no(unsigned int port_no,
775 int is_sataii_tx4)
776{
777 static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
778 return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
779}
780
781static irqreturn_t pdc_interrupt(int irq, void *dev_instance) 848static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
782{ 849{
783 struct ata_host *host = dev_instance; 850 struct ata_host *host = dev_instance;
@@ -799,6 +866,8 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
799 866
800 mmio_base = host->iomap[PDC_MMIO_BAR]; 867 mmio_base = host->iomap[PDC_MMIO_BAR];
801 868
869 spin_lock(&host->lock);
870
802 /* read and clear hotplug flags for all ports */ 871 /* read and clear hotplug flags for all ports */
803 if (host->ports[0]->flags & PDC_FLAG_GEN_II) 872 if (host->ports[0]->flags & PDC_FLAG_GEN_II)
804 hotplug_offset = PDC2_SATA_PLUG_CSR; 873 hotplug_offset = PDC2_SATA_PLUG_CSR;
@@ -814,11 +883,9 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
814 883
815 if (mask == 0xffffffff && hotplug_status == 0) { 884 if (mask == 0xffffffff && hotplug_status == 0) {
816 VPRINTK("QUICK EXIT 2\n"); 885 VPRINTK("QUICK EXIT 2\n");
817 return IRQ_NONE; 886 goto done_irq;
818 } 887 }
819 888
820 spin_lock(&host->lock);
821
822 mask &= 0xffff; /* only 16 tags possible */ 889 mask &= 0xffff; /* only 16 tags possible */
823 if (mask == 0 && hotplug_status == 0) { 890 if (mask == 0 && hotplug_status == 0) {
824 VPRINTK("QUICK EXIT 3\n"); 891 VPRINTK("QUICK EXIT 3\n");