X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdrivers%2Fstorage%2Fide%2Funiata%2Fid_sata.cpp;h=9996852d55cd7b3d5db10508e4d1ce31b9aaf984;hp=649b62cea5d3dc56573ead5320385821b52569ea;hb=5783342323f2036abca4bd986cb1a2b207b18639;hpb=3d21f7f3d09f540ad5ad8e4ad1c2a3895eb92da5 diff --git a/reactos/drivers/storage/ide/uniata/id_sata.cpp b/reactos/drivers/storage/ide/uniata/id_sata.cpp index 649b62cea5d..9996852d55c 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_sata.cpp @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2008-2012 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2008-2014 Alexandr A. Telyatnikov (Alter) Module Name: id_probe.cpp @@ -649,6 +649,8 @@ UniataAhciInit( ULONG PI; #endif //DBG ULONG CAP; + ULONG CAP2; + ULONG BOHC; ULONG GHC; BOOLEAN MemIo = FALSE; @@ -658,6 +660,37 @@ UniataAhciInit( UniataDumpAhciRegs(deviceExtension); #endif //DBG + CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2); + if(CAP2 & AHCI_CAP2_BOH) { + BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); + KdPrint2((PRINT_PREFIX " stage 1 BOHC %#x\n", BOHC)); + UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC, + BOHC | AHCI_BOHC_OOS); + for(i=0; i<50; i++) { + AtapiStallExecution(500); + BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); + KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC)); + if(BOHC & AHCI_BOHC_BB) { + break; + } + if(!(BOHC & AHCI_BOHC_BOS)) { + break; + } + } + KdPrint2((PRINT_PREFIX " stage 2 BOHC %#x\n", BOHC)); + if(BOHC & AHCI_BOHC_BB) { + for(i=0; i<2000; i++) { + AtapiStallExecution(1000); + BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); + KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC)); + if(!(BOHC & AHCI_BOHC_BOS)) { + break; + } + } + } + KdPrint2((PRINT_PREFIX " final BOHC %#x\n", BOHC)); + } + /* disable AHCI interrupts, for MSI compatibility issue see http://www.intel.com/Assets/PDF/specupdate/307014.pdf 26. AHCI Reset and MSI Request @@ -729,7 +762,14 @@ UniataAhciInit( PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI); KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI)); #endif //DBG - + CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2); + if(CAP2 & AHCI_CAP2_BOH) { + KdPrint2((PRINT_PREFIX " retry BOHC\n")); + BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); + KdPrint2((PRINT_PREFIX " BOHC %#x\n", BOHC)); + UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_BOHC, + BOHC | AHCI_BOHC_OOS); + } /* clear interrupts */ UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_IS, UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS)); @@ -1061,6 +1101,7 @@ UniataAhciStatus( } chan->AhciCompleteCI = (chan->AhciPrevCI ^ CI) & chan->AhciPrevCI; // only 1->0 states chan->AhciPrevCI = CI; + chan->AhciLastSError = SError.Reg; KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI)); chan->AhciLastIS = IS.Reg; if(CI & (1 << tag)) {