Cleanup of hard reset, works on Intel, doesn't work on Jmicron.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22307 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2007-09-25 15:37:56 +00:00
parent 8c657126cd
commit 2c76601709
3 changed files with 37 additions and 35 deletions

View File

@ -223,12 +223,7 @@ AHCIController::ResetController()
#if 1
fRegs->ghc |= GHC_HR;
FlushPostedWrites();
for (int i = 0; i < 20; i++) {
snooze(50000);
if ((fRegs->ghc & GHC_HR) == 0)
break;
}
if (fRegs->ghc & GHC_HR)
if (wait_until_clear(&fRegs->ghc, GHC_HR, 1000000) < B_OK)
return B_TIMED_OUT;
#else
fRegs->ghc &= ~GHC_AE;

View File

@ -63,12 +63,14 @@ AHCIPort::Init1()
fCommandList[0].ctbau = HI32(physAddr);
// prdt follows after command table
// disable transitions to partial or slumber state
fRegs->sctl |= 0x300;
// clear IRQ status bits
fRegs->is = fRegs->is;
// clear error bits
// fRegs->serr = fRegs->serr;
fRegs->serr = 0xffffffff;
fRegs->serr = fRegs->serr;
// power up device
fRegs->cmd |= PORT_CMD_POD;
@ -102,7 +104,7 @@ AHCIPort::Init2()
FlushPostedWrites();
// if (fRegs->sig == 0xffffffff)
if (1 /* fRegs->sig == 0xffffffff */)
ResetDevice();
PostResetDevice();
@ -114,6 +116,7 @@ AHCIPort::Init2()
TRACE("sctl 0x%08lx\n", fRegs->sctl);
TRACE("serr 0x%08lx\n", fRegs->serr);
TRACE("sact 0x%08lx\n", fRegs->sact);
TRACE("tfd 0x%08lx\n", fRegs->tfd);
return B_OK;
}
@ -156,7 +159,6 @@ AHCIPort::Uninit()
}
status_t
AHCIPort::ResetDevice()
{
@ -173,9 +175,8 @@ AHCIPort::ResetDevice()
// perform a hard reset
fRegs->sctl = (fRegs->sctl & ~0xf) | 1;
FlushPostedWrites();
snooze(10000);
spin(1100);
fRegs->sctl &= ~0xf;
fRegs->serr = 0xffffffff;
FlushPostedWrites();
if (wait_until_set(&fRegs->ssts, 0x1, 100000) < B_OK) {
@ -183,8 +184,7 @@ AHCIPort::ResetDevice()
}
// clear error bits
// fRegs->serr = fRegs->serr;
fRegs->serr = 0xffffffff;
fRegs->serr = fRegs->serr;
FlushPostedWrites();
if (fRegs->ssts & 1) {
@ -194,7 +194,8 @@ AHCIPort::ResetDevice()
}
// clear error bits
fRegs->serr = 0xffffffff;
fRegs->serr = fRegs->serr;
FlushPostedWrites();
// start DMA engine
fRegs->cmd |= PORT_CMD_ST;
@ -209,25 +210,21 @@ AHCIPort::PostResetDevice()
{
TRACE("AHCIPort::PostResetDevice port %d\n", fIndex);
TRACE("tfd 1 0x%08lx\n", fRegs->tfd);
// wait for DMA idle ?
// if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 1000000) < B_OK) {
// TRACE("AHCIPort::PostResetDevice port %d error DMA engine doesn't stop\n", fIndex);
// }
switch (fRegs->tfd & 0xff) {
case 0x7f:
TRACE("no device present?\n");
break;
case 0xff:
TRACE("invalid task file status 0xff\n");
// fall through
default:
TRACE("waiting...\n");
wait_until_clear(&fRegs->tfd, ATA_BSY | ATA_DRQ, 31000000);
if ((fRegs->ssts & 0xf) != 0x3 || (fRegs->tfd & 0xff) == 0x7f) {
TRACE("AHCIPort::PostResetDevice port %d: no device\n", fIndex);
return B_OK;
}
if ((fRegs->tfd & 0xff) == 0xff)
snooze(200000);
if ((fRegs->tfd & 0xff) == 0xff) {
TRACE("AHCIPort::PostResetDevice port %d: invalid task file status 0xff\n", fIndex);
return B_ERROR;
}
wait_until_clear(&fRegs->tfd, ATA_BSY, 31000000);
if (fRegs->sig == 0xeb140101)
fRegs->cmd |= PORT_CMD_ATAPI;
else
@ -237,13 +234,22 @@ AHCIPort::PostResetDevice()
TRACE("device signature 0x%08lx (%s)\n", fRegs->sig,
(fRegs->sig == 0xeb140101) ? "ATAPI" : (fRegs->sig == 0x00000101) ? "ATA" : "unknown");
TRACE("tfd 0x%08lx\n", fRegs->tfd);
TRACE("device detection: 0x%lx\n", fRegs->ssts & 0xf);
return B_OK;
}
void
AHCIPort::DumpD2HFis()
{
TRACE("D2H FIS:\n");
TRACE(" DW0 %02x %02x %02x %02x\n", fFIS->rfis[3], fFIS->rfis[2], fFIS->rfis[1], fFIS->rfis[0]);
TRACE(" DW1 %02x %02x %02x %02x\n", fFIS->rfis[7], fFIS->rfis[6], fFIS->rfis[5], fFIS->rfis[4]);
TRACE(" DW2 %02x %02x %02x %02x\n", fFIS->rfis[11], fFIS->rfis[10], fFIS->rfis[9], fFIS->rfis[8]);
TRACE(" DW3 %02x %02x %02x %02x\n", fFIS->rfis[15], fFIS->rfis[14], fFIS->rfis[13], fFIS->rfis[12]);
TRACE(" DW4 %02x %02x %02x %02x\n", fFIS->rfis[19], fFIS->rfis[18], fFIS->rfis[17], fFIS->rfis[16]);
}
void
AHCIPort::Interrupt()
{

View File

@ -30,6 +30,7 @@ private:
status_t ResetDevice();
status_t PostResetDevice();
void FlushPostedWrites();
void DumpD2HFis();
private:
int fIndex;