|
@@ -5359,10 +5359,20 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
|
*/
|
|
*/
|
|
int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active)
|
|
int ata_qc_complete_multiple(struct ata_port *ap, u64 qc_active)
|
|
{
|
|
{
|
|
|
|
+ u64 done_mask, ap_qc_active = ap->qc_active;
|
|
int nr_done = 0;
|
|
int nr_done = 0;
|
|
- u64 done_mask;
|
|
|
|
|
|
|
|
- done_mask = ap->qc_active ^ qc_active;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * If the internal tag is set on ap->qc_active, then we care about
|
|
|
|
+ * bit0 on the passed in qc_active mask. Move that bit up to match
|
|
|
|
+ * the internal tag.
|
|
|
|
+ */
|
|
|
|
+ if (ap_qc_active & (1ULL << ATA_TAG_INTERNAL)) {
|
|
|
|
+ qc_active |= (qc_active & 0x01) << ATA_TAG_INTERNAL;
|
|
|
|
+ qc_active ^= qc_active & 0x01;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ done_mask = ap_qc_active ^ qc_active;
|
|
|
|
|
|
if (unlikely(done_mask & qc_active)) {
|
|
if (unlikely(done_mask & qc_active)) {
|
|
ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n",
|
|
ata_port_err(ap, "illegal qc_active transition (%08llx->%08llx)\n",
|