BOOL CDisk::SendIOCommand( DWORD dwStartSector, DWORD dwNumberOfSectors, BYTE bCmd ) { DEBUGMSG(ZONE_IO, (TEXT( "Atapi!CDisk::SendIOCommand> sector(%d), sectors left(%x), command(%x)\r\n" ), dwStartSector,dwNumberOfSectors,bCmd)); RETAILMSG(0, (TEXT( "Atapi!CDisk::SendIOCommand> sector(%d), sectors left(%x), command(%x)\r\n" ), dwStartSector,dwNumberOfSectors,bCmd)); if (ZONE_CELOG) CeLogData(TRUE, CELID_ATAPI_IOCOMMAND, &bCmd, sizeof(bCmd), 0, CELZONE_ALWAYSON, 0, FALSE); SelectDevice(); if (WaitOnBusy(FALSE)) { DEBUGMSG(ZONE_IO, (TEXT( "Atapi!CDisk::SendIOCommand> Failed to send command; status(%x), error(%x)\r\n" ), GetAltStatus(),GetError())); RETAILMSG(1, (TEXT( "Atapi!CDisk::SendIOCommand> Failed to send command; status(%x), error(%x)\r\n" ), GetAltStatus(),GetError())); return FALSE; } if (m_fUseLBA48) { ASSERT(dwNumberOfSectors <= MAX_SECT_PER_EXT_COMMAND); // to transfer 65536 sectors, set number of sectors to 0 if (dwNumberOfSectors == MAX_SECT_PER_EXT_COMMAND) { dwNumberOfSectors = 0; } WriteSectorCount((BYTE)(dwNumberOfSectors >> 8)); // Sector Count 15:8 WriteSectorCount((BYTE)(dwNumberOfSectors)); // Sector Count 7:0 // CE supports only 32-bit LBA as of now. Therefore, clear the upper 16 bits of LBA. WriteHighCount(0); // LBA 47:40 WriteLowCount(0); // LBA 39:32 WriteSectorNumber((BYTE)(dwStartSector >> 24)); // LBA 31:24 WriteHighCount((BYTE)(dwStartSector >> 16)); // LBA 23:16 WriteLowCount((BYTE)(dwStartSector >> 8)); // LBA 15:8 WriteSectorNumber((BYTE)dwStartSector); // LBA 7:0 WriteDriveHeadReg( ATA_HEAD_LBA_MODE | ((m_dwDevice == 0 ) ? ATA_HEAD_DRIVE_1 : ATA_HEAD_DRIVE_2)); } else {
BOOL CDisk::SendIOCommand( DWORD dwStartSector, DWORD dwNumberOfSectors, BYTE bCmd ) { DEBUGMSG(ZONE_IO, (TEXT( "Atapi!CDisk::SendIOCommand> sector(%d), sectors left(%x), command(%x)\r\n" ), dwStartSector,dwNumberOfSectors,bCmd)); if (ZONE_CELOG) CeLogData(TRUE, CELID_ATAPI_IOCOMMAND, &bCmd, sizeof(bCmd), 0, CELZONE_ALWAYSON, 0, FALSE); SelectDevice(); if (WaitOnBusy(FALSE)) { DEBUGMSG(ZONE_IO, (TEXT( "Atapi!CDisk::SendIOCommand> Failed to send command; status(%x), error(%x)\r\n" ), GetAltStatus(),GetError())); return FALSE; } // to transfer 256 sectors, set number of sectors to 0 if (dwNumberOfSectors == MAX_SECT_PER_COMMAND) { dwNumberOfSectors = 0; } WriteSectorCount((BYTE)dwNumberOfSectors); if (m_fLBAMode == TRUE) { WriteSectorNumber( (BYTE)dwStartSector); WriteLowCount((BYTE)(dwStartSector >> 8)); WriteHighCount((BYTE)(dwStartSector >> 16)); WriteDriveHeadReg((BYTE)((dwStartSector >> 24) | ATA_HEAD_LBA_MODE) | ((m_dwDevice == 0 ) ? ATA_HEAD_DRIVE_1 : ATA_HEAD_DRIVE_2)); }
BOOL CST202T_SATA::ResetController( BOOL bSoftReset // ignore ) { DWORD dwAttempts = 0; DWORD dwStatus = 0; BYTE bStatus = 0; BOOL fRet = FALSE; ToggleOOB(SATA_SCONTROL_SPD_1_5_SPEEDLIMIT); // This part supports generation 1 speeds only. // SError will reflect several transient error conditions resulting from // the reset sequence. Clear them now. m_pRegSATA->dwSError = m_pRegSATA->dwSError; // we have to negate the RESET signal for 5 microseconds before we assert it WriteAltDriveController(0x00); Sleep(2); ::StallExecution(25); // Set_SRST // -------- // to enter Set_SRST state, set SRST in the Device Control register to one; // this will assert the RESET signal and reset both devices on the current // channel WriteAltDriveController(0x04); // 0x04 == SRST // remain in this state for at least 5 microseconds; i.e., assert RESET signal // for at least 5 microseconds // if this is a hardware reset, then assert RESET signal for at least 25 // microseconds Sleep(2); ::StallExecution(25); // this should be CEDDK implementation // Clear_wait // ---------- // clear SRST in the Device Control register, i.e., negate RESET signal WriteAltDriveController(0x00); // remain in this state for at least 2 milliseconds Sleep(5); HSR2_Check_status:; // Check_status // ------------ // read the Status or Alternate Status register // if BSY is set to one, then re-enter this state // if BSY is cleared to zero, check the ending status in the Error register // and the signature (9.12) and transition to Host_Idle bStatus = GetAltStatus(); // read Status register if (bStatus & 0x80) { // BSY is set to one, re-enter this state if ( !((m_pPort->m_pController->m_pIdeReg->dwSoftResetTimeout - dwAttempts) % 100) ) { DEBUGMSG(ZONE_INIT, (TEXT( "Atapi!CDisk::ResetController> Device is busy; %u seconds remaining\r\n" ), ((m_pPort->m_pController->m_pIdeReg->dwSoftResetTimeout - dwAttempts)/100))); } Sleep(10); dwAttempts += 1; // a device has at most 31 seconds to complete a software reset; we'll use 3 seconds if (dwAttempts == m_pPort->m_pController->m_pIdeReg->dwSoftResetTimeout) { DEBUGMSG(ZONE_INIT, (TEXT("Atapi!CDisk::ResetController> Timeout\r\n"))); goto exit; } goto HSR2_Check_status; } DEBUGMSG(ZONE_INIT, (TEXT( "Atapi!CDisk::ResetController> Device is ready\r\n" ))); // BSY is cleared to zero, check the ending status in the Error register // and the signature // TODO: Check the signature (9.12) // From SATA 1.0A, seciton 9.1, 9.3, and 9.4: // Bit 0 of Error register is set to 1 if the reset succeeded. BYTE bError; bError = GetError(); // read Error register bStatus = GetAltStatus(); // read Status register if (!(bError & 0x01)) { DEBUGMSG(ZONE_INIT, (TEXT( "Atapi!CDisk::ResetController> SRST failed. Error = 0x%x, Status = 0x%x\r\n" ), bError, bStatus)); // TODO: Recover from error goto exit; } fRet = TRUE; exit:; // SError will reflect several transient error conditions resulting from // the reset sequence. Clear them now. m_pRegSATA->dwSError = m_pRegSATA->dwSError; // Clear any pending interrupt bStatus = GetBaseStatus(); // Enable the SATA error interrupt (this is cleared by the COMRESET sequence). EnableSErrorInt(TRUE); return fRet; }