aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_sil24.c227
1 files changed, 206 insertions, 21 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b4f81eb8bbbe..03bfbb65c533 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -30,7 +30,7 @@
30#include <linux/libata.h> 30#include <linux/libata.h>
31 31
32#define DRV_NAME "sata_sil24" 32#define DRV_NAME "sata_sil24"
33#define DRV_VERSION "1.0" 33#define DRV_VERSION "1.1"
34 34
35/* 35/*
36 * Port request block (PRB) 32 bytes 36 * Port request block (PRB) 32 bytes
@@ -238,7 +238,7 @@ enum {
238 SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 238 SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
239 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | 239 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
240 ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | 240 ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
241 ATA_FLAG_AN, 241 ATA_FLAG_AN | ATA_FLAG_PMP,
242 SIL24_COMMON_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY, 242 SIL24_COMMON_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY,
243 SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ 243 SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
244 244
@@ -330,9 +330,14 @@ static u8 sil24_check_status(struct ata_port *ap);
330static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val); 330static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
331static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); 331static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
332static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); 332static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
333static int sil24_qc_defer(struct ata_queued_cmd *qc);
333static void sil24_qc_prep(struct ata_queued_cmd *qc); 334static void sil24_qc_prep(struct ata_queued_cmd *qc);
334static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); 335static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
335static void sil24_irq_clear(struct ata_port *ap); 336static void sil24_irq_clear(struct ata_port *ap);
337static void sil24_pmp_attach(struct ata_port *ap);
338static void sil24_pmp_detach(struct ata_port *ap);
339static int sil24_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val);
340static int sil24_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val);
336static void sil24_freeze(struct ata_port *ap); 341static void sil24_freeze(struct ata_port *ap);
337static void sil24_thaw(struct ata_port *ap); 342static void sil24_thaw(struct ata_port *ap);
338static void sil24_error_handler(struct ata_port *ap); 343static void sil24_error_handler(struct ata_port *ap);
@@ -341,6 +346,7 @@ static int sil24_port_start(struct ata_port *ap);
341static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 346static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
342#ifdef CONFIG_PM 347#ifdef CONFIG_PM
343static int sil24_pci_device_resume(struct pci_dev *pdev); 348static int sil24_pci_device_resume(struct pci_dev *pdev);
349static int sil24_port_resume(struct ata_port *ap);
344#endif 350#endif
345 351
346static const struct pci_device_id sil24_pci_tbl[] = { 352static const struct pci_device_id sil24_pci_tbl[] = {
@@ -393,7 +399,7 @@ static const struct ata_port_operations sil24_ops = {
393 399
394 .tf_read = sil24_tf_read, 400 .tf_read = sil24_tf_read,
395 401
396 .qc_defer = ata_std_qc_defer, 402 .qc_defer = sil24_qc_defer,
397 .qc_prep = sil24_qc_prep, 403 .qc_prep = sil24_qc_prep,
398 .qc_issue = sil24_qc_issue, 404 .qc_issue = sil24_qc_issue,
399 405
@@ -402,12 +408,21 @@ static const struct ata_port_operations sil24_ops = {
402 .scr_read = sil24_scr_read, 408 .scr_read = sil24_scr_read,
403 .scr_write = sil24_scr_write, 409 .scr_write = sil24_scr_write,
404 410
411 .pmp_attach = sil24_pmp_attach,
412 .pmp_detach = sil24_pmp_detach,
413 .pmp_read = sil24_pmp_read,
414 .pmp_write = sil24_pmp_write,
415
405 .freeze = sil24_freeze, 416 .freeze = sil24_freeze,
406 .thaw = sil24_thaw, 417 .thaw = sil24_thaw,
407 .error_handler = sil24_error_handler, 418 .error_handler = sil24_error_handler,
408 .post_internal_cmd = sil24_post_internal_cmd, 419 .post_internal_cmd = sil24_post_internal_cmd,
409 420
410 .port_start = sil24_port_start, 421 .port_start = sil24_port_start,
422
423#ifdef CONFIG_PM
424 .port_resume = sil24_port_resume,
425#endif
411}; 426};
412 427
413/* 428/*
@@ -521,11 +536,40 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
521 *tf = pp->tf; 536 *tf = pp->tf;
522} 537}
523 538
539static void sil24_config_pmp(struct ata_port *ap, int attached)
540{
541 void __iomem *port = ap->ioaddr.cmd_addr;
542
543 if (attached)
544 writel(PORT_CS_PMP_EN, port + PORT_CTRL_STAT);
545 else
546 writel(PORT_CS_PMP_EN, port + PORT_CTRL_CLR);
547}
548
549static void sil24_clear_pmp(struct ata_port *ap)
550{
551 void __iomem *port = ap->ioaddr.cmd_addr;
552 int i;
553
554 writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
555
556 for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
557 void __iomem *pmp_base = port + PORT_PMP + i * PORT_PMP_SIZE;
558
559 writel(0, pmp_base + PORT_PMP_STATUS);
560 writel(0, pmp_base + PORT_PMP_QACTIVE);
561 }
562}
563
524static int sil24_init_port(struct ata_port *ap) 564static int sil24_init_port(struct ata_port *ap)
525{ 565{
526 void __iomem *port = ap->ioaddr.cmd_addr; 566 void __iomem *port = ap->ioaddr.cmd_addr;
527 u32 tmp; 567 u32 tmp;
528 568
569 /* clear PMP error status */
570 if (ap->nr_pmp_links)
571 sil24_clear_pmp(ap);
572
529 writel(PORT_CS_INIT, port + PORT_CTRL_STAT); 573 writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
530 ata_wait_register(port + PORT_CTRL_STAT, 574 ata_wait_register(port + PORT_CTRL_STAT,
531 PORT_CS_INIT, PORT_CS_INIT, 10, 100); 575 PORT_CS_INIT, PORT_CS_INIT, 10, 100);
@@ -640,7 +684,7 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
640static int sil24_softreset(struct ata_link *link, unsigned int *class, 684static int sil24_softreset(struct ata_link *link, unsigned int *class,
641 unsigned long deadline) 685 unsigned long deadline)
642{ 686{
643 return sil24_do_softreset(link, class, 0, deadline); 687 return sil24_do_softreset(link, class, SATA_PMP_CTRL_PORT, deadline);
644} 688}
645 689
646static int sil24_hardreset(struct ata_link *link, unsigned int *class, 690static int sil24_hardreset(struct ata_link *link, unsigned int *class,
@@ -708,6 +752,38 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
708 } 752 }
709} 753}
710 754
755static int sil24_qc_defer(struct ata_queued_cmd *qc)
756{
757 struct ata_link *link = qc->dev->link;
758 struct ata_port *ap = link->ap;
759 u8 prot = qc->tf.protocol;
760 int is_atapi = (prot == ATA_PROT_ATAPI ||
761 prot == ATA_PROT_ATAPI_NODATA ||
762 prot == ATA_PROT_ATAPI_DMA);
763
764 /* ATAPI commands completing with CHECK_SENSE cause various
765 * weird problems if other commands are active. PMP DMA CS
766 * errata doesn't cover all and HSM violation occurs even with
767 * only one other device active. Always run an ATAPI command
768 * by itself.
769 */
770 if (unlikely(ap->excl_link)) {
771 if (link == ap->excl_link) {
772 if (ap->nr_active_links)
773 return ATA_DEFER_PORT;
774 qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
775 } else
776 return ATA_DEFER_PORT;
777 } else if (unlikely(is_atapi)) {
778 ap->excl_link = link;
779 if (ap->nr_active_links)
780 return ATA_DEFER_PORT;
781 qc->flags |= ATA_QCFLAG_CLEAR_EXCL;
782 }
783
784 return ata_std_qc_defer(qc);
785}
786
711static void sil24_qc_prep(struct ata_queued_cmd *qc) 787static void sil24_qc_prep(struct ata_queued_cmd *qc)
712{ 788{
713 struct ata_port *ap = qc->ap; 789 struct ata_port *ap = qc->ap;
@@ -751,7 +827,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
751 } 827 }
752 828
753 prb->ctrl = cpu_to_le16(ctrl); 829 prb->ctrl = cpu_to_le16(ctrl);
754 ata_tf_to_fis(&qc->tf, 0, 1, prb->fis); 830 ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, prb->fis);
755 831
756 if (qc->flags & ATA_QCFLAG_DMAMAP) 832 if (qc->flags & ATA_QCFLAG_DMAMAP)
757 sil24_fill_sg(qc, sge); 833 sil24_fill_sg(qc, sge);
@@ -780,6 +856,65 @@ static void sil24_irq_clear(struct ata_port *ap)
780 /* unused */ 856 /* unused */
781} 857}
782 858
859static void sil24_pmp_attach(struct ata_port *ap)
860{
861 sil24_config_pmp(ap, 1);
862 sil24_init_port(ap);
863}
864
865static void sil24_pmp_detach(struct ata_port *ap)
866{
867 sil24_init_port(ap);
868 sil24_config_pmp(ap, 0);
869}
870
871static int sil24_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val)
872{
873 struct ata_port *ap = dev->link->ap;
874 struct ata_taskfile tf;
875 int rc;
876
877 sata_pmp_read_init_tf(&tf, dev, pmp, reg);
878 rc = sil24_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
879 SATA_PMP_SCR_TIMEOUT);
880 if (rc == 0) {
881 sil24_read_tf(ap, 0, &tf);
882 *r_val = sata_pmp_read_val(&tf);
883 }
884 return rc;
885}
886
887static int sil24_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val)
888{
889 struct ata_port *ap = dev->link->ap;
890 struct ata_taskfile tf;
891
892 sata_pmp_write_init_tf(&tf, dev, pmp, reg, val);
893 return sil24_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
894 SATA_PMP_SCR_TIMEOUT);
895}
896
897static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
898 unsigned long deadline)
899{
900 return sil24_do_softreset(link, class, link->pmp, deadline);
901}
902
903static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
904 unsigned long deadline)
905{
906 int rc;
907
908 rc = sil24_init_port(link->ap);
909 if (rc) {
910 ata_link_printk(link, KERN_ERR,
911 "hardreset failed (port not ready)\n");
912 return rc;
913 }
914
915 return sata_pmp_std_hardreset(link, class, deadline);
916}
917
783static void sil24_freeze(struct ata_port *ap) 918static void sil24_freeze(struct ata_port *ap)
784{ 919{
785 void __iomem *port = ap->ioaddr.cmd_addr; 920 void __iomem *port = ap->ioaddr.cmd_addr;
@@ -807,8 +942,10 @@ static void sil24_error_intr(struct ata_port *ap)
807{ 942{
808 void __iomem *port = ap->ioaddr.cmd_addr; 943 void __iomem *port = ap->ioaddr.cmd_addr;
809 struct sil24_port_priv *pp = ap->private_data; 944 struct sil24_port_priv *pp = ap->private_data;
810 struct ata_eh_info *ehi = &ap->link.eh_info; 945 struct ata_queued_cmd *qc = NULL;
811 int freeze = 0; 946 struct ata_link *link;
947 struct ata_eh_info *ehi;
948 int abort = 0, freeze = 0;
812 u32 irq_stat; 949 u32 irq_stat;
813 950
814 /* on error, we need to clear IRQ explicitly */ 951 /* on error, we need to clear IRQ explicitly */
@@ -816,6 +953,8 @@ static void sil24_error_intr(struct ata_port *ap)
816 writel(irq_stat, port + PORT_IRQ_STAT); 953 writel(irq_stat, port + PORT_IRQ_STAT);
817 954
818 /* first, analyze and record host port events */ 955 /* first, analyze and record host port events */
956 link = &ap->link;
957 ehi = &link->eh_info;
819 ata_ehi_clear_desc(ehi); 958 ata_ehi_clear_desc(ehi);
820 959
821 ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); 960 ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
@@ -844,8 +983,43 @@ static void sil24_error_intr(struct ata_port *ap)
844 if (irq_stat & PORT_IRQ_ERROR) { 983 if (irq_stat & PORT_IRQ_ERROR) {
845 struct sil24_cerr_info *ci = NULL; 984 struct sil24_cerr_info *ci = NULL;
846 unsigned int err_mask = 0, action = 0; 985 unsigned int err_mask = 0, action = 0;
847 struct ata_queued_cmd *qc; 986 u32 context, cerr;
848 u32 cerr; 987 int pmp;
988
989 abort = 1;
990
991 /* DMA Context Switch Failure in Port Multiplier Mode
992 * errata. If we have active commands to 3 or more
993 * devices, any error condition on active devices can
994 * corrupt DMA context switching.
995 */
996 if (ap->nr_active_links >= 3) {
997 ehi->err_mask |= AC_ERR_OTHER;
998 ehi->action |= ATA_EH_HARDRESET;
999 ata_ehi_push_desc(ehi, "PMP DMA CS errata");
1000 freeze = 1;
1001 }
1002
1003 /* find out the offending link and qc */
1004 if (ap->nr_pmp_links) {
1005 context = readl(port + PORT_CONTEXT);
1006 pmp = (context >> 5) & 0xf;
1007
1008 if (pmp < ap->nr_pmp_links) {
1009 link = &ap->pmp_link[pmp];
1010 ehi = &link->eh_info;
1011 qc = ata_qc_from_tag(ap, link->active_tag);
1012
1013 ata_ehi_clear_desc(ehi);
1014 ata_ehi_push_desc(ehi, "irq_stat 0x%08x",
1015 irq_stat);
1016 } else {
1017 err_mask |= AC_ERR_HSM;
1018 action |= ATA_EH_HARDRESET;
1019 freeze = 1;
1020 }
1021 } else
1022 qc = ata_qc_from_tag(ap, link->active_tag);
849 1023
850 /* analyze CMD_ERR */ 1024 /* analyze CMD_ERR */
851 cerr = readl(port + PORT_CMD_ERR); 1025 cerr = readl(port + PORT_CMD_ERR);
@@ -864,7 +1038,6 @@ static void sil24_error_intr(struct ata_port *ap)
864 } 1038 }
865 1039
866 /* record error info */ 1040 /* record error info */
867 qc = ata_qc_from_tag(ap, ap->link.active_tag);
868 if (qc) { 1041 if (qc) {
869 sil24_read_tf(ap, qc->tag, &pp->tf); 1042 sil24_read_tf(ap, qc->tag, &pp->tf);
870 qc->err_mask |= err_mask; 1043 qc->err_mask |= err_mask;
@@ -872,13 +1045,21 @@ static void sil24_error_intr(struct ata_port *ap)
872 ehi->err_mask |= err_mask; 1045 ehi->err_mask |= err_mask;
873 1046
874 ehi->action |= action; 1047 ehi->action |= action;
1048
1049 /* if PMP, resume */
1050 if (ap->nr_pmp_links)
1051 writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
875 } 1052 }
876 1053
877 /* freeze or abort */ 1054 /* freeze or abort */
878 if (freeze) 1055 if (freeze)
879 ata_port_freeze(ap); 1056 ata_port_freeze(ap);
880 else 1057 else if (abort) {
881 ata_port_abort(ap); 1058 if (qc)
1059 ata_link_abort(qc->dev->link);
1060 else
1061 ata_port_abort(ap);
1062 }
882} 1063}
883 1064
884static void sil24_finish_qc(struct ata_queued_cmd *qc) 1065static void sil24_finish_qc(struct ata_queued_cmd *qc)
@@ -971,16 +1152,14 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
971 1152
972static void sil24_error_handler(struct ata_port *ap) 1153static void sil24_error_handler(struct ata_port *ap)
973{ 1154{
974 struct ata_eh_context *ehc = &ap->link.eh_context; 1155 if (sil24_init_port(ap))
975
976 if (sil24_init_port(ap)) {
977 ata_eh_freeze_port(ap); 1156 ata_eh_freeze_port(ap);
978 ehc->i.action |= ATA_EH_HARDRESET;
979 }
980 1157
981 /* perform recovery */ 1158 /* perform recovery */
982 ata_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset, 1159 sata_pmp_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset,
983 ata_std_postreset); 1160 ata_std_postreset, sata_pmp_std_prereset,
1161 sil24_pmp_softreset, sil24_pmp_hardreset,
1162 sata_pmp_std_postreset);
984} 1163}
985 1164
986static void sil24_post_internal_cmd(struct ata_queued_cmd *qc) 1165static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
@@ -988,8 +1167,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
988 struct ata_port *ap = qc->ap; 1167 struct ata_port *ap = qc->ap;
989 1168
990 /* make DMA engine forget about the failed command */ 1169 /* make DMA engine forget about the failed command */
991 if (qc->flags & ATA_QCFLAG_FAILED) 1170 if ((qc->flags & ATA_QCFLAG_FAILED) && sil24_init_port(ap))
992 sil24_init_port(ap); 1171 ata_eh_freeze_port(ap);
993} 1172}
994 1173
995static int sil24_port_start(struct ata_port *ap) 1174static int sil24_port_start(struct ata_port *ap)
@@ -1190,6 +1369,12 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
1190 1369
1191 return 0; 1370 return 0;
1192} 1371}
1372
1373static int sil24_port_resume(struct ata_port *ap)
1374{
1375 sil24_config_pmp(ap, ap->nr_pmp_links);
1376 return 0;
1377}
1193#endif 1378#endif
1194 1379
1195static int __init sil24_init(void) 1380static int __init sil24_init(void)