ata_port_abort(ap);
 }
 
-static void ahci_handle_port_interrupt(struct ata_port *ap,
-                                      void __iomem *port_mmio, u32 status)
+static void ahci_qc_complete(struct ata_port *ap, void __iomem *port_mmio)
 {
        struct ata_eh_info *ehi = &ap->link.eh_info;
        struct ahci_port_priv *pp = ap->private_data;
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
        u32 qc_active = 0;
        int rc;
 
+       /*
+        * pp->active_link is not reliable once FBS is enabled, both
+        * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
+        * NCQ and non-NCQ commands may be in flight at the same time.
+        */
+       if (pp->fbs_enabled) {
+               if (ap->qc_active) {
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+                       qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
+               }
+       } else {
+               /* pp->active_link is valid iff any command is in flight */
+               if (ap->qc_active && pp->active_link->sactive)
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+               else
+                       qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+       }
+
+       rc = ata_qc_complete_multiple(ap, qc_active);
+       if (unlikely(rc < 0 && !(ap->pflags & ATA_PFLAG_RESETTING))) {
+               ehi->err_mask |= AC_ERR_HSM;
+               ehi->action |= ATA_EH_RESET;
+               ata_port_freeze(ap);
+       }
+}
+
+static void ahci_handle_port_interrupt(struct ata_port *ap,
+                                      void __iomem *port_mmio, u32 status)
+{
+       struct ahci_port_priv *pp = ap->private_data;
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+
        /* ignore BAD_PMP while resetting */
-       if (unlikely(resetting))
+       if (unlikely(ap->pflags & ATA_PFLAG_RESETTING))
                status &= ~PORT_IRQ_BAD_PMP;
 
        if (sata_lpm_ignore_phy_events(&ap->link)) {
        }
 
        if (unlikely(status & PORT_IRQ_ERROR)) {
+               /*
+                * Before getting the error notification, we may have
+                * received SDB FISes notifying successful completions.
+                * Handle these first and then handle the error.
+                */
+               ahci_qc_complete(ap, port_mmio);
                ahci_error_intr(ap, status);
                return;
        }
                }
        }
 
-       /* pp->active_link is not reliable once FBS is enabled, both
-        * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
-        * NCQ and non-NCQ commands may be in flight at the same time.
-        */
-       if (pp->fbs_enabled) {
-               if (ap->qc_active) {
-                       qc_active = readl(port_mmio + PORT_SCR_ACT);
-                       qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
-               }
-       } else {
-               /* pp->active_link is valid iff any command is in flight */
-               if (ap->qc_active && pp->active_link->sactive)
-                       qc_active = readl(port_mmio + PORT_SCR_ACT);
-               else
-                       qc_active = readl(port_mmio + PORT_CMD_ISSUE);
-       }
-
-
-       rc = ata_qc_complete_multiple(ap, qc_active);
-
-       /* while resetting, invalid completions are expected */
-       if (unlikely(rc < 0 && !resetting)) {
-               ehi->err_mask |= AC_ERR_HSM;
-               ehi->action |= ATA_EH_RESET;
-               ata_port_freeze(ap);
-       }
+       /* Handle completed commands */
+       ahci_qc_complete(ap, port_mmio);
 }
 
 static void ahci_port_intr(struct ata_port *ap)