diff options
| -rw-r--r-- | drivers/ata/sata_fsl.c | 224 |
1 files changed, 163 insertions, 61 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 853559e32315..3924e7209a44 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
| @@ -34,7 +34,7 @@ enum { | |||
| 34 | 34 | ||
| 35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
| 37 | ATA_FLAG_NCQ), | 37 | ATA_FLAG_PMP | ATA_FLAG_NCQ), |
| 38 | 38 | ||
| 39 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, | 39 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, |
| 40 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ | 40 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ |
| @@ -395,7 +395,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) | |||
| 395 | cd = (struct command_desc *)pp->cmdentry + tag; | 395 | cd = (struct command_desc *)pp->cmdentry + tag; |
| 396 | cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; | 396 | cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; |
| 397 | 397 | ||
| 398 | ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) &cd->cfis); | 398 | ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *) &cd->cfis); |
| 399 | 399 | ||
| 400 | VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", | 400 | VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", |
| 401 | cd->cfis[0], cd->cfis[1], cd->cfis[2]); | 401 | cd->cfis[0], cd->cfis[1], cd->cfis[2]); |
| @@ -438,6 +438,8 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) | |||
| 438 | ioread32(CA + hcr_base), | 438 | ioread32(CA + hcr_base), |
| 439 | ioread32(CE + hcr_base), ioread32(CC + hcr_base)); | 439 | ioread32(CE + hcr_base), ioread32(CC + hcr_base)); |
| 440 | 440 | ||
| 441 | iowrite32(qc->dev->link->pmp, CQPMP + hcr_base); | ||
| 442 | |||
| 441 | /* Simply queue command to the controller/device */ | 443 | /* Simply queue command to the controller/device */ |
| 442 | iowrite32(1 << tag, CQ + hcr_base); | 444 | iowrite32(1 << tag, CQ + hcr_base); |
| 443 | 445 | ||
| @@ -558,11 +560,36 @@ static void sata_fsl_thaw(struct ata_port *ap) | |||
| 558 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); | 560 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); |
| 559 | } | 561 | } |
| 560 | 562 | ||
| 563 | static void sata_fsl_pmp_attach(struct ata_port *ap) | ||
| 564 | { | ||
| 565 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
| 566 | void __iomem *hcr_base = host_priv->hcr_base; | ||
| 567 | u32 temp; | ||
| 568 | |||
| 569 | temp = ioread32(hcr_base + HCONTROL); | ||
| 570 | iowrite32((temp | HCONTROL_PMP_ATTACHED), hcr_base + HCONTROL); | ||
| 571 | } | ||
| 572 | |||
| 573 | static void sata_fsl_pmp_detach(struct ata_port *ap) | ||
| 574 | { | ||
| 575 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
| 576 | void __iomem *hcr_base = host_priv->hcr_base; | ||
| 577 | u32 temp; | ||
| 578 | |||
| 579 | temp = ioread32(hcr_base + HCONTROL); | ||
| 580 | temp &= ~HCONTROL_PMP_ATTACHED; | ||
| 581 | iowrite32(temp, hcr_base + HCONTROL); | ||
| 582 | |||
| 583 | /* enable interrupts on the controller/port */ | ||
| 584 | temp = ioread32(hcr_base + HCONTROL); | ||
| 585 | iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL); | ||
| 586 | |||
| 587 | } | ||
| 588 | |||
| 561 | static int sata_fsl_port_start(struct ata_port *ap) | 589 | static int sata_fsl_port_start(struct ata_port *ap) |
| 562 | { | 590 | { |
| 563 | struct device *dev = ap->host->dev; | 591 | struct device *dev = ap->host->dev; |
| 564 | struct sata_fsl_port_priv *pp; | 592 | struct sata_fsl_port_priv *pp; |
| 565 | int retval; | ||
| 566 | void *mem; | 593 | void *mem; |
| 567 | dma_addr_t mem_dma; | 594 | dma_addr_t mem_dma; |
| 568 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 595 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
| @@ -688,12 +715,13 @@ static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline) | |||
| 688 | } | 715 | } |
| 689 | 716 | ||
| 690 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | 717 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, |
| 691 | unsigned long deadline) | 718 | unsigned long deadline) |
| 692 | { | 719 | { |
| 693 | struct ata_port *ap = link->ap; | 720 | struct ata_port *ap = link->ap; |
| 694 | struct sata_fsl_port_priv *pp = ap->private_data; | 721 | struct sata_fsl_port_priv *pp = ap->private_data; |
| 695 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 722 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
| 696 | void __iomem *hcr_base = host_priv->hcr_base; | 723 | void __iomem *hcr_base = host_priv->hcr_base; |
| 724 | int pmp = sata_srst_pmp(link); | ||
| 697 | u32 temp; | 725 | u32 temp; |
| 698 | struct ata_taskfile tf; | 726 | struct ata_taskfile tf; |
| 699 | u8 *cfis; | 727 | u8 *cfis; |
| @@ -703,6 +731,9 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | |||
| 703 | 731 | ||
| 704 | DPRINTK("in xx_softreset\n"); | 732 | DPRINTK("in xx_softreset\n"); |
| 705 | 733 | ||
| 734 | if (pmp != SATA_PMP_CTRL_PORT) | ||
| 735 | goto issue_srst; | ||
| 736 | |||
| 706 | try_offline_again: | 737 | try_offline_again: |
| 707 | /* | 738 | /* |
| 708 | * Force host controller to go off-line, aborting current operations | 739 | * Force host controller to go off-line, aborting current operations |
| @@ -746,6 +777,7 @@ try_offline_again: | |||
| 746 | 777 | ||
| 747 | temp = ioread32(hcr_base + HCONTROL); | 778 | temp = ioread32(hcr_base + HCONTROL); |
| 748 | temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE); | 779 | temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE); |
| 780 | temp |= HCONTROL_PMP_ATTACHED; | ||
| 749 | iowrite32(temp, hcr_base + HCONTROL); | 781 | iowrite32(temp, hcr_base + HCONTROL); |
| 750 | 782 | ||
| 751 | temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500); | 783 | temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500); |
| @@ -771,7 +803,8 @@ try_offline_again: | |||
| 771 | ata_port_printk(ap, KERN_WARNING, | 803 | ata_port_printk(ap, KERN_WARNING, |
| 772 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", | 804 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", |
| 773 | ioread32(hcr_base + HSTATUS)); | 805 | ioread32(hcr_base + HSTATUS)); |
| 774 | goto err; | 806 | *class = ATA_DEV_NONE; |
| 807 | goto out; | ||
| 775 | } | 808 | } |
| 776 | 809 | ||
| 777 | /* | 810 | /* |
| @@ -783,7 +816,8 @@ try_offline_again: | |||
| 783 | 816 | ||
| 784 | if ((temp & 0xFF) != 0x18) { | 817 | if ((temp & 0xFF) != 0x18) { |
| 785 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); | 818 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); |
| 786 | goto err; | 819 | *class = ATA_DEV_NONE; |
| 820 | goto out; | ||
| 787 | } else { | 821 | } else { |
| 788 | ata_port_printk(ap, KERN_INFO, | 822 | ata_port_printk(ap, KERN_INFO, |
| 789 | "Signature Update detected @ %d msecs\n", | 823 | "Signature Update detected @ %d msecs\n", |
| @@ -798,6 +832,7 @@ try_offline_again: | |||
| 798 | * reached here, we can send a command to the target device | 832 | * reached here, we can send a command to the target device |
| 799 | */ | 833 | */ |
| 800 | 834 | ||
| 835 | issue_srst: | ||
| 801 | DPRINTK("Sending SRST/device reset\n"); | 836 | DPRINTK("Sending SRST/device reset\n"); |
| 802 | 837 | ||
| 803 | ata_tf_init(link->device, &tf); | 838 | ata_tf_init(link->device, &tf); |
| @@ -808,7 +843,7 @@ try_offline_again: | |||
| 808 | SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); | 843 | SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); |
| 809 | 844 | ||
| 810 | tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ | 845 | tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ |
| 811 | ata_tf_to_fis(&tf, 0, 0, cfis); | 846 | ata_tf_to_fis(&tf, pmp, 0, cfis); |
| 812 | 847 | ||
| 813 | DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", | 848 | DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", |
| 814 | cfis[0], cfis[1], cfis[2], cfis[3]); | 849 | cfis[0], cfis[1], cfis[2], cfis[3]); |
| @@ -854,8 +889,10 @@ try_offline_again: | |||
| 854 | sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); | 889 | sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); |
| 855 | 890 | ||
| 856 | tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ | 891 | tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ |
| 857 | ata_tf_to_fis(&tf, 0, 0, cfis); | 892 | ata_tf_to_fis(&tf, pmp, 0, cfis); |
| 858 | 893 | ||
| 894 | if (pmp != SATA_PMP_CTRL_PORT) | ||
| 895 | iowrite32(pmp, CQPMP + hcr_base); | ||
| 859 | iowrite32(1, CQ + hcr_base); | 896 | iowrite32(1, CQ + hcr_base); |
| 860 | msleep(150); /* ?? */ | 897 | msleep(150); /* ?? */ |
| 861 | 898 | ||
| @@ -886,12 +923,21 @@ try_offline_again: | |||
| 886 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); | 923 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); |
| 887 | } | 924 | } |
| 888 | 925 | ||
| 926 | out: | ||
| 889 | return 0; | 927 | return 0; |
| 890 | 928 | ||
| 891 | err: | 929 | err: |
| 892 | return -EIO; | 930 | return -EIO; |
| 893 | } | 931 | } |
| 894 | 932 | ||
| 933 | static void sata_fsl_error_handler(struct ata_port *ap) | ||
| 934 | { | ||
| 935 | |||
| 936 | DPRINTK("in xx_error_handler\n"); | ||
| 937 | sata_pmp_error_handler(ap); | ||
| 938 | |||
| 939 | } | ||
| 940 | |||
| 895 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | 941 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) |
| 896 | { | 942 | { |
| 897 | if (qc->flags & ATA_QCFLAG_FAILED) | 943 | if (qc->flags & ATA_QCFLAG_FAILED) |
| @@ -905,18 +951,21 @@ static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | |||
| 905 | 951 | ||
| 906 | static void sata_fsl_error_intr(struct ata_port *ap) | 952 | static void sata_fsl_error_intr(struct ata_port *ap) |
| 907 | { | 953 | { |
| 908 | struct ata_link *link = &ap->link; | ||
| 909 | struct ata_eh_info *ehi = &link->eh_info; | ||
| 910 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 954 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
| 911 | void __iomem *hcr_base = host_priv->hcr_base; | 955 | void __iomem *hcr_base = host_priv->hcr_base; |
| 912 | u32 hstatus, dereg, cereg = 0, SError = 0; | 956 | u32 hstatus, dereg=0, cereg = 0, SError = 0; |
| 913 | unsigned int err_mask = 0, action = 0; | 957 | unsigned int err_mask = 0, action = 0; |
| 914 | struct ata_queued_cmd *qc; | 958 | int freeze = 0, abort=0; |
| 915 | int freeze = 0; | 959 | struct ata_link *link = NULL; |
| 960 | struct ata_queued_cmd *qc = NULL; | ||
| 961 | struct ata_eh_info *ehi; | ||
| 916 | 962 | ||
| 917 | hstatus = ioread32(hcr_base + HSTATUS); | 963 | hstatus = ioread32(hcr_base + HSTATUS); |
| 918 | cereg = ioread32(hcr_base + CE); | 964 | cereg = ioread32(hcr_base + CE); |
| 919 | 965 | ||
| 966 | /* first, analyze and record host port events */ | ||
| 967 | link = &ap->link; | ||
| 968 | ehi = &link->eh_info; | ||
| 920 | ata_ehi_clear_desc(ehi); | 969 | ata_ehi_clear_desc(ehi); |
| 921 | 970 | ||
| 922 | /* | 971 | /* |
| @@ -926,42 +975,28 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
| 926 | sata_fsl_scr_read(ap, SCR_ERROR, &SError); | 975 | sata_fsl_scr_read(ap, SCR_ERROR, &SError); |
| 927 | if (unlikely(SError & 0xFFFF0000)) { | 976 | if (unlikely(SError & 0xFFFF0000)) { |
| 928 | sata_fsl_scr_write(ap, SCR_ERROR, SError); | 977 | sata_fsl_scr_write(ap, SCR_ERROR, SError); |
| 929 | err_mask |= AC_ERR_ATA_BUS; | ||
| 930 | } | 978 | } |
| 931 | 979 | ||
| 932 | DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", | 980 | DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", |
| 933 | hstatus, cereg, ioread32(hcr_base + DE), SError); | 981 | hstatus, cereg, ioread32(hcr_base + DE), SError); |
| 934 | 982 | ||
| 935 | /* handle single device errors */ | 983 | /* handle fatal errors */ |
| 936 | if (cereg) { | 984 | if (hstatus & FATAL_ERROR_DECODE) { |
| 937 | /* | 985 | ehi->err_mask |= AC_ERR_ATA_BUS; |
| 938 | * clear the command error, also clears queue to the device | 986 | ehi->action |= ATA_EH_SOFTRESET; |
| 939 | * in error, and we can (re)issue commands to this device. | ||
| 940 | * When a device is in error all commands queued into the | ||
| 941 | * host controller and at the device are considered aborted | ||
| 942 | * and the queue for that device is stopped. Now, after | ||
| 943 | * clearing the device error, we can issue commands to the | ||
| 944 | * device to interrogate it to find the source of the error. | ||
| 945 | */ | ||
| 946 | dereg = ioread32(hcr_base + DE); | ||
| 947 | iowrite32(dereg, hcr_base + DE); | ||
| 948 | iowrite32(cereg, hcr_base + CE); | ||
| 949 | 987 | ||
| 950 | DPRINTK("single device error, CE=0x%x, DE=0x%x\n", | ||
| 951 | ioread32(hcr_base + CE), ioread32(hcr_base + DE)); | ||
| 952 | /* | 988 | /* |
| 953 | * We should consider this as non fatal error, and TF must | 989 | * Ignore serror in case of fatal errors as we always want |
| 954 | * be updated as done below. | 990 | * to do a soft-reset of the FSL SATA controller. Analyzing |
| 991 | * serror may cause libata to schedule a hard-reset action, | ||
| 992 | * and hard-reset currently does not do controller | ||
| 993 | * offline/online, causing command timeouts and leads to an | ||
| 994 | * un-recoverable state, hence make libATA ignore | ||
| 995 | * autopsy in case of fatal errors. | ||
| 955 | */ | 996 | */ |
| 956 | 997 | ||
| 957 | err_mask |= AC_ERR_DEV; | 998 | ehi->flags |= ATA_EHI_NO_AUTOPSY; |
| 958 | } | ||
| 959 | 999 | ||
| 960 | /* handle fatal errors */ | ||
| 961 | if (hstatus & FATAL_ERROR_DECODE) { | ||
| 962 | err_mask |= AC_ERR_ATA_BUS; | ||
| 963 | action |= ATA_EH_RESET; | ||
| 964 | /* how will fatal error interrupts be completed ?? */ | ||
| 965 | freeze = 1; | 1000 | freeze = 1; |
| 966 | } | 1001 | } |
| 967 | 1002 | ||
| @@ -971,30 +1006,83 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
| 971 | 1006 | ||
| 972 | /* Setup a soft-reset EH action */ | 1007 | /* Setup a soft-reset EH action */ |
| 973 | ata_ehi_hotplugged(ehi); | 1008 | ata_ehi_hotplugged(ehi); |
| 1009 | ata_ehi_push_desc(ehi, "%s", "PHY RDY changed"); | ||
| 974 | freeze = 1; | 1010 | freeze = 1; |
| 975 | } | 1011 | } |
| 976 | 1012 | ||
| 977 | /* record error info */ | 1013 | /* handle single device errors */ |
| 978 | qc = ata_qc_from_tag(ap, link->active_tag); | 1014 | if (cereg) { |
| 1015 | /* | ||
| 1016 | * clear the command error, also clears queue to the device | ||
| 1017 | * in error, and we can (re)issue commands to this device. | ||
| 1018 | * When a device is in error all commands queued into the | ||
| 1019 | * host controller and at the device are considered aborted | ||
| 1020 | * and the queue for that device is stopped. Now, after | ||
| 1021 | * clearing the device error, we can issue commands to the | ||
| 1022 | * device to interrogate it to find the source of the error. | ||
| 1023 | */ | ||
| 1024 | abort = 1; | ||
| 1025 | |||
| 1026 | DPRINTK("single device error, CE=0x%x, DE=0x%x\n", | ||
| 1027 | ioread32(hcr_base + CE), ioread32(hcr_base + DE)); | ||
| 979 | 1028 | ||
| 980 | if (qc) | 1029 | /* find out the offending link and qc */ |
| 1030 | if (ap->nr_pmp_links) { | ||
| 1031 | dereg = ioread32(hcr_base + DE); | ||
| 1032 | iowrite32(dereg, hcr_base + DE); | ||
| 1033 | iowrite32(cereg, hcr_base + CE); | ||
| 1034 | |||
| 1035 | if (dereg < ap->nr_pmp_links) { | ||
| 1036 | link = &ap->pmp_link[dereg]; | ||
| 1037 | ehi = &link->eh_info; | ||
| 1038 | qc = ata_qc_from_tag(ap, link->active_tag); | ||
| 1039 | /* | ||
| 1040 | * We should consider this as non fatal error, | ||
| 1041 | * and TF must be updated as done below. | ||
| 1042 | */ | ||
| 1043 | |||
| 1044 | err_mask |= AC_ERR_DEV; | ||
| 1045 | |||
| 1046 | } else { | ||
| 1047 | err_mask |= AC_ERR_HSM; | ||
| 1048 | action |= ATA_EH_HARDRESET; | ||
| 1049 | freeze = 1; | ||
| 1050 | } | ||
| 1051 | } else { | ||
| 1052 | dereg = ioread32(hcr_base + DE); | ||
| 1053 | iowrite32(dereg, hcr_base + DE); | ||
| 1054 | iowrite32(cereg, hcr_base + CE); | ||
| 1055 | |||
| 1056 | qc = ata_qc_from_tag(ap, link->active_tag); | ||
| 1057 | /* | ||
| 1058 | * We should consider this as non fatal error, | ||
| 1059 | * and TF must be updated as done below. | ||
| 1060 | */ | ||
| 1061 | err_mask |= AC_ERR_DEV; | ||
| 1062 | } | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* record error info */ | ||
| 1066 | if (qc) { | ||
| 981 | qc->err_mask |= err_mask; | 1067 | qc->err_mask |= err_mask; |
| 982 | else | 1068 | } else |
| 983 | ehi->err_mask |= err_mask; | 1069 | ehi->err_mask |= err_mask; |
| 984 | 1070 | ||
| 985 | ehi->action |= action; | 1071 | ehi->action |= action; |
| 986 | ehi->serror |= SError; | ||
| 987 | 1072 | ||
| 988 | /* freeze or abort */ | 1073 | /* freeze or abort */ |
| 989 | if (freeze) | 1074 | if (freeze) |
| 990 | ata_port_freeze(ap); | 1075 | ata_port_freeze(ap); |
| 991 | else | 1076 | else if (abort) { |
| 992 | ata_port_abort(ap); | 1077 | if (qc) |
| 1078 | ata_link_abort(qc->dev->link); | ||
| 1079 | else | ||
| 1080 | ata_port_abort(ap); | ||
| 1081 | } | ||
| 993 | } | 1082 | } |
| 994 | 1083 | ||
| 995 | static void sata_fsl_host_intr(struct ata_port *ap) | 1084 | static void sata_fsl_host_intr(struct ata_port *ap) |
| 996 | { | 1085 | { |
| 997 | struct ata_link *link = &ap->link; | ||
| 998 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 1086 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
| 999 | void __iomem *hcr_base = host_priv->hcr_base; | 1087 | void __iomem *hcr_base = host_priv->hcr_base; |
| 1000 | u32 hstatus, qc_active = 0; | 1088 | u32 hstatus, qc_active = 0; |
| @@ -1017,10 +1105,19 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
| 1017 | return; | 1105 | return; |
| 1018 | } | 1106 | } |
| 1019 | 1107 | ||
| 1020 | if (link->sactive) { /* only true for NCQ commands */ | 1108 | /* Read command completed register */ |
| 1109 | qc_active = ioread32(hcr_base + CC); | ||
| 1110 | |||
| 1111 | VPRINTK("Status of all queues :\n"); | ||
| 1112 | VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", | ||
| 1113 | qc_active, | ||
| 1114 | ioread32(hcr_base + CA), | ||
| 1115 | ioread32(hcr_base + CE), | ||
| 1116 | ioread32(hcr_base + CQ), | ||
| 1117 | ap->qc_active); | ||
| 1118 | |||
| 1119 | if (qc_active & ap->qc_active) { | ||
| 1021 | int i; | 1120 | int i; |
| 1022 | /* Read command completed register */ | ||
| 1023 | qc_active = ioread32(hcr_base + CC); | ||
| 1024 | /* clear CC bit, this will also complete the interrupt */ | 1121 | /* clear CC bit, this will also complete the interrupt */ |
| 1025 | iowrite32(qc_active, hcr_base + CC); | 1122 | iowrite32(qc_active, hcr_base + CC); |
| 1026 | 1123 | ||
| @@ -1032,8 +1129,9 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
| 1032 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { | 1129 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { |
| 1033 | if (qc_active & (1 << i)) { | 1130 | if (qc_active & (1 << i)) { |
| 1034 | qc = ata_qc_from_tag(ap, i); | 1131 | qc = ata_qc_from_tag(ap, i); |
| 1035 | if (qc) | 1132 | if (qc) { |
| 1036 | ata_qc_complete(qc); | 1133 | ata_qc_complete(qc); |
| 1134 | } | ||
| 1037 | DPRINTK | 1135 | DPRINTK |
| 1038 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", | 1136 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", |
| 1039 | i, ioread32(hcr_base + CC), | 1137 | i, ioread32(hcr_base + CC), |
| @@ -1042,19 +1140,21 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
| 1042 | } | 1140 | } |
| 1043 | return; | 1141 | return; |
| 1044 | 1142 | ||
| 1045 | } else if (ap->qc_active) { | 1143 | } else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) { |
| 1046 | iowrite32(1, hcr_base + CC); | 1144 | iowrite32(1, hcr_base + CC); |
| 1047 | qc = ata_qc_from_tag(ap, link->active_tag); | 1145 | qc = ata_qc_from_tag(ap, ATA_TAG_INTERNAL); |
| 1048 | 1146 | ||
| 1049 | DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", | 1147 | DPRINTK("completing non-ncq cmd, CC=0x%x\n", |
| 1050 | link->active_tag, ioread32(hcr_base + CC)); | 1148 | ioread32(hcr_base + CC)); |
| 1051 | 1149 | ||
| 1052 | if (qc) | 1150 | if (qc) { |
| 1053 | ata_qc_complete(qc); | 1151 | ata_qc_complete(qc); |
| 1152 | } | ||
| 1054 | } else { | 1153 | } else { |
| 1055 | /* Spurious Interrupt!! */ | 1154 | /* Spurious Interrupt!! */ |
| 1056 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", | 1155 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", |
| 1057 | ioread32(hcr_base + CC)); | 1156 | ioread32(hcr_base + CC)); |
| 1157 | iowrite32(qc_active, hcr_base + CC); | ||
| 1058 | return; | 1158 | return; |
| 1059 | } | 1159 | } |
| 1060 | } | 1160 | } |
| @@ -1130,9 +1230,6 @@ static int sata_fsl_init_controller(struct ata_host *host) | |||
| 1130 | iowrite32(0x00000FFFF, hcr_base + CE); | 1230 | iowrite32(0x00000FFFF, hcr_base + CE); |
| 1131 | iowrite32(0x00000FFFF, hcr_base + DE); | 1231 | iowrite32(0x00000FFFF, hcr_base + DE); |
| 1132 | 1232 | ||
| 1133 | /* initially assuming no Port multiplier, set CQPMP to 0 */ | ||
| 1134 | iowrite32(0x0, hcr_base + CQPMP); | ||
| 1135 | |||
| 1136 | /* | 1233 | /* |
| 1137 | * host controller will be brought on-line, during xx_port_start() | 1234 | * host controller will be brought on-line, during xx_port_start() |
| 1138 | * callback, that should also initiate the OOB, COMINIT sequence | 1235 | * callback, that should also initiate the OOB, COMINIT sequence |
| @@ -1154,8 +1251,8 @@ static struct scsi_host_template sata_fsl_sht = { | |||
| 1154 | .dma_boundary = ATA_DMA_BOUNDARY, | 1251 | .dma_boundary = ATA_DMA_BOUNDARY, |
| 1155 | }; | 1252 | }; |
| 1156 | 1253 | ||
| 1157 | static const struct ata_port_operations sata_fsl_ops = { | 1254 | static struct ata_port_operations sata_fsl_ops = { |
| 1158 | .inherits = &sata_port_ops, | 1255 | .inherits = &sata_pmp_port_ops, |
| 1159 | 1256 | ||
| 1160 | .qc_prep = sata_fsl_qc_prep, | 1257 | .qc_prep = sata_fsl_qc_prep, |
| 1161 | .qc_issue = sata_fsl_qc_issue, | 1258 | .qc_issue = sata_fsl_qc_issue, |
| @@ -1168,10 +1265,15 @@ static const struct ata_port_operations sata_fsl_ops = { | |||
| 1168 | .thaw = sata_fsl_thaw, | 1265 | .thaw = sata_fsl_thaw, |
| 1169 | .prereset = sata_fsl_prereset, | 1266 | .prereset = sata_fsl_prereset, |
| 1170 | .softreset = sata_fsl_softreset, | 1267 | .softreset = sata_fsl_softreset, |
| 1268 | .pmp_softreset = sata_fsl_softreset, | ||
| 1269 | .error_handler = sata_fsl_error_handler, | ||
| 1171 | .post_internal_cmd = sata_fsl_post_internal_cmd, | 1270 | .post_internal_cmd = sata_fsl_post_internal_cmd, |
| 1172 | 1271 | ||
| 1173 | .port_start = sata_fsl_port_start, | 1272 | .port_start = sata_fsl_port_start, |
| 1174 | .port_stop = sata_fsl_port_stop, | 1273 | .port_stop = sata_fsl_port_stop, |
| 1274 | |||
| 1275 | .pmp_attach = sata_fsl_pmp_attach, | ||
| 1276 | .pmp_detach = sata_fsl_pmp_detach, | ||
| 1175 | }; | 1277 | }; |
| 1176 | 1278 | ||
| 1177 | static const struct ata_port_info sata_fsl_port_info[] = { | 1279 | static const struct ata_port_info sata_fsl_port_info[] = { |
