diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 13 | ||||
| -rw-r--r-- | drivers/ata/sata_fsl.c | 8 | ||||
| -rw-r--r-- | drivers/ata/sata_mv.c | 25 | ||||
| -rw-r--r-- | drivers/ata/sata_nv.c | 57 |
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 | ||
| 2746 | static void mv_process_crpb_response(struct ata_port *ap, | 2746 | static 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 | ||
| 2780 | static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) | 2774 | static 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 | ||
| 2817 | static void mv_port_intr(struct ata_port *ap, u32 port_cause) | 2816 | static 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"); |
