[haiku-commits] haiku: hrev49665 - src/add-ons/kernel/busses/scsi/ahci

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 6 Oct 2015 02:46:34 +0200 (CEST)

hrev49665 adds 1 changeset to branch 'master'
old head: 3f93d71a1469f50f01eacc3409b1910fa667eadb
new head: a1ed294ff9fd94e10fe6b7fada5e20891b693ec2
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=a1ed294ff9fd+%5E3f93d71a1469

----------------------------------------------------------------------------

a1ed294ff9fd: AHCI: Rework port reset and control

* Move to more standardized functions matching AHCI spec
* Don't perform unnecessary double port resets
* Begin implementing a software reset to try first per spec.
Software reset needs more work, falls through to port reset
for the moment which is stable.
* Don't duplicate ATA defines, use what we already provide.
* Tested working on VirtualBox 1-16 AHCI ports, Intel C200,
and AMD FCH.

[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision: hrev49665
Commit: a1ed294ff9fd94e10fe6b7fada5e20891b693ec2
URL: http://cgit.haiku-os.org/haiku/commit/?id=a1ed294ff9fd
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Tue Oct 6 00:42:22 2015 UTC

----------------------------------------------------------------------------

5 files changed, 211 insertions(+), 100 deletions(-)
headers/private/drivers/ata_types.h | 4 +-
src/add-ons/kernel/busses/scsi/ahci/ahci_defs.h | 16 +-
.../kernel/busses/scsi/ahci/ahci_port.cpp | 275 +++++++++++++------
src/add-ons/kernel/busses/scsi/ahci/ahci_port.h | 10 +-
.../kernel/busses/scsi/ahci/sata_request.cpp | 6 +-

----------------------------------------------------------------------------

diff --git a/headers/private/drivers/ata_types.h
b/headers/private/drivers/ata_types.h
index b855d4e..f06a3d1 100644
--- a/headers/private/drivers/ata_types.h
+++ b/headers/private/drivers/ata_types.h
@@ -248,12 +248,12 @@ enum {
ATA_STATUS_BUSY = 0x80
// busy
};

-// device control register
+// device control register (ATA command block)
enum {

// bit 0 must be zero
ATA_DEVICE_CONTROL_DISABLE_INTS = 0x02, // disable INTRQ
ATA_DEVICE_CONTROL_SOFT_RESET = 0x04, // software device reset
- ATA_DEVICE_CONTROL_BIT3 = 0x08, // don't know,
but must be set
+ ATA_DEVICE_CONTROL_BIT3 = 0x08, // obsolete.
Must always be set

// bits inbetween are reserved
ATA_DEVICE_CONTROL_HIGH_ORDER_BYTE = 0x80 // read high order byte

// (for 48-bit lba)
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 1f8b149..b1122fd 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
@@ -2,6 +2,11 @@
* Copyright 2008-2015 Haiku, Inc. All rights reserved.
* Copyright 2007-2009, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ * Michael Lotz, mmlr@xxxxxxxx
+ * Alexander von Gluck IV, kallisti5@xxxxxxxxxxx
*/


@@ -54,7 +59,7 @@ AHCIPort::AHCIPort(AHCIController* controller, int index)
fSectorCount(0),
fIsATAPI(false),
fTestUnitReadyActive(false),
- fResetPort(false),
+ fSoftReset(false),
fError(false),
fTrimSupported(false)
{
@@ -120,7 +125,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 +136,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 +151,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 +178,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 +190,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 +224,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 +246,117 @@ 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);
+ // start port
+ Enable();

- if (!fTestUnitReadyActive) {
- TRACE("AHCIPort::ResetPort port %d, deviceBusy %d, "
- "forceDeviceReset %d\n", fIndex, deviceBusy,
forceDeviceReset);
+ // TODO: If FBS Enable, clear PxFBS.EN prior to issuing sw reset
+
+ if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY |
ATA_STATUS_DATA_REQUEST,
+ 1000000) < B_OK) {
+ ERROR("%s: port %d still busy. Moving on to port reset.\n",
+ __func__, fIndex);
+ return PortReset();
}

- if (deviceBusy || forceDeviceReset)
- ResetDevice();
+ // TODO: Just can't get AHCI software reset issued properly.
+ #if 0
+ // set command table soft reset bit
+ fCommandTable->cfis[2] |= ATA_DEVICE_CONTROL_SOFT_RESET;

- // start DMA engine
- fRegs->cmd |= PORT_CMD_ST;
+ // TODO: We could use a low level ahci command call
(~ahci_exec_polled_cmd)
+ cpu_status cpu = disable_interrupts();
+ acquire_spinlock(&fSpinlock);
+
+ // FIS ATA set Reset + clear busy
+ fCommandList[0].r = 1;
+ fCommandList[0].c = 1;
+ // FIS ATA clear Reset + clear busy
+ fCommandList[1].r = 0;
+ fCommandList[1].c = 0;
+
+ // Issue Command
+ fRegs->ci = 1;
FlushPostedWrites();
+ release_spinlock(&fSpinlock);
+ restore_interrupts(cpu);
+
+ if (wait_until_clear(&fRegs->ci, 0, 1000000) < B_OK) {
+ TRACE("%s: port %d: device is busy\n", __func__, fIndex);
+ return PortReset();
+ }
+
+ fCommandTable->cfis[2] &= ~ATA_DEVICE_CONTROL_SOFT_RESET;
+
+ 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();
+ }
+ #else
+ return PortReset();
+ #endif

return PostReset();
}


status_t
-AHCIPort::PostReset()
+AHCIPort::PortReset()
{
- if (!fTestUnitReadyActive)
- TRACE("AHCIPort::PostReset port %d\n", fIndex);
+ TRACE("AHCIPort::PortReset port %d\n", fIndex);

- if ((fRegs->ssts & 0xf) != 0x3 || (fRegs->tfd & 0xff) == 0x7f) {
- TRACE("AHCIPort::PostReset port %d: no device\n", fIndex);
- return B_OK;
+ // 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 (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 +366,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 +377,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 +451,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 +480,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,23 +488,23 @@ 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");
// TODO: check if the COMINIT is actually unsolicited!
// Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT
+ // Spec v1.3.1, §7.4 Interaction of command list and port
change status
+ // TODO: Issue COMRESET ?
+ //PortReset();
+ //HBAReset(); ???

- // perform a hard reset
-// if (!_HardReset())
-// return;
-//
-// // clear error bits to clear PxSERR.DIAG.X
-// _ClearErrorRegister();
+ // clear error bits to clear PxSERR.DIAG.X
+ _ClearErrorRegister();
}
if (is & PORT_INT_UF) {
TRACE("Unknown FIS\n");
- fResetPort = true;
+ fSoftReset = true;
}

if (fError) {
@@ -453,8 +529,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;
}

@@ -501,7 +576,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) {
@@ -664,7 +739,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);
@@ -1006,7 +1081,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
@@ -1058,9 +1133,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;
@@ -1095,9 +1171,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;
@@ -1323,22 +1399,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;
- FlushPostedWrites();
- spin(1100);
- // You must wait 1ms at minimum
- fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
- | DET_NO_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();
+ return true;
+}
+
+
+bool
+AHCIPort::Disable()
+{
+ TRACE("%s: port %d\n", __func__, fIndex);
+
+ if ((fRegs->cmd & PORT_CMD_ST) == 0) {
+ // Port already disabled, carry on.
+ TRACE("%s: port %d attempting to disable stopped port.\n",
+ __func__, fIndex);
+ } else {
+ // 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);
}
}


Other related posts:

  • » [haiku-commits] haiku: hrev49665 - src/add-ons/kernel/busses/scsi/ahci - kallisti5