diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 25 |
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 | ||
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) |