⬢ DragonFlyBSD Kernel Audit
DF-4502 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/ahci/ahci_pm.c
+++ b/sys/dev/disk/ahci/ahci_pm.c
@@ -806,9 +806,17 @@
 		kprintf("%s: Soft-reset(2) through PM failed, %s\n",
 			ATANAME(ap, at),
 			(count > 1 ? "retrying" : "giving up"));
+		/*
+		 * ALWAYS release the error CCB before deciding to retry
+		 * or give up, mirroring the first-FIS failure path above
+		 * and ahci_port_softreset()'s err-label discipline
+		 * (ahci.c).  Leaving it reserved wedges the port
+		 * (AP_F_ERR_CCB_RESERVED blocks all command issue) and
+		 * panics the next ahci_get_err_ccb() on the port.
+		 */
+		ahci_put_err_ccb(ccb);
 		if (--count) {
 			ahci_os_sleep(1000);
-			ahci_put_err_ccb(ccb);
 			ahci_pwrite(ap, AHCI_PREG_SERR, -1);
 			ahci_pwrite(ap, AHCI_PREG_IS, AHCI_PREG_IS_IFS);
 			goto retry;