diff options
-rw-r--r-- | drivers/ata/sata_fsl.c | 20 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 47 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 32 |
3 files changed, 48 insertions, 51 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 61c89b54ea23..18c986dbb7f1 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -1096,7 +1096,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1096 | { | 1096 | { |
1097 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 1097 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
1098 | void __iomem *hcr_base = host_priv->hcr_base; | 1098 | void __iomem *hcr_base = host_priv->hcr_base; |
1099 | u32 hstatus, qc_active = 0; | 1099 | u32 hstatus, done_mask = 0; |
1100 | struct ata_queued_cmd *qc; | 1100 | struct ata_queued_cmd *qc; |
1101 | u32 SError; | 1101 | u32 SError; |
1102 | 1102 | ||
@@ -1116,28 +1116,28 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | /* Read command completed register */ | 1118 | /* Read command completed register */ |
1119 | qc_active = ioread32(hcr_base + CC); | 1119 | done_mask = ioread32(hcr_base + CC); |
1120 | 1120 | ||
1121 | VPRINTK("Status of all queues :\n"); | 1121 | VPRINTK("Status of all queues :\n"); |
1122 | VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", | 1122 | VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", |
1123 | qc_active, | 1123 | done_mask, |
1124 | ioread32(hcr_base + CA), | 1124 | ioread32(hcr_base + CA), |
1125 | ioread32(hcr_base + CE), | 1125 | ioread32(hcr_base + CE), |
1126 | ioread32(hcr_base + CQ), | 1126 | ioread32(hcr_base + CQ), |
1127 | ap->qc_active); | 1127 | ap->qc_active); |
1128 | 1128 | ||
1129 | if (qc_active & ap->qc_active) { | 1129 | if (done_mask & ap->qc_active) { |
1130 | int i; | 1130 | int i; |
1131 | /* clear CC bit, this will also complete the interrupt */ | 1131 | /* clear CC bit, this will also complete the interrupt */ |
1132 | iowrite32(qc_active, hcr_base + CC); | 1132 | iowrite32(done_mask, hcr_base + CC); |
1133 | 1133 | ||
1134 | DPRINTK("Status of all queues :\n"); | 1134 | DPRINTK("Status of all queues :\n"); |
1135 | DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n", | 1135 | DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n", |
1136 | qc_active, ioread32(hcr_base + CA), | 1136 | done_mask, ioread32(hcr_base + CA), |
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 (qc_active & (1 << i)) { | 1140 | if (done_mask & (1 << i)) { |
1141 | qc = ata_qc_from_tag(ap, i); | 1141 | qc = ata_qc_from_tag(ap, i); |
1142 | if (qc) { | 1142 | if (qc) { |
1143 | ata_qc_complete(qc); | 1143 | ata_qc_complete(qc); |
@@ -1164,7 +1164,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1164 | /* Spurious Interrupt!! */ | 1164 | /* Spurious Interrupt!! */ |
1165 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", | 1165 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", |
1166 | ioread32(hcr_base + CC)); | 1166 | ioread32(hcr_base + CC)); |
1167 | iowrite32(qc_active, hcr_base + CC); | 1167 | iowrite32(done_mask, hcr_base + CC); |
1168 | return; | 1168 | return; |
1169 | } | 1169 | } |
1170 | } | 1170 | } |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a476cd99b95d..9463c71dd38e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -2716,34 +2716,35 @@ static void mv_err_intr(struct ata_port *ap) | |||
2716 | static void mv_process_crpb_response(struct ata_port *ap, | 2716 | static void mv_process_crpb_response(struct ata_port *ap, |
2717 | struct mv_crpb *response, unsigned int tag, int ncq_enabled) | 2717 | struct mv_crpb *response, unsigned int tag, int ncq_enabled) |
2718 | { | 2718 | { |
2719 | u8 ata_status; | ||
2720 | u16 edma_status = le16_to_cpu(response->flags); | ||
2719 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); | 2721 | struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); |
2720 | 2722 | ||
2721 | if (qc) { | 2723 | if (unlikely(!qc)) { |
2722 | u8 ata_status; | ||
2723 | u16 edma_status = le16_to_cpu(response->flags); | ||
2724 | /* | ||
2725 | * edma_status from a response queue entry: | ||
2726 | * LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only). | ||
2727 | * MSB is saved ATA status from command completion. | ||
2728 | */ | ||
2729 | if (!ncq_enabled) { | ||
2730 | u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV; | ||
2731 | if (err_cause) { | ||
2732 | /* | ||
2733 | * Error will be seen/handled by mv_err_intr(). | ||
2734 | * So do nothing at all here. | ||
2735 | */ | ||
2736 | return; | ||
2737 | } | ||
2738 | } | ||
2739 | ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; | ||
2740 | if (!ac_err_mask(ata_status)) | ||
2741 | ata_qc_complete(qc); | ||
2742 | /* else: leave it for mv_err_intr() */ | ||
2743 | } else { | ||
2744 | ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", | 2724 | ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", |
2745 | __func__, tag); | 2725 | __func__, tag); |
2726 | return; | ||
2727 | } | ||
2728 | |||
2729 | /* | ||
2730 | * edma_status from a response queue entry: | ||
2731 | * LSB is from EDMA_ERR_IRQ_CAUSE (non-NCQ only). | ||
2732 | * MSB is saved ATA status from command completion. | ||
2733 | */ | ||
2734 | if (!ncq_enabled) { | ||
2735 | u8 err_cause = edma_status & 0xff & ~EDMA_ERR_DEV; | ||
2736 | if (err_cause) { | ||
2737 | /* | ||
2738 | * Error will be seen/handled by | ||
2739 | * mv_err_intr(). So do nothing at all here. | ||
2740 | */ | ||
2741 | return; | ||
2742 | } | ||
2746 | } | 2743 | } |
2744 | ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; | ||
2745 | if (!ac_err_mask(ata_status)) | ||
2746 | ata_qc_complete(qc); | ||
2747 | /* else: leave it for mv_err_intr() */ | ||
2747 | } | 2748 | } |
2748 | 2749 | ||
2749 | static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) | 2750 | static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp) |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 21161136cad0..cb89ef8d99d9 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -1018,7 +1018,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
1018 | NV_ADMA_STAT_CPBERR | | 1018 | NV_ADMA_STAT_CPBERR | |
1019 | NV_ADMA_STAT_CMD_COMPLETE)) { | 1019 | NV_ADMA_STAT_CMD_COMPLETE)) { |
1020 | u32 check_commands = notifier_clears[i]; | 1020 | u32 check_commands = notifier_clears[i]; |
1021 | int pos, error = 0; | 1021 | int pos, rc; |
1022 | 1022 | ||
1023 | if (status & NV_ADMA_STAT_CPBERR) { | 1023 | if (status & NV_ADMA_STAT_CPBERR) { |
1024 | /* check all active commands */ | 1024 | /* check all active commands */ |
@@ -1030,10 +1030,12 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | |||
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | /* check CPBs for completed commands */ | 1032 | /* check CPBs for completed commands */ |
1033 | while ((pos = ffs(check_commands)) && !error) { | 1033 | while ((pos = ffs(check_commands))) { |
1034 | pos--; | 1034 | pos--; |
1035 | error = nv_adma_check_cpb(ap, pos, | 1035 | rc = nv_adma_check_cpb(ap, pos, |
1036 | notifier_error & (1 << pos)); | 1036 | notifier_error & (1 << pos)); |
1037 | if (unlikely(rc)) | ||
1038 | check_commands = 0; | ||
1037 | check_commands &= ~(1 << pos); | 1039 | check_commands &= ~(1 << pos); |
1038 | } | 1040 | } |
1039 | } | 1041 | } |
@@ -2129,7 +2131,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap) | |||
2129 | struct nv_swncq_port_priv *pp = ap->private_data; | 2131 | struct nv_swncq_port_priv *pp = ap->private_data; |
2130 | struct ata_eh_info *ehi = &ap->link.eh_info; | 2132 | struct ata_eh_info *ehi = &ap->link.eh_info; |
2131 | u32 sactive; | 2133 | u32 sactive; |
2132 | int nr_done = 0; | ||
2133 | u32 done_mask; | 2134 | u32 done_mask; |
2134 | int i; | 2135 | int i; |
2135 | u8 host_stat; | 2136 | u8 host_stat; |
@@ -2170,22 +2171,21 @@ static int nv_swncq_sdbfis(struct ata_port *ap) | |||
2170 | pp->dhfis_bits &= ~(1 << i); | 2171 | pp->dhfis_bits &= ~(1 << i); |
2171 | pp->dmafis_bits &= ~(1 << i); | 2172 | pp->dmafis_bits &= ~(1 << i); |
2172 | pp->sdbfis_bits |= (1 << i); | 2173 | pp->sdbfis_bits |= (1 << i); |
2173 | nr_done++; | ||
2174 | } | 2174 | } |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | if (!ap->qc_active) { | 2177 | if (!ap->qc_active) { |
2178 | DPRINTK("over\n"); | 2178 | DPRINTK("over\n"); |
2179 | nv_swncq_pp_reinit(ap); | 2179 | nv_swncq_pp_reinit(ap); |
2180 | return nr_done; | 2180 | return 0; |
2181 | } | 2181 | } |
2182 | 2182 | ||
2183 | if (pp->qc_active & pp->dhfis_bits) | 2183 | if (pp->qc_active & pp->dhfis_bits) |
2184 | return nr_done; | 2184 | return 0; |
2185 | 2185 | ||
2186 | if ((pp->ncq_flags & ncq_saw_backout) || | 2186 | if ((pp->ncq_flags & ncq_saw_backout) || |
2187 | (pp->qc_active ^ pp->dhfis_bits)) | 2187 | (pp->qc_active ^ pp->dhfis_bits)) |
2188 | /* if the controller cann't get a device to host register FIS, | 2188 | /* if the controller can't get a device to host register FIS, |
2189 | * The driver needs to reissue the new command. | 2189 | * The driver needs to reissue the new command. |
2190 | */ | 2190 | */ |
2191 | lack_dhfis = 1; | 2191 | lack_dhfis = 1; |
@@ -2202,7 +2202,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) | |||
2202 | if (lack_dhfis) { | 2202 | if (lack_dhfis) { |
2203 | qc = ata_qc_from_tag(ap, pp->last_issue_tag); | 2203 | qc = ata_qc_from_tag(ap, pp->last_issue_tag); |
2204 | nv_swncq_issue_atacmd(ap, qc); | 2204 | nv_swncq_issue_atacmd(ap, qc); |
2205 | return nr_done; | 2205 | return 0; |
2206 | } | 2206 | } |
2207 | 2207 | ||
2208 | if (pp->defer_queue.defer_bits) { | 2208 | if (pp->defer_queue.defer_bits) { |
@@ -2212,7 +2212,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) | |||
2212 | nv_swncq_issue_atacmd(ap, qc); | 2212 | nv_swncq_issue_atacmd(ap, qc); |
2213 | } | 2213 | } |
2214 | 2214 | ||
2215 | return nr_done; | 2215 | return 0; |
2216 | } | 2216 | } |
2217 | 2217 | ||
2218 | static inline u32 nv_swncq_tag(struct ata_port *ap) | 2218 | static inline u32 nv_swncq_tag(struct ata_port *ap) |
@@ -2224,7 +2224,7 @@ static inline u32 nv_swncq_tag(struct ata_port *ap) | |||
2224 | return (tag & 0x1f); | 2224 | return (tag & 0x1f); |
2225 | } | 2225 | } |
2226 | 2226 | ||
2227 | static int nv_swncq_dmafis(struct ata_port *ap) | 2227 | static void nv_swncq_dmafis(struct ata_port *ap) |
2228 | { | 2228 | { |
2229 | struct ata_queued_cmd *qc; | 2229 | struct ata_queued_cmd *qc; |
2230 | unsigned int rw; | 2230 | unsigned int rw; |
@@ -2239,7 +2239,7 @@ static int nv_swncq_dmafis(struct ata_port *ap) | |||
2239 | qc = ata_qc_from_tag(ap, tag); | 2239 | qc = ata_qc_from_tag(ap, tag); |
2240 | 2240 | ||
2241 | if (unlikely(!qc)) | 2241 | if (unlikely(!qc)) |
2242 | return 0; | 2242 | return; |
2243 | 2243 | ||
2244 | rw = qc->tf.flags & ATA_TFLAG_WRITE; | 2244 | rw = qc->tf.flags & ATA_TFLAG_WRITE; |
2245 | 2245 | ||
@@ -2254,8 +2254,6 @@ static int nv_swncq_dmafis(struct ata_port *ap) | |||
2254 | dmactl |= ATA_DMA_WR; | 2254 | dmactl |= ATA_DMA_WR; |
2255 | 2255 | ||
2256 | iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); | 2256 | iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); |
2257 | |||
2258 | return 1; | ||
2259 | } | 2257 | } |
2260 | 2258 | ||
2261 | static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) | 2259 | static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) |
@@ -2265,7 +2263,6 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) | |||
2265 | struct ata_eh_info *ehi = &ap->link.eh_info; | 2263 | struct ata_eh_info *ehi = &ap->link.eh_info; |
2266 | u32 serror; | 2264 | u32 serror; |
2267 | u8 ata_stat; | 2265 | u8 ata_stat; |
2268 | int rc = 0; | ||
2269 | 2266 | ||
2270 | ata_stat = ap->ops->sff_check_status(ap); | 2267 | ata_stat = ap->ops->sff_check_status(ap); |
2271 | nv_swncq_irq_clear(ap, fis); | 2268 | nv_swncq_irq_clear(ap, fis); |
@@ -2310,8 +2307,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) | |||
2310 | "dhfis 0x%X dmafis 0x%X sactive 0x%X\n", | 2307 | "dhfis 0x%X dmafis 0x%X sactive 0x%X\n", |
2311 | ap->print_id, pp->qc_active, pp->dhfis_bits, | 2308 | ap->print_id, pp->qc_active, pp->dhfis_bits, |
2312 | pp->dmafis_bits, readl(pp->sactive_block)); | 2309 | pp->dmafis_bits, readl(pp->sactive_block)); |
2313 | rc = nv_swncq_sdbfis(ap); | 2310 | if (nv_swncq_sdbfis(ap) < 0) |
2314 | if (rc < 0) | ||
2315 | goto irq_error; | 2311 | goto irq_error; |
2316 | } | 2312 | } |
2317 | 2313 | ||
@@ -2348,7 +2344,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) | |||
2348 | */ | 2344 | */ |
2349 | pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap)); | 2345 | pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap)); |
2350 | pp->ncq_flags |= ncq_saw_dmas; | 2346 | pp->ncq_flags |= ncq_saw_dmas; |
2351 | rc = nv_swncq_dmafis(ap); | 2347 | nv_swncq_dmafis(ap); |
2352 | } | 2348 | } |
2353 | 2349 | ||
2354 | irq_exit: | 2350 | irq_exit: |