aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c13
-rw-r--r--drivers/ata/sata_fsl.c8
-rw-r--r--drivers/ata/sata_mv.c25
-rw-r--r--drivers/ata/sata_nv.c57
4 files changed, 38 insertions, 65 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 4012b33e8b8a..92cd5f375b8f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4943,8 +4943,13 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
4943 * ata_qc_complete - Complete an active ATA command 4943 * ata_qc_complete - Complete an active ATA command
4944 * @qc: Command to complete 4944 * @qc: Command to complete
4945 * 4945 *
4946 * Indicate to the mid and upper layers that an ATA 4946 * Indicate to the mid and upper layers that an ATA command has
4947 * command has completed, with either an ok or not-ok status. 4947 * completed, with either an ok or not-ok status.
4948 *
4949 * Refrain from calling this function multiple times when
4950 * successfully completing multiple NCQ commands.
4951 * ata_qc_complete_multiple() should be used instead, which will
4952 * properly update IRQ expect state.
4948 * 4953 *
4949 * LOCKING: 4954 * LOCKING:
4950 * spin_lock_irqsave(host lock) 4955 * spin_lock_irqsave(host lock)
@@ -5037,6 +5042,10 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
5037 * requests normally. ap->qc_active and @qc_active is compared 5042 * requests normally. ap->qc_active and @qc_active is compared
5038 * and commands are completed accordingly. 5043 * and commands are completed accordingly.
5039 * 5044 *
5045 * Always use this function when completing multiple NCQ commands
5046 * from IRQ handlers instead of calling ata_qc_complete()
5047 * multiple times to keep IRQ expect status properly in sync.
5048 *
5040 * LOCKING: 5049 * LOCKING:
5041 * spin_lock_irqsave(host lock) 5050 * spin_lock_irqsave(host lock)
5042 * 5051 *
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 7325f77480dc..1440dc0af242 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1137,17 +1137,13 @@ static void sata_fsl_host_intr(struct ata_port *ap)
1137 ioread32(hcr_base + CE)); 1137 ioread32(hcr_base + CE));
1138 1138
1139 for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { 1139 for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
1140 if (done_mask & (1 << i)) { 1140 if (done_mask & (1 << i))
1141 qc = ata_qc_from_tag(ap, i);
1142 if (qc) {
1143 ata_qc_complete(qc);
1144 }
1145 DPRINTK 1141 DPRINTK
1146 ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", 1142 ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
1147 i, ioread32(hcr_base + CC), 1143 i, ioread32(hcr_base + CC),
1148 ioread32(hcr_base + CA)); 1144 ioread32(hcr_base + CA));
1149 }
1150 } 1145 }
1146 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
1151 return; 1147 return;
1152 1148
1153 } else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) { 1149 } else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) {
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index a9fd9709c262..bf74a36d3cc3 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2743,18 +2743,11 @@ static void mv_err_intr(struct ata_port *ap)
2743 } 2743 }
2744} 2744}
2745 2745
2746static void mv_process_crpb_response(struct ata_port *ap, 2746static bool mv_process_crpb_response(struct ata_port *ap,
2747 struct mv_crpb *response, unsigned int tag, int ncq_enabled) 2747 struct mv_crpb *response, unsigned int tag, int ncq_enabled)
2748{ 2748{
2749 u8 ata_status; 2749 u8 ata_status;
2750 u16 edma_status = le16_to_cpu(response->flags); 2750 u16 edma_status = le16_to_cpu(response->flags);
2751 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
2752
2753 if (unlikely(!qc)) {
2754 ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n",
2755 __func__, tag);
2756 return;
2757 }
2758 2751
2759 /* 2752 /*
2760 * edma_status from a response queue entry: 2753 * edma_status from a response queue entry:
@@ -2768,13 +2761,14 @@ static void mv_process_crpb_response(struct ata_port *ap,
2768 * Error will be seen/handled by 2761 * Error will be seen/handled by
2769 * mv_err_intr(). So do nothing at all here. 2762 * mv_err_intr(). So do nothing at all here.
2770 */ 2763 */
2771 return; 2764 return false;
2772 } 2765 }
2773 } 2766 }
2774 ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; 2767 ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT;
2775 if (!ac_err_mask(ata_status)) 2768 if (!ac_err_mask(ata_status))
2776 ata_qc_complete(qc); 2769 return true;
2777 /* else: leave it for mv_err_intr() */ 2770 /* else: leave it for mv_err_intr() */
2771 return false;
2778} 2772}
2779 2773
2780static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) 2774static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp)
@@ -2783,6 +2777,7 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
2783 struct mv_host_priv *hpriv = ap->host->private_data; 2777 struct mv_host_priv *hpriv = ap->host->private_data;
2784 u32 in_index; 2778 u32 in_index;
2785 bool work_done = false; 2779 bool work_done = false;
2780 u32 done_mask = 0;
2786 int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN); 2781 int ncq_enabled = (pp->pp_flags & MV_PP_FLAG_NCQ_EN);
2787 2782
2788 /* Get the hardware queue position index */ 2783 /* Get the hardware queue position index */
@@ -2803,15 +2798,19 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp
2803 /* Gen II/IIE: get command tag from CRPB entry */ 2798 /* Gen II/IIE: get command tag from CRPB entry */
2804 tag = le16_to_cpu(response->id) & 0x1f; 2799 tag = le16_to_cpu(response->id) & 0x1f;
2805 } 2800 }
2806 mv_process_crpb_response(ap, response, tag, ncq_enabled); 2801 if (mv_process_crpb_response(ap, response, tag, ncq_enabled))
2802 done_mask |= 1 << tag;
2807 work_done = true; 2803 work_done = true;
2808 } 2804 }
2809 2805
2810 /* Update the software queue position index in hardware */ 2806 if (work_done) {
2811 if (work_done) 2807 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
2808
2809 /* Update the software queue position index in hardware */
2812 writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | 2810 writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
2813 (pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT), 2811 (pp->resp_idx << EDMA_RSP_Q_PTR_SHIFT),
2814 port_mmio + EDMA_RSP_Q_OUT_PTR); 2812 port_mmio + EDMA_RSP_Q_OUT_PTR);
2813 }
2815} 2814}
2816 2815
2817static void mv_port_intr(struct ata_port *ap, u32 port_cause) 2816static void mv_port_intr(struct ata_port *ap, u32 port_cause)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index cb89ef8d99d9..7254e255fd78 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -873,29 +873,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
873 ata_port_freeze(ap); 873 ata_port_freeze(ap);
874 else 874 else
875 ata_port_abort(ap); 875 ata_port_abort(ap);
876 return 1; 876 return -1;
877 } 877 }
878 878
879 if (likely(flags & NV_CPB_RESP_DONE)) { 879 if (likely(flags & NV_CPB_RESP_DONE))
880 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); 880 return 1;
881 VPRINTK("CPB flags done, flags=0x%x\n", flags);
882 if (likely(qc)) {
883 DPRINTK("Completing qc from tag %d\n", cpb_num);
884 ata_qc_complete(qc);
885 } else {
886 struct ata_eh_info *ehi = &ap->link.eh_info;
887 /* Notifier bits set without a command may indicate the drive
888 is misbehaving. Raise host state machine violation on this
889 condition. */
890 ata_port_printk(ap, KERN_ERR,
891 "notifier for tag %d with no cmd?\n",
892 cpb_num);
893 ehi->err_mask |= AC_ERR_HSM;
894 ehi->action |= ATA_EH_RESET;
895 ata_port_freeze(ap);
896 return 1;
897 }
898 }
899 return 0; 881 return 0;
900} 882}
901 883
@@ -1018,6 +1000,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
1018 NV_ADMA_STAT_CPBERR | 1000 NV_ADMA_STAT_CPBERR |
1019 NV_ADMA_STAT_CMD_COMPLETE)) { 1001 NV_ADMA_STAT_CMD_COMPLETE)) {
1020 u32 check_commands = notifier_clears[i]; 1002 u32 check_commands = notifier_clears[i];
1003 u32 done_mask = 0;
1021 int pos, rc; 1004 int pos, rc;
1022 1005
1023 if (status & NV_ADMA_STAT_CPBERR) { 1006 if (status & NV_ADMA_STAT_CPBERR) {
@@ -1034,10 +1017,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
1034 pos--; 1017 pos--;
1035 rc = nv_adma_check_cpb(ap, pos, 1018 rc = nv_adma_check_cpb(ap, pos,
1036 notifier_error & (1 << pos)); 1019 notifier_error & (1 << pos));
1037 if (unlikely(rc)) 1020 if (rc > 0)
1021 done_mask |= 1 << pos;
1022 else if (unlikely(rc < 0))
1038 check_commands = 0; 1023 check_commands = 0;
1039 check_commands &= ~(1 << pos); 1024 check_commands &= ~(1 << pos);
1040 } 1025 }
1026 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
1041 } 1027 }
1042 } 1028 }
1043 1029
@@ -2132,7 +2118,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2132 struct ata_eh_info *ehi = &ap->link.eh_info; 2118 struct ata_eh_info *ehi = &ap->link.eh_info;
2133 u32 sactive; 2119 u32 sactive;
2134 u32 done_mask; 2120 u32 done_mask;
2135 int i;
2136 u8 host_stat; 2121 u8 host_stat;
2137 u8 lack_dhfis = 0; 2122 u8 lack_dhfis = 0;
2138 2123
@@ -2152,27 +2137,11 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2152 sactive = readl(pp->sactive_block); 2137 sactive = readl(pp->sactive_block);
2153 done_mask = pp->qc_active ^ sactive; 2138 done_mask = pp->qc_active ^ sactive;
2154 2139
2155 if (unlikely(done_mask & sactive)) { 2140 pp->qc_active &= ~done_mask;
2156 ata_ehi_clear_desc(ehi); 2141 pp->dhfis_bits &= ~done_mask;
2157 ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition" 2142 pp->dmafis_bits &= ~done_mask;
2158 "(%08x->%08x)", pp->qc_active, sactive); 2143 pp->sdbfis_bits |= done_mask;
2159 ehi->err_mask |= AC_ERR_HSM; 2144 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
2160 ehi->action |= ATA_EH_RESET;
2161 return -EINVAL;
2162 }
2163 for (i = 0; i < ATA_MAX_QUEUE; i++) {
2164 if (!(done_mask & (1 << i)))
2165 continue;
2166
2167 qc = ata_qc_from_tag(ap, i);
2168 if (qc) {
2169 ata_qc_complete(qc);
2170 pp->qc_active &= ~(1 << i);
2171 pp->dhfis_bits &= ~(1 << i);
2172 pp->dmafis_bits &= ~(1 << i);
2173 pp->sdbfis_bits |= (1 << i);
2174 }
2175 }
2176 2145
2177 if (!ap->qc_active) { 2146 if (!ap->qc_active) {
2178 DPRINTK("over\n"); 2147 DPRINTK("over\n");