aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_mv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r--drivers/ata/sata_mv.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index a9fd9709c26..bf74a36d3cc 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)