diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
index b9c8c03..1e942cb 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h
@@ -5,6 +5,7 @@
 #ifndef _AHCI_DEFS_H
 #define _AHCI_DEFS_H
 
+#include <ata_types.h>
 #include <bus/PCI.h>
 #include <bus/SCSI.h>
 #include <PCI_x86.h>
@@ -97,6 +98,11 @@ enum {
 #define IPM_TRANSITIONS_TO_PARTIAL_DISABLED 0x1
 #define IPM_TRANSITIONS_TO_SLUMBER_DISABLED 0x2
 
+// Device signatures
+#define	SATA_SIG_ATA			0x00000101 // SATA drive
+#define	SATA_SIG_ATAPI			0xEB140101 // ATAPI drive
+#define	SATA_SIG_SEMB			0xC33C0101 // Enclosure management bridge
+#define	SATA_SIG_PM				0x96690101 // Port multiplier
 
 typedef struct {
 	uint32		clb;			// Command List Base Address
@@ -130,7 +136,7 @@ enum {
 	PORT_CMD_ATAPI	= (1 << 24),	// Device is ATAPI
 	PORT_CMD_CR		= (1 << 15),	// Command List Running (DMA active)
 	PORT_CMD_FR		= (1 << 14),	// FIS Receive Running
-	PORT_CMD_FER	= (1 << 4),		// FIS Receive Enable
+	PORT_CMD_FRE	= (1 << 4),		// FIS Receive Enable
 	PORT_CMD_CLO	= (1 << 3),		// Command List Override
 	PORT_CMD_POD	= (1 << 2),		// Power On Device
 	PORT_CMD_SUD	= (1 << 1),		// Spin-up Device
@@ -167,14 +173,6 @@ enum {
 							| PORT_INT_DS | PORT_INT_PS | PORT_INT_DHR)
 
 enum {
-	ATA_BSY			= 0x80,
-	ATA_DF			= 0x20,
-	ATA_DRQ			= 0x08,
-	ATA_ERR			= 0x01,
-};
-
-
-enum {
 	PORT_FBS_DWE_SHIFT		= 16,	// Device With Error
 	PORT_FBS_DWE_MASK		= 0xf,
 	PORT_FBS_ADO_SHIFT		= 12,	// Active Device Optimization
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
index 94a0034..45c7762 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
@@ -54,7 +54,7 @@ AHCIPort::AHCIPort(AHCIController* controller, int index)
 	fSectorCount(0),
 	fIsATAPI(false),
 	fTestUnitReadyActive(false),
-	fResetPort(false),
+	fSoftReset(false),
 	fError(false),
 	fTrimSupported(false)
 {
@@ -120,7 +120,7 @@ AHCIPort::Init1()
 	fRegs->is = fRegs->is;
 
 	// clear error bits
-	fRegs->serr = fRegs->serr;
+	_ClearErrorRegister();
 
 	// power up device
 	fRegs->cmd |= PORT_CMD_POD;
@@ -131,8 +131,8 @@ AHCIPort::Init1()
 	// activate link
 	fRegs->cmd = (fRegs->cmd & ~PORT_CMD_ICC_MASK) | PORT_CMD_ICC_ACTIVE;
 
-	// enable FIS receive
-	fRegs->cmd |= PORT_CMD_FER;
+	// enable FIS receive (enabled when fb set, only to be disabled when unset)
+	fRegs->cmd |= PORT_CMD_FRE;
 
 	FlushPostedWrites();
 
@@ -146,15 +146,16 @@ AHCIPort::Init2()
 {
 	TRACE("AHCIPort::Init2 port %d\n", fIndex);
 
-	// start DMA engine
-	fRegs->cmd |= PORT_CMD_ST;
+	// enable port
+	Enable();
 
 	// enable interrupts
 	fRegs->ie = PORT_INT_MASK;
 
 	FlushPostedWrites();
 
-	ResetPort(true);
+	// reset port and probe info
+	SoftReset();
 
 	TRACE("ie   0x%08" B_PRIx32 "\n", fRegs->ie);
 	TRACE("is   0x%08" B_PRIx32 "\n", fRegs->is);
@@ -172,6 +173,9 @@ AHCIPort::Init2()
 
 	fDevicePresent = (fRegs->ssts & 0xf) == 0x3;
 
+	TRACE("%s: port %d, device %s\n", __func__, fIndex,
+		fDevicePresent ? "present" : "absent");
+
 	return B_OK;
 }
 
@@ -181,22 +185,19 @@ AHCIPort::Uninit()
 {
 	TRACE("AHCIPort::Uninit port %d\n", fIndex);
 
-	// disable FIS receive
-	fRegs->cmd &= ~PORT_CMD_FER;
+	// Spec v1.3.1, §10.3.2 - Shut down port before unsetting FRE
 
-	// wait for receive completion, up to 500ms
-	if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK) {
-		TRACE("AHCIPort::Uninit port %d error FIS rx still running\n", fIndex);
+	// shutdown the port
+	if (!Disable()) {
+		ERROR("%s: port %d error, unable to shutdown before FRE clear!\n",
+			__func__, fIndex);
+		return;
 	}
 
-	// stop DMA engine
-	fRegs->cmd &= ~PORT_CMD_ST;
-
-	// wait for DMA completion
-	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
-		TRACE("AHCIPort::Uninit port %d error DMA engine still running\n",
-			fIndex);
-	}
+	// Clear FRE and wait for completion
+	fRegs->cmd &= ~PORT_CMD_FRE;
+	if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK)
+		ERROR("%s: port %d error FIS rx still running\n", __func__, fIndex);
 
 	// disable interrupts
 	fRegs->ie = 0;
@@ -218,8 +219,10 @@ void
 AHCIPort::ResetDevice()
 {
 	// perform a hard reset
-	if (!_HardReset())
+	if (PortReset() != B_OK) {
+		ERROR("%s: port %d unable to hard reset device\n", __func__, fIndex);
 		return;
+	}
 
 	if (wait_until_set(&fRegs->ssts, 0x1, 100000) < B_OK)
 		TRACE("AHCIPort::ResetDevice port %d no device detected\n", fIndex);
@@ -238,49 +241,93 @@ AHCIPort::ResetDevice()
 
 
 status_t
-AHCIPort::ResetPort(bool forceDeviceReset)
+AHCIPort::SoftReset()
 {
-	if (!fTestUnitReadyActive)
-		TRACE("AHCIPort::ResetPort port %d\n", fIndex);
+	TRACE("AHCIPort::SoftReset port %d\n", fIndex);
 
-	// stop DMA engine
-	fRegs->cmd &= ~PORT_CMD_ST;
-	FlushPostedWrites();
+	// Spec v1.3.1, §10.4.1 Software Reset
+	// A single device on one port is reset, HBA and phy comm remain intact.
 
-	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
-		TRACE("AHCIPort::ResetPort port %d error DMA engine doesn't stop\n",
-			fIndex);
+	// stop port, flush transactions
+	if (!Disable()) {
+		// If the port doesn't power off, move on to a stronger reset.
+		ERROR("%s: port %d soft reset failed. Moving on to port reset.\n",
+			__func__, fIndex);
+		return PortReset();
 	}
 
-	bool deviceBusy = fRegs->tfd & (ATA_BSY | ATA_DRQ);
+	// TODO: If FBS Enable, clear PxFBS.EN prior to issuing sw reset
 
-	if (!fTestUnitReadyActive) {
-		TRACE("AHCIPort::ResetPort port %d, deviceBusy %d, "
-			"forceDeviceReset %d\n", fIndex, deviceBusy, forceDeviceReset);
+	// If the port is still busy, move on to port reset.
+	if (fRegs->tfd & (ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST)) {
+		ERROR("%s: port %d still busy. Moving on to port reset.\n",
+			__func__, fIndex);
+		return PortReset();
 	}
 
-	if (deviceBusy || forceDeviceReset)
-		ResetDevice();
-
-	// start DMA engine
-	fRegs->cmd |= PORT_CMD_ST;
+	// ATA Reset
+	fCommandList->r = 1;
+	// ATA Clear Busy
+	fCommandList->c = 1;
+	// Issue Command
+	fRegs->ci = 1;
 	FlushPostedWrites();
 
+	if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
+		1000000) < B_OK) {
+		ERROR("%s: port %d software reset failed. Doing port reset...\n",
+			__func__, fIndex);
+		return PortReset();
+	}
+
+	// start port
+	Enable();
+
 	return PostReset();
 }
 
 
 status_t
-AHCIPort::PostReset()
+AHCIPort::PortReset()
 {
-	if (!fTestUnitReadyActive)
-		TRACE("AHCIPort::PostReset port %d\n", fIndex);
+	TRACE("AHCIPort::PortReset port %d\n", fIndex);
+
+	// Spec v1.3.1, §10.4.2 Port Reset
+	// Physical comm between HBA and port disabled. More Intrusive
+	if (!Disable()) {
+		ERROR("%s: port %d unable to reset!\n", __func__, fIndex);
+		return B_ERROR;
+	}
+
+	fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
+		| DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
+	FlushPostedWrites();
+	spin(1100);
+		// You must wait 1ms at minimum
+	fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
+		| DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
+	FlushPostedWrites();
 
-	if ((fRegs->ssts & 0xf) != 0x3 || (fRegs->tfd & 0xff) == 0x7f) {
-		TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
-		return B_OK;
+	if (wait_until_set(&fRegs->ssts, 0x3, 500000) < B_OK) {
+		TRACE("AHCIPort::PortReset port %d device present but no phy "
+			"communication\n", fIndex);
+		return B_ERROR;
 	}
 
+	//if ((fRegs->tfd & 0xff) == 0x7f) {
+	//	TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
+	//	return B_OK;
+	//}
+
+	Enable();
+
+	return PostReset();
+}
+
+
+status_t
+AHCIPort::PostReset()
+{
 	if ((fRegs->tfd & 0xff) == 0xff)
 		snooze(200000);
 
@@ -290,10 +337,9 @@ AHCIPort::PostReset()
 		return B_ERROR;
 	}
 
-	wait_until_clear(&fRegs->tfd, ATA_BSY, 31000000);
-
-	fIsATAPI = fRegs->sig == 0xeb140101;
+	wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY, 31000000);
 
+	fIsATAPI = fRegs->sig == SATA_SIG_ATAPI;
 	if (fIsATAPI)
 		fRegs->cmd |= PORT_CMD_ATAPI;
 	else
@@ -302,10 +348,12 @@ AHCIPort::PostReset()
 
 	if (!fTestUnitReadyActive) {
 		TRACE("device signature 0x%08" B_PRIx32 " (%s)\n", fRegs->sig,
-			fRegs->sig == 0xeb140101 ? "ATAPI" : fRegs->sig == 0x00000101
+			fRegs->sig == SATA_SIG_ATAPI ? "ATAPI" : fRegs->sig == SATA_SIG_ATA
 				? "ATA" : "unknown");
 	}
 
+	_ClearErrorRegister();
+
 	return B_OK;
 }
 
@@ -374,29 +422,28 @@ AHCIPort::InterruptErrorHandler(uint32 is)
 	}
 
 	// read and clear SError
-	uint32 serr = fRegs->serr;
-	fRegs->serr = serr;
+	_ClearErrorRegister();
 
 	if (is & PORT_INT_TFE) {
 		if (!fTestUnitReadyActive)
 			TRACE("Task File Error\n");
 
-		fResetPort = true;
+		fSoftReset = true;
 		fError = true;
 	}
 	if (is & PORT_INT_HBF) {
 		TRACE("Host Bus Fatal Error\n");
-		fResetPort = true;
+		fSoftReset = true;
 		fError = true;
 	}
 	if (is & PORT_INT_HBD) {
 		TRACE("Host Bus Data Error\n");
-		fResetPort = true;
+		fSoftReset = true;
 		fError = true;
 	}
 	if (is & PORT_INT_IF) {
 		TRACE("Interface Fatal Error\n");
-		fResetPort = true;
+		fSoftReset = true;
 		fError = true;
 	}
 	if (is & PORT_INT_INF) {
@@ -404,7 +451,7 @@ AHCIPort::InterruptErrorHandler(uint32 is)
 	}
 	if (is & PORT_INT_OF) {
 		TRACE("Overflow\n");
-		fResetPort = true;
+		fSoftReset = true;
 		fError = true;
 	}
 	if (is & PORT_INT_IPM) {
@@ -412,22 +459,20 @@ AHCIPort::InterruptErrorHandler(uint32 is)
 	}
 	if (is & PORT_INT_PRC) {
 		TRACE("PhyReady Change\n");
-//		fResetPort = true;
+//		fSoftReset = true;
 	}
 	if (is & PORT_INT_PC) {
 		TRACE("Port Connect Change\n");
 		// Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT
-
-		// perform a hard reset
-		if (!_HardReset())
-			return;
-
-		// clear error bits to clear PxSERR.DIAG.X
+		// Spec v1.3.1, §7.4 Interaction of command list and port change status
+		// TODO: Issue COMRESET ?
+		//PortReset();
+		//HBAReset(); ???
 		_ClearErrorRegister();
 	}
 	if (is & PORT_INT_UF) {
 		TRACE("Unknown FIS\n");
-		fResetPort = true;
+		fSoftReset = true;
 	}
 
 	if (fError) {
@@ -452,8 +497,7 @@ AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,
 	status_t status = get_memory_map_etc(B_CURRENT_TEAM, data, dataSize,
 		entries, &entriesUsed);
 	if (status != B_OK) {
-		TRACE("AHCIPort::FillPrdTable get_memory_map() failed: %s\n",
-			strerror(status));
+		TRACE("%s: get_memory_map() failed: %s\n", __func__, strerror(status));
 		return B_ERROR;
 	}
 
@@ -500,7 +544,7 @@ AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,
 		sgCount--;
 	}
 	if (*prdCount == 0) {
-		TRACE("AHCIPort::FillPrdTable: count is 0\n");
+		TRACE("%s: count is 0\n", __func__);
 		return B_ERROR;
 	}
 	if (dataSize > 0) {
@@ -663,7 +707,7 @@ AHCIPort::ScsiInquiry(scsi_ccb* request)
 	ExecuteSataRequest(&sreq);
 	sreq.WaitForCompletion();
 
-	if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
+	if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
 		ERROR("identify device failed\n");
 		request->subsys_status = SCSI_REQ_CMP_ERR;
 		gSCSI->finished(request, 1);
@@ -1005,7 +1049,7 @@ for (uint32 i = 0; i < lbaRangeCount; i++) {
 		ExecuteSataRequest(&sreq);
 		sreq.WaitForCompletion();
 
-		if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
+		if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
 			TRACE("trim failed (%" B_PRIu32 " ranges)!\n", lbaRangeCount);
 			request->subsys_status = SCSI_REQ_CMP_ERR;
 		} else
@@ -1057,9 +1101,10 @@ AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)
 	fCommandList->prdtl = prdEntrys;
 	fCommandList->prdbc = 0;
 
-	if (wait_until_clear(&fRegs->tfd, ATA_BSY | ATA_DRQ, 1000000) < B_OK) {
+	if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
+			1000000) < B_OK) {
 		TRACE("ExecuteAtaRequest port %d: device is busy\n", fIndex);
-		ResetPort();
+		SoftReset();
 		FinishTransfer();
 		request->Abort();
 		return;
@@ -1094,9 +1139,9 @@ AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)
 	TRACE("tfd  0x%08" B_PRIx32 "\n", fRegs->tfd);
 */
 
-	if (fResetPort || status == B_TIMED_OUT) {
-		fResetPort = false;
-		ResetPort();
+	if (fSoftReset || status == B_TIMED_OUT) {
+		fSoftReset = false;
+		SoftReset();
 	}
 
 	size_t bytesTransfered = fCommandList->prdbc;
@@ -1322,23 +1367,55 @@ AHCIPort::ScsiGetRestrictions(bool* isATAPI, bool* noAutoSense,
 
 
 bool
-AHCIPort::_HardReset()
+AHCIPort::Enable()
 {
+	// Spec v1.3.1, §10.3.1 Start (PxCMD.ST)
+	TRACE("%s: port %d\n", __func__, fIndex);
 	if ((fRegs->cmd & PORT_CMD_ST) != 0) {
-		// We shouldn't perform a reset, but at least document it
-		TRACE("AHCIPort::_HardReset() PORT_CMD_ST set, behaviour undefined\n");
+		TRACE("%s: Starting port already running!\n", __func__);
 		return false;
 	}
 
-	fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
-		| DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
+	if ((fRegs->cmd & PORT_CMD_FRE) == 0) {
+		TRACE("%s: Unable to start port without FRE enabled!\n", __func__);
+		return false;
+	}
+
+	// Clear DMA engine and wait for completion
+	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
+		TRACE("%s: port %d error DMA engine still running\n", __func__,
+			fIndex);
+		return false;
+	}
+	// Start port
+	fRegs->cmd |= PORT_CMD_ST;
 	FlushPostedWrites();
-	spin(1100);
-		// You must wait 1ms at minimum
-	fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
-		| DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
+	return true;
+}
+
+
+bool
+AHCIPort::Disable()
+{
+	TRACE("%s: port %d\n", __func__, fIndex);
+
+	if ((fRegs->cmd & PORT_CMD_ST) == 0) {
+		TRACE("%s: port %d attempting to disable stopped port.\n",
+			__func__, fIndex);
+	}
+
+	// Disable port
+	fRegs->cmd &= ~PORT_CMD_ST;
 	FlushPostedWrites();
 
+	// Spec v1.3.1, §10.4.2 Port Reset - assume hung after 500 mil.
+	// Clear DMA engine and wait for completion
+	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
+		TRACE("%s: port %d error DMA engine still running\n", __func__,
+			fIndex);
+		return false;
+	}
+
 	return true;
 }
 
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
index 0bc4e67..deed571 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
@@ -48,8 +48,13 @@ private:
 	void		ExecuteSataRequest(sata_request *request, bool isWrite = false);
 
 	void		ResetDevice();
-	status_t	ResetPort(bool forceDeviceReset = false);
+	status_t	SoftReset();
+	status_t	PortReset();
 	status_t	PostReset();
+
+	bool		Enable();
+	bool		Disable();
+
 	void		FlushPostedWrites();
 	void		DumpD2HFis();
 
@@ -57,7 +62,6 @@ private:
 	status_t	WaitForTransfer(int *tfd, bigtime_t timeout);
 	void		FinishTransfer();
 
-	inline	bool				_HardReset();
 	inline	void				_ClearErrorRegister();
 
 //	uint8 *		SetCommandFis(volatile command_list_entry *cmd, volatile fis *fis, const void *data, size_t dataSize);
@@ -79,7 +83,7 @@ private:
 	uint64							fSectorCount;
 	bool							fIsATAPI;
 	bool							fTestUnitReadyActive;
-	bool							fResetPort;
+	bool							fSoftReset;
 	bool							fError;
 	bool							fTrimSupported;
 	uint32							fMaxTrimRangeBlocks;
diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
index 6a53fcf..9e06dce 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
+++ b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
@@ -121,7 +121,7 @@ sata_request::SetATAPICommand(size_t transferLength)
 void
 sata_request::Finish(int tfd, size_t bytesTransfered)
 {
-	if ((tfd & (ATA_ERR | ATA_DF)) != 0) {
+	if ((tfd & (ATA_STATUS_ERROR | ATA_STATUS_DEVICE_FAULT)) != 0) {
 		uint8 status = tfd & 0xff;
 		uint8 error = (tfd >> 8) & 0xff;
 
@@ -135,7 +135,7 @@ sata_request::Finish(int tfd, size_t bytesTransfered)
 		fCcb->data_resid = fCcb->data_length - bytesTransfered;
 		fCcb->device_status = SCSI_STATUS_GOOD;
 		fCcb->subsys_status = SCSI_REQ_CMP;
-		if (tfd & (ATA_ERR | ATA_DF)) {
+		if (tfd & (ATA_STATUS_ERROR | ATA_STATUS_DEVICE_FAULT)) {
 			fCcb->subsys_status = SCSI_REQ_CMP_ERR;
 			if (fIsATAPI) {
 				if (!IsTestUnitReady()) {
@@ -187,7 +187,7 @@ sata_request::Abort()
 		gSCSI->finished(fCcb, 1);
 		delete this;
 	} else {
-		fCompletionStatus = ATA_ERR;
+		fCompletionStatus = ATA_STATUS_ERROR;
 		release_sem(fCompletionSem);
 	}
 }
