diff --git a/sys/dev/disk/ahci/ahci.c b/sys/dev/disk/ahci/ahci.c
index 68cdabc..c34b82a 100644
--- a/sys/dev/disk/ahci/ahci.c
+++ b/sys/dev/disk/ahci/ahci.c
@@ -2378,8 +2378,10 @@ finish_error:
 	 * Spurious IFS errors (blockable).
 	 *
 	 * Spurious IFS errors can occur while we are doing a reset
-	 * sequence through a PM.  Try to recover if we are being asked
-	 * to ignore IFS errors during these periods.
+	 * sequence through a PM due to attempts to write PM registers.
+	 *
+	 * Try to recover if we are being asked to ignore IFS errors during
+	 * these periods.
 	 */
 	if ((is & AHCI_PREG_IS_IFS) && (ap->ap_flags & AP_F_IGNORE_IFS)) {
 		u_int32_t serr = ahci_pread(ap, AHCI_PREG_SERR);
@@ -2410,6 +2412,8 @@ finish_error:
 	 * A PRCS interrupt will occur on hot-unplug (and possibly also
 	 * on hot-plug).
 	 *
+	 * These bits do not stop command processing.
+	 *
 	 * XXX We can then check the CPS (Cold Presence State) bit, if
 	 * supported, to determine if a device is plugged in or not and do
 	 * the right thing.
@@ -2419,36 +2423,47 @@ finish_error:
 	 *	     If this occurs command processing is automatically
 	 *	     stopped (CR goes inactive) and the port must be stopped
 	 *	     and restarted.
+	 *
+	 *	     PRCS is cleared by clearing DIAG_N.
 	 */
 	if (is & (AHCI_PREG_IS_PCS | AHCI_PREG_IS_PRCS)) {
-		kprintf("%s: Transient Errors: %b\n",
-			PORTNAME(ap), is, AHCI_PFMT_IS);
 		ahci_pwrite(ap, AHCI_PREG_SERR,
 			(AHCI_PREG_SERR_DIAG_N | AHCI_PREG_SERR_DIAG_X));
 		ahci_pwrite(ap, AHCI_PREG_IS,
 			    is & (AHCI_PREG_IS_PCS | AHCI_PREG_IS_PRCS));
 		is &= ~(AHCI_PREG_IS_PCS | AHCI_PREG_IS_PRCS);
-		ahci_port_stop(ap, 0);
-		switch (ahci_pread(ap, AHCI_PREG_SSTS) & AHCI_PREG_SSTS_DET) {
-		case AHCI_PREG_SSTS_DET_DEV:
-			if (ap->ap_probe == ATA_PROBE_FAILED) {
-				need = NEED_HOTPLUG_INSERT;
-				goto fatal;
-			}
-			need = NEED_RESTART;
-			break;
-		default:
-			if (ap->ap_type != ATA_PROBE_FAILED) {
-				need = NEED_HOTPLUG_REMOVE;
-				goto fatal;
+
+		if (ap->ap_flags & AP_F_IN_RESET) {
+			kprintf("%s: Transient Errors during reset: "
+				"%b (ignored)\n",
+				PORTNAME(ap), is, AHCI_PFMT_IS);
+		} else {
+			kprintf("%s: Transient Errors: %b\n",
+				PORTNAME(ap), is, AHCI_PFMT_IS);
+			ahci_port_stop(ap, 0);
+			switch (ahci_pread(ap, AHCI_PREG_SSTS) & AHCI_PREG_SSTS_DET) {
+			case AHCI_PREG_SSTS_DET_DEV:
+				if (ap->ap_probe == ATA_PROBE_FAILED) {
+					need = NEED_HOTPLUG_INSERT;
+					goto fatal;
+				}
+				need = NEED_RESTART;
+				break;
+			default:
+				if (ap->ap_type != ATA_PROBE_FAILED) {
+					need = NEED_HOTPLUG_REMOVE;
+					goto fatal;
+				}
+				need = NEED_RESTART;
+				break;
 			}
-			need = NEED_RESTART;
-			break;
 		}
 	}
 
 	/*
 	 * Check for remaining errors - they are fatal. (blockable)
+	 *
+	 * These bits stop command processing.
 	 */
 	if (is & (AHCI_PREG_IS_TFES | AHCI_PREG_IS_HBFS | AHCI_PREG_IS_IFS |
 		  AHCI_PREG_IS_OFS | AHCI_PREG_IS_UFS)) {
diff --git a/sys/dev/disk/ahci/ahci_pm.c b/sys/dev/disk/ahci/ahci_pm.c
index 47be498..303a4b2 100644
--- a/sys/dev/disk/ahci/ahci_pm.c
+++ b/sys/dev/disk/ahci/ahci_pm.c
@@ -76,6 +76,7 @@ retry:
 	 * NOTE: On retry the port might be running, stopped, or failed.
 	 */
 	ahci_port_stop(ap, 0);
+	ap->ap_flags |= AP_F_IN_RESET;
 	ap->ap_state = AP_S_NORMAL;
 	cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
 	if ((cmd & AHCI_PREG_CMD_PMA) == 0) {
@@ -225,6 +226,7 @@ retry:
 err:
 	if (ccb != NULL)
 		ahci_put_err_ccb(ccb);
+	ap->ap_flags &= ~AP_F_IN_RESET;
 
 	if (error == 0 && ahci_pm_identify(ap)) {
 		kprintf("%s: PM - cannot identify port multiplier\n",
@@ -568,8 +570,9 @@ retry:
 	ccb->ccb_xa.state = ATA_S_PENDING;
 
 	/*
-	 * XXX hack to ignore IFS errors which can occur during the target
-	 *     device's reset.
+	 * XXX hack to ignore IFS errors for operations through port
+	 *     multipliers.  Target device's resets through the PM
+	 *     appear to be able to cause IFS errors ??
 	 *
 	 *     If an IFS error occurs the target is probably powering up,
 	 *     so we try for a longer period of time.
@@ -682,11 +685,20 @@ err:
 	if (ahci_pm_write(ap, target, SATA_PMREG_SERR, -1)) {
 		kprintf("%s: ahci_pm_softreset unable to clear SERR\n",
 			ATANAME(ap, at));
-		ap->ap_flags &= ~AP_F_IGNORE_IFS;
+		if (error == 0)
+			error = EIO;
 	}
-/*	ahci_pwrite(ap, AHCI_PREG_SERR, -1);*/
 
-	at->at_probe = error ? ATA_PROBE_FAILED : ATA_PROBE_NEED_IDENT;
+	/*
+	 * Final disposition.  Cleanup on error.  If no error occurred we
+	 * continue to ignore IFS while attached to the PM.
+	 */
+	if (error) {
+		ap->ap_flags &= ~AP_F_IGNORE_IFS;
+		at->at_probe = ATA_PROBE_FAILED;
+	} else {
+		at->at_probe = ATA_PROBE_NEED_IDENT;
+	}
 	return (error);
 }
 
