28 ASSERT (PciIo !=
NULL);
60 ASSERT (PciIo !=
NULL);
90 ASSERT (PciIo !=
NULL);
120 ASSERT (PciIo !=
NULL);
155 ASSERT (PciIo !=
NULL);
156 ASSERT (Buffer !=
NULL);
163 EfiPciIoWidthFifoUint16,
191 ASSERT (PciIo !=
NULL);
192 ASSERT (Buffer !=
NULL);
199 EfiPciIoWidthFifoUint16,
227 ASSERT (PciIo !=
NULL);
228 ASSERT (IdeRegisters !=
NULL);
232 StatusBlock.AtaStatus =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
233 StatusBlock.AtaError =
IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
234 StatusBlock.AtaSectorCount =
IdeReadPortB (PciIo, IdeRegisters->SectorCount);
235 StatusBlock.AtaSectorCountExp =
IdeReadPortB (PciIo, IdeRegisters->SectorCount);
236 StatusBlock.AtaSectorNumber =
IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
237 StatusBlock.AtaSectorNumberExp =
IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
238 StatusBlock.AtaCylinderLow =
IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
239 StatusBlock.AtaCylinderLowExp =
IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
240 StatusBlock.AtaCylinderHigh =
IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
241 StatusBlock.AtaCylinderHighExp =
IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
242 StatusBlock.AtaDeviceHead =
IdeReadPortB (PciIo, IdeRegisters->Head);
244 if (AtaStatusBlock !=
NULL) {
253 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));
257 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));
262 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));
266 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));
270 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));
274 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));
278 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));
282 DEBUG ((DEBUG_ERROR,
"CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));
307 UINT8 StatusRegister;
309 ASSERT (PciIo !=
NULL);
310 ASSERT (IdeRegisters !=
NULL);
312 StatusRegister =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
318 return EFI_DEVICE_ERROR;
351 UINT8 StatusRegister;
352 BOOLEAN InfiniteWait;
354 ASSERT (PciIo !=
NULL);
355 ASSERT (IdeRegisters !=
NULL);
360 InfiniteWait =
FALSE;
365 StatusRegister =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
372 return EFI_DEVICE_ERROR;
384 }
while (InfiniteWait || (Delay > 0));
415 BOOLEAN InfiniteWait;
417 ASSERT (PciIo !=
NULL);
418 ASSERT (IdeRegisters !=
NULL);
423 InfiniteWait =
FALSE;
428 AltRegister =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
435 return EFI_DEVICE_ERROR;
447 }
while (InfiniteWait || (Delay > 0));
488 UINT8 StatusRegister;
490 BOOLEAN InfiniteWait;
492 ASSERT (PciIo !=
NULL);
493 ASSERT (IdeRegisters !=
NULL);
498 InfiniteWait =
FALSE;
506 StatusRegister =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
513 ErrorRegister =
IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
519 return EFI_DEVICE_ERROR;
525 return EFI_NOT_READY;
535 }
while (InfiniteWait || (Delay > 0));
576 BOOLEAN InfiniteWait;
578 ASSERT (PciIo !=
NULL);
579 ASSERT (IdeRegisters !=
NULL);
584 InfiniteWait =
FALSE;
593 AltRegister =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
599 ErrorRegister =
IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);
605 return EFI_DEVICE_ERROR;
611 return EFI_NOT_READY;
621 }
while (InfiniteWait || (Delay > 0));
648 UINT8 StatusRegister;
649 BOOLEAN InfiniteWait;
651 ASSERT (PciIo !=
NULL);
652 ASSERT (IdeRegisters !=
NULL);
657 InfiniteWait =
FALSE;
662 StatusRegister =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
674 }
while (InfiniteWait || (Delay > 0));
735 UINT16 CommandBlockBaseAddr;
736 UINT16 ControlBlockBaseAddr;
737 UINT16 BusMasterBaseAddr;
739 if ((PciIo ==
NULL) || (IdeRegisters ==
NULL)) {
740 return EFI_INVALID_PARAMETER;
743 Status = PciIo->Pci.Read (
751 if (EFI_ERROR (Status)) {
755 BusMasterBaseAddr = (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));
757 if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {
758 CommandBlockBaseAddr = 0x1f0;
759 ControlBlockBaseAddr = 0x3f6;
764 if (((PciData.Device.Bar[0] & BIT0) == 0) ||
765 ((PciData.Device.Bar[1] & BIT0) == 0))
767 return EFI_UNSUPPORTED;
770 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[0] & 0x0000fff8);
771 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[1] & 0x0000fffc) + 2);
777 IdeRegisters[EfiIdePrimary].Data = CommandBlockBaseAddr;
778 IdeRegisters[EfiIdePrimary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
779 IdeRegisters[EfiIdePrimary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
780 IdeRegisters[EfiIdePrimary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
781 IdeRegisters[EfiIdePrimary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
782 IdeRegisters[EfiIdePrimary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
783 IdeRegisters[EfiIdePrimary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
784 IdeRegisters[EfiIdePrimary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
785 IdeRegisters[EfiIdePrimary].AltOrDev = ControlBlockBaseAddr;
786 IdeRegisters[EfiIdePrimary].BusMasterBaseAddr = BusMasterBaseAddr;
788 if ((PciData.Hdr.ClassCode[0] & IDE_SECONDARY_OPERATING_MODE) == 0) {
789 CommandBlockBaseAddr = 0x170;
790 ControlBlockBaseAddr = 0x376;
795 if (((PciData.Device.Bar[2] & BIT0) == 0) ||
796 ((PciData.Device.Bar[3] & BIT0) == 0))
798 return EFI_UNSUPPORTED;
801 CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[2] & 0x0000fff8);
802 ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[3] & 0x0000fffc) + 2);
808 IdeRegisters[EfiIdeSecondary].Data = CommandBlockBaseAddr;
809 IdeRegisters[EfiIdeSecondary].ErrOrFeature = (UINT16)(CommandBlockBaseAddr + 0x01);
810 IdeRegisters[EfiIdeSecondary].SectorCount = (UINT16)(CommandBlockBaseAddr + 0x02);
811 IdeRegisters[EfiIdeSecondary].SectorNumber = (UINT16)(CommandBlockBaseAddr + 0x03);
812 IdeRegisters[EfiIdeSecondary].CylinderLsb = (UINT16)(CommandBlockBaseAddr + 0x04);
813 IdeRegisters[EfiIdeSecondary].CylinderMsb = (UINT16)(CommandBlockBaseAddr + 0x05);
814 IdeRegisters[EfiIdeSecondary].Head = (UINT16)(CommandBlockBaseAddr + 0x06);
815 IdeRegisters[EfiIdeSecondary].CmdOrStatus = (UINT16)(CommandBlockBaseAddr + 0x07);
816 IdeRegisters[EfiIdeSecondary].AltOrDev = ControlBlockBaseAddr;
817 IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16)(BusMasterBaseAddr + 0x8);
847 ASSERT (PciIo !=
NULL);
848 ASSERT (IdeRegisters !=
NULL);
849 ASSERT (AtaCommandBlock !=
NULL);
851 DeviceHead = AtaCommandBlock->AtaDeviceHead;
852 AtaCommand = AtaCommandBlock->AtaCommand;
855 if (EFI_ERROR (Status)) {
856 return EFI_DEVICE_ERROR;
862 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
868 Status =
DRQClear2 (PciIo, IdeRegisters, Timeout);
869 if (EFI_ERROR (Status)) {
870 return EFI_DEVICE_ERROR;
876 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeaturesExp);
877 IdeWritePortB (PciIo, IdeRegisters->ErrOrFeature, AtaCommandBlock->AtaFeatures);
882 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCountExp);
883 IdeWritePortB (PciIo, IdeRegisters->SectorCount, AtaCommandBlock->AtaSectorCount);
888 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumberExp);
889 IdeWritePortB (PciIo, IdeRegisters->SectorNumber, AtaCommandBlock->AtaSectorNumber);
891 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLowExp);
892 IdeWritePortB (PciIo, IdeRegisters->CylinderLsb, AtaCommandBlock->AtaCylinderLow);
894 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHighExp);
895 IdeWritePortB (PciIo, IdeRegisters->CylinderMsb, AtaCommandBlock->AtaCylinderHigh);
900 IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, AtaCommand);
951 if ((PciIo ==
NULL) || (IdeRegisters ==
NULL) || (Buffer ==
NULL) || (AtaCommandBlock ==
NULL)) {
952 return EFI_INVALID_PARAMETER;
958 Status =
AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
959 if (EFI_ERROR (Status)) {
960 Status = EFI_DEVICE_ERROR;
964 Buffer16 = (UINT16 *)Buffer;
988 while (WordCount <
RShiftU64 (ByteCount, 1)) {
992 Status =
DRQReady2 (PciIo, IdeRegisters, Timeout);
993 if (EFI_ERROR (Status)) {
994 Status = EFI_DEVICE_ERROR;
1001 if ((WordCount + Increment) >
RShiftU64 (ByteCount, 1)) {
1022 if (EFI_ERROR (Status)) {
1023 Status = EFI_DEVICE_ERROR;
1027 WordCount += Increment;
1028 Buffer16 += Increment;
1031 Status =
DRQClear (PciIo, IdeRegisters, Timeout);
1032 if (EFI_ERROR (Status)) {
1033 Status = EFI_DEVICE_ERROR;
1080 if ((PciIo ==
NULL) || (IdeRegisters ==
NULL) || (AtaCommandBlock ==
NULL)) {
1081 return EFI_INVALID_PARAMETER;
1087 Status =
AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1088 if (EFI_ERROR (Status)) {
1089 Status = EFI_DEVICE_ERROR;
1097 if (EFI_ERROR (Status)) {
1098 Status = EFI_DEVICE_ERROR;
1103 if (EFI_ERROR (Status)) {
1104 Status = EFI_DEVICE_ERROR;
1139 UINT8 RegisterValue;
1141 UINT16 IoPortForBmis;
1143 BOOLEAN InfiniteWait;
1146 InfiniteWait =
TRUE;
1148 InfiniteWait =
FALSE;
1155 if (EFI_ERROR (Status)) {
1156 Status = EFI_DEVICE_ERROR;
1160 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1162 if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {
1163 DEBUG ((DEBUG_ERROR,
"ATA UDMA operation fails\n"));
1164 Status = EFI_DEVICE_ERROR;
1168 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1178 }
while (InfiniteWait || (Delay > 0));
1204 UINT8 RegisterValue;
1205 UINT16 IoPortForBmis;
1211 if (EFI_ERROR (Status)) {
1212 return EFI_DEVICE_ERROR;
1215 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1218 if ((RegisterValue & BMIS_ERROR) != 0) {
1219 DEBUG ((DEBUG_ERROR,
"ATA UDMA operation fails\n"));
1220 return EFI_DEVICE_ERROR;
1223 if ((RegisterValue & BMIS_INTERRUPT) != 0) {
1227 if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {
1233 return EFI_NOT_READY;
1267 IN VOID *DataBuffer,
1268 IN UINT64 DataLength,
1276 UINT16 IoPortForBmic;
1277 UINT16 IoPortForBmis;
1278 UINT16 IoPortForBmid;
1287 UINT8 RegisterValue;
1290 UINTN ByteRemaining;
1291 UINT8 DeviceControl;
1301 UINTN AlignmentMask;
1302 UINTN RealPageCount;
1312 PciIo = Instance->PciIo;
1314 if ((PciIo ==
NULL) || (IdeRegisters ==
NULL) || (DataBuffer ==
NULL) || (AtaCommandBlock ==
NULL)) {
1315 return EFI_INVALID_PARAMETER;
1323 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
1324 while ((Task ==
NULL) && (!
IsListEmpty (&Instance->NonBlockingTaskList))) {
1332 gBS->RestoreTPL (OldTpl);
1337 if (((
UINTN)DataBuffer & 0x1) != 0) {
1338 return EFI_INVALID_PARAMETER;
1344 IoPortForBmic = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);
1345 IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);
1346 IoPortForBmid = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);
1353 if (((Task !=
NULL) && (!Task->IsStart)) || (Task ==
NULL)) {
1364 if (PrdTableSize > 0x10000) {
1365 return EFI_INVALID_PARAMETER;
1379 ASSERT (RealPageCount > PageCount);
1381 Status = PciIo->AllocateBuffer (
1389 if (EFI_ERROR (Status)) {
1390 return EFI_OUT_OF_RESOURCES;
1394 Status = PciIo->Map (
1397 (VOID *)(
UINTN)BaseAddr,
1408 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(
UINTN)BaseAddr);
1409 return EFI_OUT_OF_RESOURCES;
1417 AlignmentMask = SIZE_64KB - 1;
1418 PrdTableBaseAddr = ((
UINTN)BaseAddr + AlignmentMask) & ~AlignmentMask;
1419 PrdTableMapAddr = ((
UINTN)BaseMapAddr + AlignmentMask) & ~AlignmentMask;
1430 ByteCount = (
UINTN)DataLength;
1431 Status = PciIo->Map (
1439 if (EFI_ERROR (Status) || (ByteCount != DataLength)) {
1440 PciIo->Unmap (PciIo, PrdTableMap);
1441 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(
UINTN)BaseAddr);
1442 return EFI_OUT_OF_RESOURCES;
1448 ASSERT ((BufferMapAddress & 0x1) == 0);
1449 ASSERT ((ByteCount & 0x1) == 0);
1454 ByteRemaining = ByteCount;
1456 while (ByteRemaining != 0) {
1457 if (ByteRemaining <= 0x10000) {
1458 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((
UINTN)BufferMapAddress);
1459 TempPrdBaseAddr->ByteCount = (UINT16)ByteRemaining;
1460 TempPrdBaseAddr->EndOfTable = 0x8000;
1464 TempPrdBaseAddr->RegionBaseAddr = (UINT32)((
UINTN)BufferMapAddress);
1465 TempPrdBaseAddr->ByteCount = (UINT16)0x0;
1467 ByteRemaining -= 0x10000;
1468 BufferMapAddress += 0x10000;
1475 DeviceHead = AtaCommandBlock->AtaDeviceHead;
1477 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));
1483 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1489 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1502 RegisterValue |= BMIC_NREAD;
1504 RegisterValue &= ~((UINT8)BMIC_NREAD);
1510 Task->Map = BufferMap;
1511 Task->TableMap = PrdTableMap;
1513 Task->PageCount = RealPageCount;
1514 Task->IsStart =
TRUE;
1520 Status =
AtaIssueCommand (PciIo, IdeRegisters, AtaCommandBlock, Timeout);
1522 if (EFI_ERROR (Status)) {
1523 Status = EFI_DEVICE_ERROR;
1528 if (EFI_ERROR (Status)) {
1529 Status = EFI_DEVICE_ERROR;
1537 RegisterValue |= BMIC_START;
1556 if ((Task ==
NULL) || (Status != EFI_NOT_READY)) {
1561 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
1567 RegisterValue =
IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);
1573 RegisterValue &= ~((UINT8)BMIC_START);
1579 DeviceControl =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1581 IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);
1592 if ((Task ==
NULL) || (Status != EFI_NOT_READY)) {
1594 PciIo->Unmap (PciIo, Task->TableMap);
1595 PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);
1596 PciIo->Unmap (PciIo, Task->Map);
1598 PciIo->Unmap (PciIo, PrdTableMap);
1599 PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(
UINTN)BaseAddr);
1600 PciIo->Unmap (PciIo, BufferMap);
1630 UINT16 TempWordBuffer;
1632 AltRegister =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1634 return EFI_NOT_READY;
1638 TempWordBuffer =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1646 TempWordBuffer =
IdeReadPortB (PciIo, IdeRegisters->AltOrDev);
1676 IN OUT VOID *Buffer,
1677 IN OUT UINT32 *ByteCount,
1682 UINT32 RequiredWordCount;
1683 UINT32 ActualWordCount;
1689 RequiredWordCount = *ByteCount >> 1;
1694 if (RequiredWordCount == 0) {
1701 ActualWordCount = 0;
1703 while (ActualWordCount < RequiredWordCount) {
1708 Status =
DRQReady2 (PciIo, IdeRegisters, Timeout);
1709 if (EFI_ERROR (Status)) {
1710 if (Status == EFI_NOT_READY) {
1724 WordCount =
IdeReadPortB (PciIo, IdeRegisters->CylinderMsb) << 8;
1725 WordCount = WordCount |
IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
1726 WordCount = WordCount & 0xffff;
1729 WordCount =
MIN (WordCount, (RequiredWordCount - ActualWordCount));
1751 if (EFI_ERROR (Status)) {
1752 return EFI_DEVICE_ERROR;
1755 PtrBuffer += WordCount;
1756 ActualWordCount += WordCount;
1772 if (EFI_ERROR (Status)) {
1773 return EFI_DEVICE_ERROR;
1779 Status =
DRQClear (PciIo, IdeRegisters, Timeout);
1780 if (EFI_ERROR (Status)) {
1781 return EFI_DEVICE_ERROR;
1784 *ByteCount = ActualWordCount << 1;
1817 UINT8 PacketCommand[12];
1825 if (Packet->CdbLength > 12) {
1826 return EFI_INVALID_PARAMETER;
1830 CopyMem (PacketCommand, Packet->Cdb, Packet->CdbLength);
1835 AtaCommandBlock.AtaFeatures = 0x00;
1840 AtaCommandBlock.AtaCylinderLow = (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff);
1841 AtaCommandBlock.AtaCylinderHigh = (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8);
1842 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1845 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));
1854 Status =
AtaIssueCommand (PciIo, IdeRegisters, &AtaCommandBlock, Packet->Timeout);
1855 if (EFI_ERROR (Status)) {
1859 Status =
DRQReady (PciIo, IdeRegisters, Packet->Timeout);
1860 if (EFI_ERROR (Status)) {
1867 for (Count = 0; Count < 6; Count++) {
1868 IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16 *)PacketCommand + Count));
1878 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1882 Packet->InDataBuffer,
1883 &Packet->InTransferLength,
1891 Packet->OutDataBuffer,
1892 &Packet->OutTransferLength,
1931 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
1932 AtaCommandBlock.AtaFeatures = 0x03;
1933 AtaCommandBlock.AtaSectorCount = *((UINT8 *)TransferMode);
1940 &Instance->IdeRegisters[Channel],
1980 AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;
1981 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) + DriveParameters->Heads);
1988 &Instance->IdeRegisters[Channel],
1995 if (EFI_ERROR (Status)) {
1996 DEBUG ((DEBUG_WARN,
"Init Drive Parameters Fail, Status = %r\n", Status));
2003 AtaCommandBlock.AtaSectorCount = DriveParameters->MultipleSector;
2004 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2008 &Instance->IdeRegisters[Channel],
2015 if (EFI_ERROR (Status)) {
2016 DEBUG ((DEBUG_WARN,
"Set Multiple Mode Parameters Fail, Status = %r\n", Status));
2054 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2061 &Instance->IdeRegisters[Channel],
2068 if (EFI_ERROR (Status)) {
2071 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
2073 return EFI_DEVICE_ERROR;
2078 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
2081 LBAMid =
IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);
2082 LBAHigh =
IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);
2084 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
2088 DEBUG ((DEBUG_INFO,
"The S.M.A.R.T threshold exceeded condition is not detected\n"));
2091 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
2093 }
else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
2097 DEBUG ((DEBUG_INFO,
"The S.M.A.R.T threshold exceeded condition is detected\n"));
2100 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
2133 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
2139 "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2140 (Channel == 1) ?
"secondary" :
"primary",
2141 (Device == 1) ?
"slave" :
"master"
2145 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
2151 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
2154 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
2163 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2170 &Instance->IdeRegisters[Channel],
2177 if (!EFI_ERROR (Status)) {
2184 AtaCommandBlock.AtaFeatures = 0xD2;
2185 AtaCommandBlock.AtaSectorCount = 0xF1;
2188 AtaCommandBlock.AtaDeviceHead = (UINT8)((Device << 0x4) | 0xe0);
2192 &Instance->IdeRegisters[Channel],
2198 if (!EFI_ERROR (Status)) {
2211 "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2212 (Channel == 1) ?
"secondary" :
"primary",
2213 (Device == 1) ?
"slave" :
"master"
2258 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2262 &Instance->IdeRegisters[Channel],
2323 AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);
2330 &Instance->IdeRegisters[Channel],
2373 UINT8 SectorCountReg;
2377 EFI_ATA_DEVICE_TYPE DeviceType;
2389 IdeRegisters = &Instance->IdeRegisters[IdeChannel];
2390 IdeInit = Instance->IdeControllerInit;
2391 PciIo = Instance->PciIo;
2393 for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {
2397 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2406 if (EFI_ERROR (Status)) {
2407 DEBUG ((DEBUG_ERROR,
"New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));
2414 IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));
2420 SectorCountReg =
IdeReadPortB (PciIo, IdeRegisters->SectorCount);
2421 LBALowReg =
IdeReadPortB (PciIo, IdeRegisters->SectorNumber);
2422 LBAMidReg =
IdeReadPortB (PciIo, IdeRegisters->CylinderLsb);
2423 LBAHighReg =
IdeReadPortB (PciIo, IdeRegisters->CylinderMsb);
2428 if ((SectorCountReg == 0x1) && (LBALowReg == 0x1) && (LBAMidReg == 0x0) && (LBAHighReg == 0x0)) {
2429 DeviceType = EfiIdeHarddisk;
2430 }
else if ((LBAMidReg == 0x14) && (LBAHighReg == 0xeb)) {
2431 DeviceType = EfiIdeCdrom;
2439 if (DeviceType == EfiIdeHarddisk) {
2440 Status =
AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer,
NULL);
2444 if (EFI_ERROR (Status)) {
2447 DeviceType = EfiIdeCdrom;
2455 if (EFI_ERROR (Status)) {
2456 DeviceType = EfiIdeHarddisk;
2457 Status =
AtaIdentify (Instance, IdeChannel, IdeDevice, &Buffer,
NULL);
2461 if (EFI_ERROR (Status)) {
2470 "[%a] channel [%a] [%a] device\n",
2471 (IdeChannel == 1) ?
"secondary" :
"primary ",
2472 (IdeDevice == 1) ?
"slave " :
"master",
2473 DeviceType == EfiIdeCdrom ?
"cdrom " :
"harddisk"
2478 if ((DeviceType == EfiIdeHarddisk) &&
PcdGetBool (PcdAtaSmartEnable)) {
2491 IdeInit->
SubmitData (IdeInit, IdeChannel, IdeDevice, &Buffer);
2502 if (EFI_ERROR (Status)) {
2503 DEBUG ((DEBUG_ERROR,
"Calculate Mode Fail, Status = %r\n", Status));
2510 if (SupportedModes->
PioMode.
Mode <= EfiAtaPioMode2) {
2511 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2513 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2516 TransferMode.ModeNumber = (UINT8)(SupportedModes->
PioMode.
Mode);
2521 if (EFI_ERROR (Status)) {
2522 DEBUG ((DEBUG_ERROR,
"Set transfer Mode Fail, Status = %r\n", Status));
2534 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2535 TransferMode.ModeNumber = (UINT8)(SupportedModes->
UdmaMode.
Mode);
2538 if (EFI_ERROR (Status)) {
2539 DEBUG ((DEBUG_ERROR,
"Set transfer Mode Fail, Status = %r\n", Status));
2543 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2547 if (EFI_ERROR (Status)) {
2548 DEBUG ((DEBUG_ERROR,
"Set transfer Mode Fail, Status = %r\n", Status));
2558 if (DeviceType == EfiIdeHarddisk) {
2572 IdeInit->
SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);
2579 if (EFI_ERROR (Status)) {
2583 if (DeviceType == EfiIdeHarddisk) {
2610 BOOLEAN ChannelEnabled;
2613 IdeInit = Instance->IdeControllerInit;
2614 PciIo = Instance->PciIo;
2621 if (EFI_ERROR (Status)) {
2625 for (IdeChannel = 0; IdeChannel < Channel; IdeChannel++) {
2637 if (EFI_ERROR (Status)) {
2638 DEBUG ((DEBUG_ERROR,
"[GetChannel, Status=%x]", Status));
2642 if (!ChannelEnabled) {
2646 ASSERT (MaxDevices <= 2);
2672 IdeInit->
NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID EFIAPI AsyncNonBlockingTransferRoutine(EFI_EVENT Event, VOID *Context)
EFI_STATUS EFIAPI CreateNewDeviceInfo(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT16 Port, IN UINT16 PortMultiplier, IN EFI_ATA_DEVICE_TYPE DeviceType, IN EFI_IDENTIFY_DATA *IdentifyData)
#define ATA_SMART_ENABLE_OPERATION
reserved
#define ATA_CMD_SET_FEATURES
defined from ATA-1
#define ATA_CTLREG_IEN_L
Interrupt Enable #.
#define ATA_SMART_RETURN_STATUS
defined from ATA-3
#define ATA_CONSTANT_C2
reserved
#define ATA_STSREG_BSY
Controller Busy defined from ATA-1.
#define ATA_ERRREG_ABRT
Aborted Command defined from ATA-1.
#define ATA_STSREG_DRQ
Data Request defined from ATA-1.
#define ATA_CMD_SMART
defined from ATA-3
#define ATA_STSREG_DWF
Drive Write Fault defined from ATA-1, obsoleted from ATA-4.
#define ATA_STSREG_ERR
Error defined from ATA-1.
#define ATA_ERRREG_MC
Media Change defined from ATA-1, obsoleted from ATA-4.
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
#define ATA_ERRREG_TK0NF
Track 0 Not Found defined from ATA-1, obsoleted from ATA-4.
#define ATA_CMD_EXEC_DRIVE_DIAG
defined from ATA-1
#define ATA_ERRREG_UNC
Uncorrectable Data defined from ATA-1, obsoleted from ATA-4.
#define ATA_ERRREG_AMNF
Address Mark Not Found defined from ATA-1, obsoleted from ATA-4.
#define ATA_CMD_INIT_DRIVE_PARAM
defined from ATA-1, obsoleted from ATA-6
#define ATA_CMD_SET_MULTIPLE_MODE
defined from ATA-2
#define ATA_STSREG_CORR
Corrected Data defined from ATA-1, obsoleted from ATA-4.
#define ATA_CONSTANT_4F
reserved
#define ATA_ERRREG_BBK
Bad block detected defined from ATA-1, obsoleted from ATA-2.
#define ATA_CMD_IDENTIFY_DEVICE
defined from ATA-3
#define ATA_CMD_PACKET
defined from ATA-3
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
@ EfiIdeBeforeChannelReset
@ EfiIdeAfterChannelReset
@ EfiIdeBeforeChannelEnumeration
@ EfiIdeBusBeforeDevicePresenceDetection
EFI_STATUS EFIAPI DetectAndConfigIdeDevice(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 IdeChannel)
VOID EFIAPI IdeWritePortDW(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT32 Data)
EFI_STATUS EFIAPI AtaPioDataInOut(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT VOID *Buffer, IN UINT64 ByteCount, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
EFI_STATUS EFIAPI AtaIdentifyPacket(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_IDENTIFY_DATA *Buffer, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI AtaPacketReadPendingData(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters)
VOID EFIAPI IdeAtaSmartSupport(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_IDENTIFY_DATA *IdentifyData, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI DRQReady(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
UINT8 EFIAPI IdeReadPortB(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port)
EFI_STATUS EFIAPI GetIdeRegisterIoAddr(IN EFI_PCI_IO_PROTOCOL *PciIo, IN OUT EFI_IDE_REGISTERS *IdeRegisters)
EFI_STATUS EFIAPI DRQReady2(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
EFI_STATUS EFIAPI AtaPacketCommandExecute(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT8 Channel, IN UINT8 Device, IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet)
EFI_STATUS EFIAPI WaitForBSYClear(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
EFI_STATUS EFIAPI SetDeviceTransferMode(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_TRANSFER_MODE *TransferMode, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI AtaNonDataCommandIn(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
VOID EFIAPI IdeWritePortWMultiple(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINTN Count, IN VOID *Buffer)
VOID EFIAPI IdeWritePortB(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT8 Data)
EFI_STATUS EFIAPI IdeAtaSmartReturnStatusCheck(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI AtaIdentify(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN OUT EFI_IDENTIFY_DATA *Buffer, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI DRQClear2(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
EFI_STATUS AtaUdmStatusCheck(IN EFI_PCI_IO_PROTOCOL *PciIo, IN ATA_NONBLOCK_TASK *Task, IN EFI_IDE_REGISTERS *IdeRegisters)
VOID EFIAPI DumpAllIdeRegisters(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
VOID EFIAPI IdeReadPortWMultiple(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINTN Count, IN VOID *Buffer)
EFI_STATUS EFIAPI AtaIssueCommand(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN UINT64 Timeout)
EFI_STATUS EFIAPI AtaUdmaInOut(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN EFI_IDE_REGISTERS *IdeRegisters, IN BOOLEAN Read, IN VOID *DataBuffer, IN UINT64 DataLength, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout, IN ATA_NONBLOCK_TASK *Task)
EFI_STATUS EFIAPI AtaPacketReadWrite(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN OUT VOID *Buffer, IN OUT UINT32 *ByteCount, IN BOOLEAN Read, IN UINT64 Timeout)
EFI_STATUS EFIAPI SetDriveParameters(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, IN UINT8 Channel, IN UINT8 Device, IN EFI_ATA_DRIVE_PARMS *DriveParameters, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock)
EFI_STATUS EFIAPI IdeModeInitialization(IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance)
EFI_STATUS EFIAPI DRQClear(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
EFI_STATUS AtaUdmStatusWait(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters, IN UINT64 Timeout)
EFI_STATUS EFIAPI CheckStatusRegister(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_IDE_REGISTERS *IdeRegisters)
VOID EFIAPI IdeWritePortW(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT16 Port, IN UINT16 Data)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
#define REPORT_STATUS_CODE(Type, Value)
#define EFI_PCI_IO_PASS_THROUGH_BAR
Special BAR that passes a memory or I/O cycle through unchanged.
EFI_PCI_IO_PROTOCOL_OPERATION
@ EfiPciIoOperationBusMasterWrite
@ EfiPciIoOperationBusMasterRead
@ EfiPciIoOperationBusMasterCommonBuffer
#define PcdGetBool(TokenName)
#define EFI_PROGRESS_CODE
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_IDE_CONTROLLER_SUBMIT_DATA SubmitData
EFI_IDE_CONTROLLER_SET_TIMING SetTiming
EFI_IDE_CONTROLLER_CALCULATE_MODE CalculateMode
EFI_IDE_CONTROLLER_NOTIFY_PHASE NotifyPhase
EFI_IDE_CONTROLLER_GET_CHANNEL_INFO GetChannelInfo
EFI_ATA_MODE MultiWordDmaMode
UINT32 Mode
The actual ATA mode. This field is not a bit map.
BOOLEAN Valid
TRUE if Mode is valid.
EFI_ATA_IDENTIFY_DATA AtaData