1 /** @file 2 The file for AHCI mode of ATA host controller. 3 4 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR> 5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "AtaAtapiPassThru.h" 17 18 /** 19 Read AHCI Operation register. 20 21 @param PciIo The PCI IO protocol instance. 22 @param Offset The operation register offset. 23 24 @return The register content read. 25 26 **/ 27 UINT32 28 EFIAPI 29 AhciReadReg ( 30 IN EFI_PCI_IO_PROTOCOL *PciIo, 31 IN UINT32 Offset 32 ) 33 { 34 UINT32 Data; 35 36 ASSERT (PciIo != NULL); 37 38 Data = 0; 39 40 PciIo->Mem.Read ( 41 PciIo, 42 EfiPciIoWidthUint32, 43 EFI_AHCI_BAR_INDEX, 44 (UINT64) Offset, 45 1, 46 &Data 47 ); 48 49 return Data; 50 } 51 52 /** 53 Write AHCI Operation register. 54 55 @param PciIo The PCI IO protocol instance. 56 @param Offset The operation register offset. 57 @param Data The data used to write down. 58 59 **/ 60 VOID 61 EFIAPI 62 AhciWriteReg ( 63 IN EFI_PCI_IO_PROTOCOL *PciIo, 64 IN UINT32 Offset, 65 IN UINT32 Data 66 ) 67 { 68 ASSERT (PciIo != NULL); 69 70 PciIo->Mem.Write ( 71 PciIo, 72 EfiPciIoWidthUint32, 73 EFI_AHCI_BAR_INDEX, 74 (UINT64) Offset, 75 1, 76 &Data 77 ); 78 79 return ; 80 } 81 82 /** 83 Do AND operation with the value of AHCI Operation register. 84 85 @param PciIo The PCI IO protocol instance. 86 @param Offset The operation register offset. 87 @param AndData The data used to do AND operation. 88 89 **/ 90 VOID 91 EFIAPI 92 AhciAndReg ( 93 IN EFI_PCI_IO_PROTOCOL *PciIo, 94 IN UINT32 Offset, 95 IN UINT32 AndData 96 ) 97 { 98 UINT32 Data; 99 100 ASSERT (PciIo != NULL); 101 102 Data = AhciReadReg (PciIo, Offset); 103 104 Data &= AndData; 105 106 AhciWriteReg (PciIo, Offset, Data); 107 } 108 109 /** 110 Do OR operation with the value of AHCI Operation register. 111 112 @param PciIo The PCI IO protocol instance. 113 @param Offset The operation register offset. 114 @param OrData The data used to do OR operation. 115 116 **/ 117 VOID 118 EFIAPI 119 AhciOrReg ( 120 IN EFI_PCI_IO_PROTOCOL *PciIo, 121 IN UINT32 Offset, 122 IN UINT32 OrData 123 ) 124 { 125 UINT32 Data; 126 127 ASSERT (PciIo != NULL); 128 129 Data = AhciReadReg (PciIo, Offset); 130 131 Data |= OrData; 132 133 AhciWriteReg (PciIo, Offset, Data); 134 } 135 136 /** 137 Wait for the value of the specified MMIO register set to the test value. 138 139 @param PciIo The PCI IO protocol instance. 140 @param Offset The MMIO address to test. 141 @param MaskValue The mask value of memory. 142 @param TestValue The test value of memory. 143 @param Timeout The time out value for wait memory set, uses 100ns as a unit. 144 145 @retval EFI_TIMEOUT The MMIO setting is time out. 146 @retval EFI_SUCCESS The MMIO is correct set. 147 148 **/ 149 EFI_STATUS 150 EFIAPI 151 AhciWaitMmioSet ( 152 IN EFI_PCI_IO_PROTOCOL *PciIo, 153 IN UINTN Offset, 154 IN UINT32 MaskValue, 155 IN UINT32 TestValue, 156 IN UINT64 Timeout 157 ) 158 { 159 UINT32 Value; 160 UINT64 Delay; 161 BOOLEAN InfiniteWait; 162 163 if (Timeout == 0) { 164 InfiniteWait = TRUE; 165 } else { 166 InfiniteWait = FALSE; 167 } 168 169 Delay = DivU64x32 (Timeout, 1000) + 1; 170 171 do { 172 // 173 // Access PCI MMIO space to see if the value is the tested one. 174 // 175 Value = AhciReadReg (PciIo, (UINT32) Offset) & MaskValue; 176 177 if (Value == TestValue) { 178 return EFI_SUCCESS; 179 } 180 181 // 182 // Stall for 100 microseconds. 183 // 184 MicroSecondDelay (100); 185 186 Delay--; 187 188 } while (InfiniteWait || (Delay > 0)); 189 190 return EFI_TIMEOUT; 191 } 192 193 /** 194 Wait for the value of the specified system memory set to the test value. 195 196 @param Address The system memory address to test. 197 @param MaskValue The mask value of memory. 198 @param TestValue The test value of memory. 199 @param Timeout The time out value for wait memory set, uses 100ns as a unit. 200 201 @retval EFI_TIMEOUT The system memory setting is time out. 202 @retval EFI_SUCCESS The system memory is correct set. 203 204 **/ 205 EFI_STATUS 206 EFIAPI 207 AhciWaitMemSet ( 208 IN EFI_PHYSICAL_ADDRESS Address, 209 IN UINT32 MaskValue, 210 IN UINT32 TestValue, 211 IN UINT64 Timeout 212 ) 213 { 214 UINT32 Value; 215 UINT64 Delay; 216 BOOLEAN InfiniteWait; 217 218 if (Timeout == 0) { 219 InfiniteWait = TRUE; 220 } else { 221 InfiniteWait = FALSE; 222 } 223 224 Delay = DivU64x32 (Timeout, 1000) + 1; 225 226 do { 227 // 228 // Access sytem memory to see if the value is the tested one. 229 // 230 // The system memory pointed by Address will be updated by the 231 // SATA Host Controller, "volatile" is introduced to prevent 232 // compiler from optimizing the access to the memory address 233 // to only read once. 234 // 235 Value = *(volatile UINT32 *) (UINTN) Address; 236 Value &= MaskValue; 237 238 if (Value == TestValue) { 239 return EFI_SUCCESS; 240 } 241 242 // 243 // Stall for 100 microseconds. 244 // 245 MicroSecondDelay (100); 246 247 Delay--; 248 249 } while (InfiniteWait || (Delay > 0)); 250 251 return EFI_TIMEOUT; 252 } 253 254 /** 255 Check the memory status to the test value. 256 257 @param[in] Address The memory address to test. 258 @param[in] MaskValue The mask value of memory. 259 @param[in] TestValue The test value of memory. 260 @param[in, out] Task Optional. Pointer to the ATA_NONBLOCK_TASK used by 261 non-blocking mode. If NULL, then just try once. 262 263 @retval EFI_NOTREADY The memory is not set. 264 @retval EFI_TIMEOUT The memory setting retry times out. 265 @retval EFI_SUCCESS The memory is correct set. 266 267 **/ 268 EFI_STATUS 269 EFIAPI 270 AhciCheckMemSet ( 271 IN UINTN Address, 272 IN UINT32 MaskValue, 273 IN UINT32 TestValue, 274 IN OUT ATA_NONBLOCK_TASK *Task 275 ) 276 { 277 UINT32 Value; 278 279 if (Task != NULL) { 280 Task->RetryTimes--; 281 } 282 283 Value = *(volatile UINT32 *) Address; 284 Value &= MaskValue; 285 286 if (Value == TestValue) { 287 return EFI_SUCCESS; 288 } 289 290 if ((Task != NULL) && !Task->InfiniteWait && (Task->RetryTimes == 0)) { 291 return EFI_TIMEOUT; 292 } else { 293 return EFI_NOT_READY; 294 } 295 } 296 297 /** 298 Check if the device is still on port. It also checks if the AHCI controller 299 supports the address and data count will be transferred. 300 301 @param PciIo The PCI IO protocol instance. 302 @param Port The number of port. 303 304 @retval EFI_SUCCESS The device is attached to port and the transfer data is 305 supported by AHCI controller. 306 @retval EFI_UNSUPPORTED The transfer address and count is not supported by AHCI 307 controller. 308 @retval EFI_NOT_READY The physical communication between AHCI controller and device 309 is not ready. 310 311 **/ 312 EFI_STATUS 313 EFIAPI 314 AhciCheckDeviceStatus ( 315 IN EFI_PCI_IO_PROTOCOL *PciIo, 316 IN UINT8 Port 317 ) 318 { 319 UINT32 Data; 320 UINT32 Offset; 321 322 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS; 323 324 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK; 325 326 if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) { 327 return EFI_SUCCESS; 328 } 329 330 return EFI_NOT_READY; 331 } 332 333 /** 334 335 Clear the port interrupt and error status. It will also clear 336 HBA interrupt status. 337 338 @param PciIo The PCI IO protocol instance. 339 @param Port The number of port. 340 341 **/ 342 VOID 343 EFIAPI 344 AhciClearPortStatus ( 345 IN EFI_PCI_IO_PROTOCOL *PciIo, 346 IN UINT8 Port 347 ) 348 { 349 UINT32 Offset; 350 351 // 352 // Clear any error status 353 // 354 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR; 355 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset)); 356 357 // 358 // Clear any port interrupt status 359 // 360 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS; 361 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset)); 362 363 // 364 // Clear any HBA interrupt status 365 // 366 AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET)); 367 } 368 369 /** 370 This function is used to dump the Status Registers and if there is ERR bit set 371 in the Status Register, the Error Register's value is also be dumped. 372 373 @param PciIo The PCI IO protocol instance. 374 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 375 @param Port The number of port. 376 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure. 377 378 **/ 379 VOID 380 EFIAPI 381 AhciDumpPortStatus ( 382 IN EFI_PCI_IO_PROTOCOL *PciIo, 383 IN EFI_AHCI_REGISTERS *AhciRegisters, 384 IN UINT8 Port, 385 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock 386 ) 387 { 388 UINTN Offset; 389 UINT32 Data; 390 UINTN FisBaseAddr; 391 EFI_STATUS Status; 392 393 ASSERT (PciIo != NULL); 394 395 if (AtaStatusBlock != NULL) { 396 ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); 397 398 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); 399 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; 400 401 Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, NULL); 402 if (!EFI_ERROR (Status)) { 403 // 404 // If D2H FIS is received, update StatusBlock with its content. 405 // 406 CopyMem (AtaStatusBlock, (UINT8 *)Offset, sizeof (EFI_ATA_STATUS_BLOCK)); 407 } else { 408 // 409 // If D2H FIS is not received, only update Status & Error field through PxTFD 410 // as there is no other way to get the content of the Shadow Register Block. 411 // 412 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 413 Data = AhciReadReg (PciIo, (UINT32)Offset); 414 415 AtaStatusBlock->AtaStatus = (UINT8)Data; 416 if ((AtaStatusBlock->AtaStatus & BIT0) != 0) { 417 AtaStatusBlock->AtaError = (UINT8)(Data >> 8); 418 } 419 } 420 } 421 } 422 423 424 /** 425 Enable the FIS running for giving port. 426 427 @param PciIo The PCI IO protocol instance. 428 @param Port The number of port. 429 @param Timeout The timeout value of enabling FIS, uses 100ns as a unit. 430 431 @retval EFI_DEVICE_ERROR The FIS enable setting fails. 432 @retval EFI_TIMEOUT The FIS enable setting is time out. 433 @retval EFI_SUCCESS The FIS enable successfully. 434 435 **/ 436 EFI_STATUS 437 EFIAPI 438 AhciEnableFisReceive ( 439 IN EFI_PCI_IO_PROTOCOL *PciIo, 440 IN UINT8 Port, 441 IN UINT64 Timeout 442 ) 443 { 444 UINT32 Offset; 445 446 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 447 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE); 448 449 return EFI_SUCCESS; 450 } 451 452 /** 453 Disable the FIS running for giving port. 454 455 @param PciIo The PCI IO protocol instance. 456 @param Port The number of port. 457 @param Timeout The timeout value of disabling FIS, uses 100ns as a unit. 458 459 @retval EFI_DEVICE_ERROR The FIS disable setting fails. 460 @retval EFI_TIMEOUT The FIS disable setting is time out. 461 @retval EFI_UNSUPPORTED The port is in running state. 462 @retval EFI_SUCCESS The FIS disable successfully. 463 464 **/ 465 EFI_STATUS 466 EFIAPI 467 AhciDisableFisReceive ( 468 IN EFI_PCI_IO_PROTOCOL *PciIo, 469 IN UINT8 Port, 470 IN UINT64 Timeout 471 ) 472 { 473 UINT32 Offset; 474 UINT32 Data; 475 476 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 477 Data = AhciReadReg (PciIo, Offset); 478 479 // 480 // Before disabling Fis receive, the DMA engine of the port should NOT be in running status. 481 // 482 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) { 483 return EFI_UNSUPPORTED; 484 } 485 486 // 487 // Check if the Fis receive DMA engine for the port is running. 488 // 489 if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) { 490 return EFI_SUCCESS; 491 } 492 493 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE)); 494 495 return AhciWaitMmioSet ( 496 PciIo, 497 Offset, 498 EFI_AHCI_PORT_CMD_FR, 499 0, 500 Timeout 501 ); 502 } 503 504 505 506 /** 507 Build the command list, command table and prepare the fis receiver. 508 509 @param PciIo The PCI IO protocol instance. 510 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 511 @param Port The number of port. 512 @param PortMultiplier The timeout value of stop. 513 @param CommandFis The control fis will be used for the transfer. 514 @param CommandList The command list will be used for the transfer. 515 @param AtapiCommand The atapi command will be used for the transfer. 516 @param AtapiCommandLength The length of the atapi command. 517 @param CommandSlotNumber The command slot will be used for the transfer. 518 @param DataPhysicalAddr The pointer to the data buffer pci bus master address. 519 @param DataLength The data count to be transferred. 520 521 **/ 522 VOID 523 EFIAPI 524 AhciBuildCommand ( 525 IN EFI_PCI_IO_PROTOCOL *PciIo, 526 IN EFI_AHCI_REGISTERS *AhciRegisters, 527 IN UINT8 Port, 528 IN UINT8 PortMultiplier, 529 IN EFI_AHCI_COMMAND_FIS *CommandFis, 530 IN EFI_AHCI_COMMAND_LIST *CommandList, 531 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, 532 IN UINT8 AtapiCommandLength, 533 IN UINT8 CommandSlotNumber, 534 IN OUT VOID *DataPhysicalAddr, 535 IN UINT32 DataLength 536 ) 537 { 538 UINT64 BaseAddr; 539 UINT32 PrdtNumber; 540 UINT32 PrdtIndex; 541 UINTN RemainedData; 542 UINTN MemAddr; 543 DATA_64 Data64; 544 UINT32 Offset; 545 546 // 547 // Filling the PRDT 548 // 549 PrdtNumber = (UINT32)DivU64x32 (((UINT64)DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1), EFI_AHCI_MAX_DATA_PER_PRDT); 550 551 // 552 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block. 553 // It also limits that the maximum amount of the PRDT entry in the command table 554 // is 65535. 555 // 556 ASSERT (PrdtNumber <= 65535); 557 558 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port; 559 560 BaseAddr = Data64.Uint64; 561 562 ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS)); 563 564 ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE)); 565 566 CommandFis->AhciCFisPmNum = PortMultiplier; 567 568 CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS)); 569 570 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 571 if (AtapiCommand != NULL) { 572 CopyMem ( 573 &AhciRegisters->AhciCommandTable->AtapiCmd, 574 AtapiCommand, 575 AtapiCommandLength 576 ); 577 578 CommandList->AhciCmdA = 1; 579 CommandList->AhciCmdP = 1; 580 581 AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI)); 582 } else { 583 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI)); 584 } 585 586 RemainedData = (UINTN) DataLength; 587 MemAddr = (UINTN) DataPhysicalAddr; 588 CommandList->AhciCmdPrdtl = PrdtNumber; 589 590 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) { 591 if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) { 592 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1; 593 } else { 594 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1; 595 } 596 597 Data64.Uint64 = (UINT64)MemAddr; 598 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32; 599 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32; 600 RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT; 601 MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT; 602 } 603 604 // 605 // Set the last PRDT to Interrupt On Complete 606 // 607 if (PrdtNumber > 0) { 608 AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1; 609 } 610 611 CopyMem ( 612 (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)), 613 CommandList, 614 sizeof (EFI_AHCI_COMMAND_LIST) 615 ); 616 617 Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr; 618 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32; 619 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32; 620 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier; 621 622 } 623 624 /** 625 Buid a command FIS. 626 627 @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure. 628 @param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure. 629 630 **/ 631 VOID 632 EFIAPI 633 AhciBuildCommandFis ( 634 IN OUT EFI_AHCI_COMMAND_FIS *CmdFis, 635 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock 636 ) 637 { 638 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS)); 639 640 CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D; 641 // 642 // Indicator it's a command 643 // 644 CmdFis->AhciCFisCmdInd = 0x1; 645 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand; 646 647 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures; 648 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp; 649 650 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber; 651 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp; 652 653 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow; 654 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp; 655 656 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh; 657 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp; 658 659 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount; 660 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp; 661 662 CmdFis->AhciCFisDevHead = (UINT8) (AtaCommandBlock->AtaDeviceHead | 0xE0); 663 } 664 665 /** 666 Start a PIO data transfer on specific port. 667 668 @param[in] PciIo The PCI IO protocol instance. 669 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 670 @param[in] Port The number of port. 671 @param[in] PortMultiplier The timeout value of stop. 672 @param[in] AtapiCommand The atapi command will be used for the 673 transfer. 674 @param[in] AtapiCommandLength The length of the atapi command. 675 @param[in] Read The transfer direction. 676 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data. 677 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data. 678 @param[in, out] MemoryAddr The pointer to the data buffer. 679 @param[in] DataCount The data count to be transferred. 680 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit. 681 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK 682 used by non-blocking mode. 683 684 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs. 685 @retval EFI_TIMEOUT The operation is time out. 686 @retval EFI_UNSUPPORTED The device is not ready for transfer. 687 @retval EFI_SUCCESS The PIO data transfer executes successfully. 688 689 **/ 690 EFI_STATUS 691 EFIAPI 692 AhciPioTransfer ( 693 IN EFI_PCI_IO_PROTOCOL *PciIo, 694 IN EFI_AHCI_REGISTERS *AhciRegisters, 695 IN UINT8 Port, 696 IN UINT8 PortMultiplier, 697 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, 698 IN UINT8 AtapiCommandLength, 699 IN BOOLEAN Read, 700 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, 701 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, 702 IN OUT VOID *MemoryAddr, 703 IN UINT32 DataCount, 704 IN UINT64 Timeout, 705 IN ATA_NONBLOCK_TASK *Task 706 ) 707 { 708 EFI_STATUS Status; 709 UINTN FisBaseAddr; 710 UINTN Offset; 711 EFI_PHYSICAL_ADDRESS PhyAddr; 712 VOID *Map; 713 UINTN MapLength; 714 EFI_PCI_IO_PROTOCOL_OPERATION Flag; 715 UINT64 Delay; 716 EFI_AHCI_COMMAND_FIS CFis; 717 EFI_AHCI_COMMAND_LIST CmdList; 718 UINT32 PortTfd; 719 UINT32 PrdCount; 720 BOOLEAN InfiniteWait; 721 BOOLEAN PioFisReceived; 722 BOOLEAN D2hFisReceived; 723 724 if (Timeout == 0) { 725 InfiniteWait = TRUE; 726 } else { 727 InfiniteWait = FALSE; 728 } 729 730 if (Read) { 731 Flag = EfiPciIoOperationBusMasterWrite; 732 } else { 733 Flag = EfiPciIoOperationBusMasterRead; 734 } 735 736 // 737 // construct command list and command table with pci bus address 738 // 739 MapLength = DataCount; 740 Status = PciIo->Map ( 741 PciIo, 742 Flag, 743 MemoryAddr, 744 &MapLength, 745 &PhyAddr, 746 &Map 747 ); 748 749 if (EFI_ERROR (Status) || (DataCount != MapLength)) { 750 return EFI_BAD_BUFFER_SIZE; 751 } 752 753 // 754 // Package read needed 755 // 756 AhciBuildCommandFis (&CFis, AtaCommandBlock); 757 758 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST)); 759 760 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; 761 CmdList.AhciCmdW = Read ? 0 : 1; 762 763 AhciBuildCommand ( 764 PciIo, 765 AhciRegisters, 766 Port, 767 PortMultiplier, 768 &CFis, 769 &CmdList, 770 AtapiCommand, 771 AtapiCommandLength, 772 0, 773 (VOID *)(UINTN)PhyAddr, 774 DataCount 775 ); 776 777 Status = AhciStartCommand ( 778 PciIo, 779 Port, 780 0, 781 Timeout 782 ); 783 if (EFI_ERROR (Status)) { 784 goto Exit; 785 } 786 787 // 788 // Check the status and wait the driver sending data 789 // 790 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); 791 792 if (Read && (AtapiCommand == 0)) { 793 // 794 // Wait device sends the PIO setup fis before data transfer 795 // 796 Status = EFI_TIMEOUT; 797 Delay = DivU64x32 (Timeout, 1000) + 1; 798 do { 799 PioFisReceived = FALSE; 800 D2hFisReceived = FALSE; 801 Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET; 802 Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, NULL); 803 if (!EFI_ERROR (Status)) { 804 PioFisReceived = TRUE; 805 } 806 // 807 // According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered. 808 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from device 809 // after the transaction is finished successfully. 810 // To get better device compatibilities, we further check if the PxTFD's ERR bit is set. 811 // By this way, we can know if there is a real error happened. 812 // 813 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; 814 Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, NULL); 815 if (!EFI_ERROR (Status)) { 816 D2hFisReceived = TRUE; 817 } 818 819 if (PioFisReceived || D2hFisReceived) { 820 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 821 PortTfd = AhciReadReg (PciIo, (UINT32) Offset); 822 // 823 // PxTFD will be updated if there is a D2H or SetupFIS received. 824 // 825 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) { 826 Status = EFI_DEVICE_ERROR; 827 break; 828 } 829 830 PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc)); 831 if (PrdCount == DataCount) { 832 Status = EFI_SUCCESS; 833 break; 834 } 835 } 836 837 // 838 // Stall for 100 microseconds. 839 // 840 MicroSecondDelay(100); 841 842 Delay--; 843 if (Delay == 0) { 844 Status = EFI_TIMEOUT; 845 } 846 } while (InfiniteWait || (Delay > 0)); 847 } else { 848 // 849 // Wait for D2H Fis is received 850 // 851 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; 852 Status = AhciWaitMemSet ( 853 Offset, 854 EFI_AHCI_FIS_TYPE_MASK, 855 EFI_AHCI_FIS_REGISTER_D2H, 856 Timeout 857 ); 858 859 if (EFI_ERROR (Status)) { 860 goto Exit; 861 } 862 863 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 864 PortTfd = AhciReadReg (PciIo, (UINT32) Offset); 865 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) { 866 Status = EFI_DEVICE_ERROR; 867 } 868 } 869 870 Exit: 871 AhciStopCommand ( 872 PciIo, 873 Port, 874 Timeout 875 ); 876 877 AhciDisableFisReceive ( 878 PciIo, 879 Port, 880 Timeout 881 ); 882 883 PciIo->Unmap ( 884 PciIo, 885 Map 886 ); 887 888 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); 889 890 return Status; 891 } 892 893 /** 894 Start a DMA data transfer on specific port 895 896 @param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance. 897 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 898 @param[in] Port The number of port. 899 @param[in] PortMultiplier The timeout value of stop. 900 @param[in] AtapiCommand The atapi command will be used for the 901 transfer. 902 @param[in] AtapiCommandLength The length of the atapi command. 903 @param[in] Read The transfer direction. 904 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data. 905 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data. 906 @param[in, out] MemoryAddr The pointer to the data buffer. 907 @param[in] DataCount The data count to be transferred. 908 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit. 909 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK 910 used by non-blocking mode. 911 912 @retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs. 913 @retval EFI_TIMEOUT The operation is time out. 914 @retval EFI_UNSUPPORTED The device is not ready for transfer. 915 @retval EFI_SUCCESS The DMA data transfer executes successfully. 916 917 **/ 918 EFI_STATUS 919 EFIAPI 920 AhciDmaTransfer ( 921 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance, 922 IN EFI_AHCI_REGISTERS *AhciRegisters, 923 IN UINT8 Port, 924 IN UINT8 PortMultiplier, 925 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, 926 IN UINT8 AtapiCommandLength, 927 IN BOOLEAN Read, 928 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, 929 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, 930 IN OUT VOID *MemoryAddr, 931 IN UINT32 DataCount, 932 IN UINT64 Timeout, 933 IN ATA_NONBLOCK_TASK *Task 934 ) 935 { 936 EFI_STATUS Status; 937 UINTN Offset; 938 EFI_PHYSICAL_ADDRESS PhyAddr; 939 VOID *Map; 940 UINTN MapLength; 941 EFI_PCI_IO_PROTOCOL_OPERATION Flag; 942 EFI_AHCI_COMMAND_FIS CFis; 943 EFI_AHCI_COMMAND_LIST CmdList; 944 UINTN FisBaseAddr; 945 UINT32 PortTfd; 946 947 EFI_PCI_IO_PROTOCOL *PciIo; 948 EFI_TPL OldTpl; 949 950 Map = NULL; 951 PciIo = Instance->PciIo; 952 953 if (PciIo == NULL) { 954 return EFI_INVALID_PARAMETER; 955 } 956 957 // 958 // Before starting the Blocking BlockIO operation, push to finish all non-blocking 959 // BlockIO tasks. 960 // Delay 100us to simulate the blocking time out checking. 961 // 962 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 963 while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) { 964 AsyncNonBlockingTransferRoutine (NULL, Instance); 965 // 966 // Stall for 100us. 967 // 968 MicroSecondDelay (100); 969 } 970 gBS->RestoreTPL (OldTpl); 971 972 if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) { 973 // 974 // Mark the Task to indicate that it has been started. 975 // 976 if (Task != NULL) { 977 Task->IsStart = TRUE; 978 } 979 if (Read) { 980 Flag = EfiPciIoOperationBusMasterWrite; 981 } else { 982 Flag = EfiPciIoOperationBusMasterRead; 983 } 984 985 // 986 // Construct command list and command table with pci bus address. 987 // 988 MapLength = DataCount; 989 Status = PciIo->Map ( 990 PciIo, 991 Flag, 992 MemoryAddr, 993 &MapLength, 994 &PhyAddr, 995 &Map 996 ); 997 998 if (EFI_ERROR (Status) || (DataCount != MapLength)) { 999 return EFI_BAD_BUFFER_SIZE; 1000 } 1001 1002 if (Task != NULL) { 1003 Task->Map = Map; 1004 } 1005 // 1006 // Package read needed 1007 // 1008 AhciBuildCommandFis (&CFis, AtaCommandBlock); 1009 1010 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST)); 1011 1012 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; 1013 CmdList.AhciCmdW = Read ? 0 : 1; 1014 1015 AhciBuildCommand ( 1016 PciIo, 1017 AhciRegisters, 1018 Port, 1019 PortMultiplier, 1020 &CFis, 1021 &CmdList, 1022 AtapiCommand, 1023 AtapiCommandLength, 1024 0, 1025 (VOID *)(UINTN)PhyAddr, 1026 DataCount 1027 ); 1028 1029 Status = AhciStartCommand ( 1030 PciIo, 1031 Port, 1032 0, 1033 Timeout 1034 ); 1035 if (EFI_ERROR (Status)) { 1036 goto Exit; 1037 } 1038 } 1039 1040 // 1041 // Wait for command compelte 1042 // 1043 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); 1044 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; 1045 if (Task != NULL) { 1046 // 1047 // For Non-blocking 1048 // 1049 Status = AhciCheckMemSet ( 1050 Offset, 1051 EFI_AHCI_FIS_TYPE_MASK, 1052 EFI_AHCI_FIS_REGISTER_D2H, 1053 Task 1054 ); 1055 } else { 1056 Status = AhciWaitMemSet ( 1057 Offset, 1058 EFI_AHCI_FIS_TYPE_MASK, 1059 EFI_AHCI_FIS_REGISTER_D2H, 1060 Timeout 1061 ); 1062 } 1063 1064 if (EFI_ERROR (Status)) { 1065 goto Exit; 1066 } 1067 1068 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 1069 PortTfd = AhciReadReg (PciIo, (UINT32) Offset); 1070 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) { 1071 Status = EFI_DEVICE_ERROR; 1072 } 1073 1074 Exit: 1075 // 1076 // For Blocking mode, the command should be stopped, the Fis should be disabled 1077 // and the PciIo should be unmapped. 1078 // For non-blocking mode, only when a error is happened (if the return status is 1079 // EFI_NOT_READY that means the command doesn't finished, try again.), first do the 1080 // context cleanup, then set the packet's Asb status. 1081 // 1082 if (Task == NULL || 1083 ((Task != NULL) && (Status != EFI_NOT_READY)) 1084 ) { 1085 AhciStopCommand ( 1086 PciIo, 1087 Port, 1088 Timeout 1089 ); 1090 1091 AhciDisableFisReceive ( 1092 PciIo, 1093 Port, 1094 Timeout 1095 ); 1096 1097 PciIo->Unmap ( 1098 PciIo, 1099 (Task != NULL) ? Task->Map : Map 1100 ); 1101 1102 if (Task != NULL) { 1103 Task->Packet->Asb->AtaStatus = 0x01; 1104 } 1105 } 1106 1107 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); 1108 return Status; 1109 } 1110 1111 /** 1112 Start a non data transfer on specific port. 1113 1114 @param[in] PciIo The PCI IO protocol instance. 1115 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1116 @param[in] Port The number of port. 1117 @param[in] PortMultiplier The timeout value of stop. 1118 @param[in] AtapiCommand The atapi command will be used for the 1119 transfer. 1120 @param[in] AtapiCommandLength The length of the atapi command. 1121 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data. 1122 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data. 1123 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit. 1124 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK 1125 used by non-blocking mode. 1126 1127 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs. 1128 @retval EFI_TIMEOUT The operation is time out. 1129 @retval EFI_UNSUPPORTED The device is not ready for transfer. 1130 @retval EFI_SUCCESS The non data transfer executes successfully. 1131 1132 **/ 1133 EFI_STATUS 1134 EFIAPI 1135 AhciNonDataTransfer ( 1136 IN EFI_PCI_IO_PROTOCOL *PciIo, 1137 IN EFI_AHCI_REGISTERS *AhciRegisters, 1138 IN UINT8 Port, 1139 IN UINT8 PortMultiplier, 1140 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL, 1141 IN UINT8 AtapiCommandLength, 1142 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, 1143 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, 1144 IN UINT64 Timeout, 1145 IN ATA_NONBLOCK_TASK *Task 1146 ) 1147 { 1148 EFI_STATUS Status; 1149 UINTN FisBaseAddr; 1150 UINTN Offset; 1151 UINT32 PortTfd; 1152 EFI_AHCI_COMMAND_FIS CFis; 1153 EFI_AHCI_COMMAND_LIST CmdList; 1154 1155 // 1156 // Package read needed 1157 // 1158 AhciBuildCommandFis (&CFis, AtaCommandBlock); 1159 1160 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST)); 1161 1162 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4; 1163 1164 AhciBuildCommand ( 1165 PciIo, 1166 AhciRegisters, 1167 Port, 1168 PortMultiplier, 1169 &CFis, 1170 &CmdList, 1171 AtapiCommand, 1172 AtapiCommandLength, 1173 0, 1174 NULL, 1175 0 1176 ); 1177 1178 Status = AhciStartCommand ( 1179 PciIo, 1180 Port, 1181 0, 1182 Timeout 1183 ); 1184 if (EFI_ERROR (Status)) { 1185 goto Exit; 1186 } 1187 1188 // 1189 // Wait device sends the Response Fis 1190 // 1191 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); 1192 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET; 1193 Status = AhciWaitMemSet ( 1194 Offset, 1195 EFI_AHCI_FIS_TYPE_MASK, 1196 EFI_AHCI_FIS_REGISTER_D2H, 1197 Timeout 1198 ); 1199 1200 if (EFI_ERROR (Status)) { 1201 goto Exit; 1202 } 1203 1204 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 1205 PortTfd = AhciReadReg (PciIo, (UINT32) Offset); 1206 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) { 1207 Status = EFI_DEVICE_ERROR; 1208 } 1209 1210 Exit: 1211 AhciStopCommand ( 1212 PciIo, 1213 Port, 1214 Timeout 1215 ); 1216 1217 AhciDisableFisReceive ( 1218 PciIo, 1219 Port, 1220 Timeout 1221 ); 1222 1223 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock); 1224 1225 return Status; 1226 } 1227 1228 /** 1229 Stop command running for giving port 1230 1231 @param PciIo The PCI IO protocol instance. 1232 @param Port The number of port. 1233 @param Timeout The timeout value of stop, uses 100ns as a unit. 1234 1235 @retval EFI_DEVICE_ERROR The command stop unsuccessfully. 1236 @retval EFI_TIMEOUT The operation is time out. 1237 @retval EFI_SUCCESS The command stop successfully. 1238 1239 **/ 1240 EFI_STATUS 1241 EFIAPI 1242 AhciStopCommand ( 1243 IN EFI_PCI_IO_PROTOCOL *PciIo, 1244 IN UINT8 Port, 1245 IN UINT64 Timeout 1246 ) 1247 { 1248 UINT32 Offset; 1249 UINT32 Data; 1250 1251 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 1252 Data = AhciReadReg (PciIo, Offset); 1253 1254 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) { 1255 return EFI_SUCCESS; 1256 } 1257 1258 if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) { 1259 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST)); 1260 } 1261 1262 return AhciWaitMmioSet ( 1263 PciIo, 1264 Offset, 1265 EFI_AHCI_PORT_CMD_CR, 1266 0, 1267 Timeout 1268 ); 1269 } 1270 1271 /** 1272 Start command for give slot on specific port. 1273 1274 @param PciIo The PCI IO protocol instance. 1275 @param Port The number of port. 1276 @param CommandSlot The number of Command Slot. 1277 @param Timeout The timeout value of start, uses 100ns as a unit. 1278 1279 @retval EFI_DEVICE_ERROR The command start unsuccessfully. 1280 @retval EFI_TIMEOUT The operation is time out. 1281 @retval EFI_SUCCESS The command start successfully. 1282 1283 **/ 1284 EFI_STATUS 1285 EFIAPI 1286 AhciStartCommand ( 1287 IN EFI_PCI_IO_PROTOCOL *PciIo, 1288 IN UINT8 Port, 1289 IN UINT8 CommandSlot, 1290 IN UINT64 Timeout 1291 ) 1292 { 1293 UINT32 CmdSlotBit; 1294 EFI_STATUS Status; 1295 UINT32 PortStatus; 1296 UINT32 StartCmd; 1297 UINT32 PortTfd; 1298 UINT32 Offset; 1299 UINT32 Capability; 1300 1301 // 1302 // Collect AHCI controller information 1303 // 1304 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET); 1305 1306 CmdSlotBit = (UINT32) (1 << CommandSlot); 1307 1308 AhciClearPortStatus ( 1309 PciIo, 1310 Port 1311 ); 1312 1313 Status = AhciEnableFisReceive ( 1314 PciIo, 1315 Port, 1316 Timeout 1317 ); 1318 1319 if (EFI_ERROR (Status)) { 1320 return Status; 1321 } 1322 1323 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 1324 PortStatus = AhciReadReg (PciIo, Offset); 1325 1326 StartCmd = 0; 1327 if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) { 1328 StartCmd = AhciReadReg (PciIo, Offset); 1329 StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK; 1330 StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE; 1331 } 1332 1333 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 1334 PortTfd = AhciReadReg (PciIo, Offset); 1335 1336 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) { 1337 if ((Capability & BIT24) != 0) { 1338 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 1339 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_CLO); 1340 1341 AhciWaitMmioSet ( 1342 PciIo, 1343 Offset, 1344 EFI_AHCI_PORT_CMD_CLO, 1345 0, 1346 Timeout 1347 ); 1348 } 1349 } 1350 1351 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 1352 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd); 1353 1354 // 1355 // Setting the command 1356 // 1357 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI; 1358 AhciAndReg (PciIo, Offset, 0); 1359 AhciOrReg (PciIo, Offset, CmdSlotBit); 1360 1361 return EFI_SUCCESS; 1362 } 1363 1364 /** 1365 Do AHCI port reset. 1366 1367 @param PciIo The PCI IO protocol instance. 1368 @param Port The number of port. 1369 @param Timeout The timeout value of reset, uses 100ns as a unit. 1370 1371 @retval EFI_DEVICE_ERROR The port reset unsuccessfully 1372 @retval EFI_TIMEOUT The reset operation is time out. 1373 @retval EFI_SUCCESS The port reset successfully. 1374 1375 **/ 1376 EFI_STATUS 1377 EFIAPI 1378 AhciPortReset ( 1379 IN EFI_PCI_IO_PROTOCOL *PciIo, 1380 IN UINT8 Port, 1381 IN UINT64 Timeout 1382 ) 1383 { 1384 EFI_STATUS Status; 1385 UINT32 Offset; 1386 1387 AhciClearPortStatus (PciIo, Port); 1388 1389 AhciStopCommand (PciIo, Port, Timeout); 1390 1391 AhciDisableFisReceive (PciIo, Port, Timeout); 1392 1393 AhciEnableFisReceive (PciIo, Port, Timeout); 1394 1395 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL; 1396 1397 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT); 1398 1399 // 1400 // wait 5 millisecond before de-assert DET 1401 // 1402 MicroSecondDelay (5000); 1403 1404 AhciAndReg (PciIo, Offset, (UINT32)EFI_AHCI_PORT_SCTL_MASK); 1405 1406 // 1407 // wait 5 millisecond before de-assert DET 1408 // 1409 MicroSecondDelay (5000); 1410 1411 // 1412 // Wait for communication to be re-established 1413 // 1414 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS; 1415 Status = AhciWaitMmioSet ( 1416 PciIo, 1417 Offset, 1418 EFI_AHCI_PORT_SSTS_DET_MASK, 1419 EFI_AHCI_PORT_SSTS_DET_PCE, 1420 Timeout 1421 ); 1422 1423 if (EFI_ERROR (Status)) { 1424 DEBUG ((EFI_D_ERROR, "Port %d COMRESET failed: %r\n", Port, Status)); 1425 return Status; 1426 } 1427 1428 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR; 1429 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_ERR_CLEAR); 1430 1431 return EFI_SUCCESS; 1432 } 1433 1434 /** 1435 Do AHCI HBA reset. 1436 1437 @param PciIo The PCI IO protocol instance. 1438 @param Timeout The timeout value of reset, uses 100ns as a unit. 1439 1440 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset. 1441 @retval EFI_TIMEOUT The reset operation is time out. 1442 @retval EFI_SUCCESS AHCI controller is reset successfully. 1443 1444 **/ 1445 EFI_STATUS 1446 EFIAPI 1447 AhciReset ( 1448 IN EFI_PCI_IO_PROTOCOL *PciIo, 1449 IN UINT64 Timeout 1450 ) 1451 { 1452 UINT64 Delay; 1453 UINT32 Value; 1454 1455 // 1456 // Make sure that GHC.AE bit is set before accessing any AHCI registers. 1457 // 1458 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET); 1459 1460 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) { 1461 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE); 1462 } 1463 1464 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET); 1465 1466 Delay = DivU64x32(Timeout, 1000) + 1; 1467 1468 do { 1469 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET); 1470 1471 if ((Value & EFI_AHCI_GHC_RESET) == 0) { 1472 break; 1473 } 1474 1475 // 1476 // Stall for 100 microseconds. 1477 // 1478 MicroSecondDelay(100); 1479 1480 Delay--; 1481 } while (Delay > 0); 1482 1483 if (Delay == 0) { 1484 return EFI_TIMEOUT; 1485 } 1486 1487 return EFI_SUCCESS; 1488 } 1489 1490 /** 1491 Send SMART Return Status command to check if the execution of SMART cmd is successful or not. 1492 1493 @param PciIo The PCI IO protocol instance. 1494 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1495 @param Port The number of port. 1496 @param PortMultiplier The port multiplier port number. 1497 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure. 1498 1499 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution. 1500 @retval Others Fail to get return status data. 1501 1502 **/ 1503 EFI_STATUS 1504 EFIAPI 1505 AhciAtaSmartReturnStatusCheck ( 1506 IN EFI_PCI_IO_PROTOCOL *PciIo, 1507 IN EFI_AHCI_REGISTERS *AhciRegisters, 1508 IN UINT8 Port, 1509 IN UINT8 PortMultiplier, 1510 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock 1511 ) 1512 { 1513 EFI_STATUS Status; 1514 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1515 UINT8 LBAMid; 1516 UINT8 LBAHigh; 1517 UINTN FisBaseAddr; 1518 UINT32 Value; 1519 1520 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1521 1522 AtaCommandBlock.AtaCommand = ATA_CMD_SMART; 1523 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS; 1524 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F; 1525 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2; 1526 1527 // 1528 // Send S.M.A.R.T Read Return Status command to device 1529 // 1530 Status = AhciNonDataTransfer ( 1531 PciIo, 1532 AhciRegisters, 1533 (UINT8)Port, 1534 (UINT8)PortMultiplier, 1535 NULL, 1536 0, 1537 &AtaCommandBlock, 1538 AtaStatusBlock, 1539 ATA_ATAPI_TIMEOUT, 1540 NULL 1541 ); 1542 1543 if (EFI_ERROR (Status)) { 1544 REPORT_STATUS_CODE ( 1545 EFI_ERROR_CODE | EFI_ERROR_MINOR, 1546 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED) 1547 ); 1548 return EFI_DEVICE_ERROR; 1549 } 1550 1551 REPORT_STATUS_CODE ( 1552 EFI_PROGRESS_CODE, 1553 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE) 1554 ); 1555 1556 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS); 1557 1558 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET); 1559 1560 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) { 1561 LBAMid = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[5]; 1562 LBAHigh = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[6]; 1563 1564 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) { 1565 // 1566 // The threshold exceeded condition is not detected by the device 1567 // 1568 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n")); 1569 REPORT_STATUS_CODE ( 1570 EFI_PROGRESS_CODE, 1571 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD) 1572 ); 1573 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) { 1574 // 1575 // The threshold exceeded condition is detected by the device 1576 // 1577 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n")); 1578 REPORT_STATUS_CODE ( 1579 EFI_PROGRESS_CODE, 1580 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD) 1581 ); 1582 } 1583 } 1584 1585 return EFI_SUCCESS; 1586 } 1587 1588 /** 1589 Enable SMART command of the disk if supported. 1590 1591 @param PciIo The PCI IO protocol instance. 1592 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1593 @param Port The number of port. 1594 @param PortMultiplier The port multiplier port number. 1595 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data. 1596 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure. 1597 1598 **/ 1599 VOID 1600 EFIAPI 1601 AhciAtaSmartSupport ( 1602 IN EFI_PCI_IO_PROTOCOL *PciIo, 1603 IN EFI_AHCI_REGISTERS *AhciRegisters, 1604 IN UINT8 Port, 1605 IN UINT8 PortMultiplier, 1606 IN EFI_IDENTIFY_DATA *IdentifyData, 1607 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock 1608 ) 1609 { 1610 EFI_STATUS Status; 1611 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1612 1613 // 1614 // Detect if the device supports S.M.A.R.T. 1615 // 1616 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) { 1617 // 1618 // S.M.A.R.T is not supported by the device 1619 // 1620 DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n", 1621 Port, PortMultiplier)); 1622 REPORT_STATUS_CODE ( 1623 EFI_ERROR_CODE | EFI_ERROR_MINOR, 1624 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED) 1625 ); 1626 } else { 1627 // 1628 // Check if the feature is enabled. If not, then enable S.M.A.R.T. 1629 // 1630 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) { 1631 1632 REPORT_STATUS_CODE ( 1633 EFI_PROGRESS_CODE, 1634 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE) 1635 ); 1636 1637 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1638 1639 AtaCommandBlock.AtaCommand = ATA_CMD_SMART; 1640 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION; 1641 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F; 1642 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2; 1643 1644 // 1645 // Send S.M.A.R.T Enable command to device 1646 // 1647 Status = AhciNonDataTransfer ( 1648 PciIo, 1649 AhciRegisters, 1650 (UINT8)Port, 1651 (UINT8)PortMultiplier, 1652 NULL, 1653 0, 1654 &AtaCommandBlock, 1655 AtaStatusBlock, 1656 ATA_ATAPI_TIMEOUT, 1657 NULL 1658 ); 1659 1660 1661 if (!EFI_ERROR (Status)) { 1662 // 1663 // Send S.M.A.R.T AutoSave command to device 1664 // 1665 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1666 1667 AtaCommandBlock.AtaCommand = ATA_CMD_SMART; 1668 AtaCommandBlock.AtaFeatures = 0xD2; 1669 AtaCommandBlock.AtaSectorCount = 0xF1; 1670 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F; 1671 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2; 1672 1673 Status = AhciNonDataTransfer ( 1674 PciIo, 1675 AhciRegisters, 1676 (UINT8)Port, 1677 (UINT8)PortMultiplier, 1678 NULL, 1679 0, 1680 &AtaCommandBlock, 1681 AtaStatusBlock, 1682 ATA_ATAPI_TIMEOUT, 1683 NULL 1684 ); 1685 1686 if (!EFI_ERROR (Status)) { 1687 Status = AhciAtaSmartReturnStatusCheck ( 1688 PciIo, 1689 AhciRegisters, 1690 (UINT8)Port, 1691 (UINT8)PortMultiplier, 1692 AtaStatusBlock 1693 ); 1694 } 1695 } 1696 } 1697 DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n", 1698 Port, PortMultiplier)); 1699 } 1700 1701 return ; 1702 } 1703 1704 /** 1705 Send Buffer cmd to specific device. 1706 1707 @param PciIo The PCI IO protocol instance. 1708 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1709 @param Port The number of port. 1710 @param PortMultiplier The port multiplier port number. 1711 @param Buffer The data buffer to store IDENTIFY PACKET data. 1712 1713 @retval EFI_DEVICE_ERROR The cmd abort with error occurs. 1714 @retval EFI_TIMEOUT The operation is time out. 1715 @retval EFI_UNSUPPORTED The device is not ready for executing. 1716 @retval EFI_SUCCESS The cmd executes successfully. 1717 1718 **/ 1719 EFI_STATUS 1720 EFIAPI 1721 AhciIdentify ( 1722 IN EFI_PCI_IO_PROTOCOL *PciIo, 1723 IN EFI_AHCI_REGISTERS *AhciRegisters, 1724 IN UINT8 Port, 1725 IN UINT8 PortMultiplier, 1726 IN OUT EFI_IDENTIFY_DATA *Buffer 1727 ) 1728 { 1729 EFI_STATUS Status; 1730 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1731 EFI_ATA_STATUS_BLOCK AtaStatusBlock; 1732 1733 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) { 1734 return EFI_INVALID_PARAMETER; 1735 } 1736 1737 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1738 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); 1739 1740 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE; 1741 AtaCommandBlock.AtaSectorCount = 1; 1742 1743 Status = AhciPioTransfer ( 1744 PciIo, 1745 AhciRegisters, 1746 Port, 1747 PortMultiplier, 1748 NULL, 1749 0, 1750 TRUE, 1751 &AtaCommandBlock, 1752 &AtaStatusBlock, 1753 Buffer, 1754 sizeof (EFI_IDENTIFY_DATA), 1755 ATA_ATAPI_TIMEOUT, 1756 NULL 1757 ); 1758 1759 return Status; 1760 } 1761 1762 /** 1763 Send Buffer cmd to specific device. 1764 1765 @param PciIo The PCI IO protocol instance. 1766 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1767 @param Port The number of port. 1768 @param PortMultiplier The port multiplier port number. 1769 @param Buffer The data buffer to store IDENTIFY PACKET data. 1770 1771 @retval EFI_DEVICE_ERROR The cmd abort with error occurs. 1772 @retval EFI_TIMEOUT The operation is time out. 1773 @retval EFI_UNSUPPORTED The device is not ready for executing. 1774 @retval EFI_SUCCESS The cmd executes successfully. 1775 1776 **/ 1777 EFI_STATUS 1778 EFIAPI 1779 AhciIdentifyPacket ( 1780 IN EFI_PCI_IO_PROTOCOL *PciIo, 1781 IN EFI_AHCI_REGISTERS *AhciRegisters, 1782 IN UINT8 Port, 1783 IN UINT8 PortMultiplier, 1784 IN OUT EFI_IDENTIFY_DATA *Buffer 1785 ) 1786 { 1787 EFI_STATUS Status; 1788 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1789 EFI_ATA_STATUS_BLOCK AtaStatusBlock; 1790 1791 if (PciIo == NULL || AhciRegisters == NULL) { 1792 return EFI_INVALID_PARAMETER; 1793 } 1794 1795 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1796 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); 1797 1798 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE; 1799 AtaCommandBlock.AtaSectorCount = 1; 1800 1801 Status = AhciPioTransfer ( 1802 PciIo, 1803 AhciRegisters, 1804 Port, 1805 PortMultiplier, 1806 NULL, 1807 0, 1808 TRUE, 1809 &AtaCommandBlock, 1810 &AtaStatusBlock, 1811 Buffer, 1812 sizeof (EFI_IDENTIFY_DATA), 1813 ATA_ATAPI_TIMEOUT, 1814 NULL 1815 ); 1816 1817 return Status; 1818 } 1819 1820 /** 1821 Send SET FEATURE cmd on specific device. 1822 1823 @param PciIo The PCI IO protocol instance. 1824 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1825 @param Port The number of port. 1826 @param PortMultiplier The port multiplier port number. 1827 @param Feature The data to send Feature register. 1828 @param FeatureSpecificData The specific data for SET FEATURE cmd. 1829 1830 @retval EFI_DEVICE_ERROR The cmd abort with error occurs. 1831 @retval EFI_TIMEOUT The operation is time out. 1832 @retval EFI_UNSUPPORTED The device is not ready for executing. 1833 @retval EFI_SUCCESS The cmd executes successfully. 1834 1835 **/ 1836 EFI_STATUS 1837 EFIAPI 1838 AhciDeviceSetFeature ( 1839 IN EFI_PCI_IO_PROTOCOL *PciIo, 1840 IN EFI_AHCI_REGISTERS *AhciRegisters, 1841 IN UINT8 Port, 1842 IN UINT8 PortMultiplier, 1843 IN UINT16 Feature, 1844 IN UINT32 FeatureSpecificData 1845 ) 1846 { 1847 EFI_STATUS Status; 1848 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1849 EFI_ATA_STATUS_BLOCK AtaStatusBlock; 1850 1851 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1852 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); 1853 1854 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES; 1855 AtaCommandBlock.AtaFeatures = (UINT8) Feature; 1856 AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8); 1857 AtaCommandBlock.AtaSectorCount = (UINT8) FeatureSpecificData; 1858 AtaCommandBlock.AtaSectorNumber = (UINT8) (FeatureSpecificData >> 8); 1859 AtaCommandBlock.AtaCylinderLow = (UINT8) (FeatureSpecificData >> 16); 1860 AtaCommandBlock.AtaCylinderHigh = (UINT8) (FeatureSpecificData >> 24); 1861 1862 Status = AhciNonDataTransfer ( 1863 PciIo, 1864 AhciRegisters, 1865 (UINT8)Port, 1866 (UINT8)PortMultiplier, 1867 NULL, 1868 0, 1869 &AtaCommandBlock, 1870 &AtaStatusBlock, 1871 ATA_ATAPI_TIMEOUT, 1872 NULL 1873 ); 1874 1875 return Status; 1876 } 1877 1878 /** 1879 This function is used to send out ATAPI commands conforms to the Packet Command 1880 with PIO Protocol. 1881 1882 @param PciIo The PCI IO protocol instance. 1883 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1884 @param Port The number of port. 1885 @param PortMultiplier The number of port multiplier. 1886 @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure. 1887 1888 @retval EFI_SUCCESS send out the ATAPI packet command successfully 1889 and device sends data successfully. 1890 @retval EFI_DEVICE_ERROR the device failed to send data. 1891 1892 **/ 1893 EFI_STATUS 1894 EFIAPI 1895 AhciPacketCommandExecute ( 1896 IN EFI_PCI_IO_PROTOCOL *PciIo, 1897 IN EFI_AHCI_REGISTERS *AhciRegisters, 1898 IN UINT8 Port, 1899 IN UINT8 PortMultiplier, 1900 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet 1901 ) 1902 { 1903 EFI_STATUS Status; 1904 VOID *Buffer; 1905 UINT32 Length; 1906 EFI_ATA_COMMAND_BLOCK AtaCommandBlock; 1907 EFI_ATA_STATUS_BLOCK AtaStatusBlock; 1908 BOOLEAN Read; 1909 1910 if (Packet == NULL || Packet->Cdb == NULL) { 1911 return EFI_INVALID_PARAMETER; 1912 } 1913 1914 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK)); 1915 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK)); 1916 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET; 1917 // 1918 // No OVL; No DMA 1919 // 1920 AtaCommandBlock.AtaFeatures = 0x00; 1921 // 1922 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device 1923 // determine how many data should be transferred. 1924 // 1925 AtaCommandBlock.AtaCylinderLow = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff); 1926 AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8); 1927 1928 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) { 1929 Buffer = Packet->InDataBuffer; 1930 Length = Packet->InTransferLength; 1931 Read = TRUE; 1932 } else { 1933 Buffer = Packet->OutDataBuffer; 1934 Length = Packet->OutTransferLength; 1935 Read = FALSE; 1936 } 1937 1938 if (Length == 0) { 1939 Status = AhciNonDataTransfer ( 1940 PciIo, 1941 AhciRegisters, 1942 Port, 1943 PortMultiplier, 1944 Packet->Cdb, 1945 Packet->CdbLength, 1946 &AtaCommandBlock, 1947 &AtaStatusBlock, 1948 Packet->Timeout, 1949 NULL 1950 ); 1951 } else { 1952 Status = AhciPioTransfer ( 1953 PciIo, 1954 AhciRegisters, 1955 Port, 1956 PortMultiplier, 1957 Packet->Cdb, 1958 Packet->CdbLength, 1959 Read, 1960 &AtaCommandBlock, 1961 &AtaStatusBlock, 1962 Buffer, 1963 Length, 1964 Packet->Timeout, 1965 NULL 1966 ); 1967 } 1968 return Status; 1969 } 1970 1971 /** 1972 Allocate transfer-related data struct which is used at AHCI mode. 1973 1974 @param PciIo The PCI IO protocol instance. 1975 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS. 1976 1977 **/ 1978 EFI_STATUS 1979 EFIAPI 1980 AhciCreateTransferDescriptor ( 1981 IN EFI_PCI_IO_PROTOCOL *PciIo, 1982 IN OUT EFI_AHCI_REGISTERS *AhciRegisters 1983 ) 1984 { 1985 EFI_STATUS Status; 1986 UINTN Bytes; 1987 VOID *Buffer; 1988 1989 UINT32 Capability; 1990 UINT32 PortImplementBitMap; 1991 UINT8 MaxPortNumber; 1992 UINT8 MaxCommandSlotNumber; 1993 BOOLEAN Support64Bit; 1994 UINT64 MaxReceiveFisSize; 1995 UINT64 MaxCommandListSize; 1996 UINT64 MaxCommandTableSize; 1997 EFI_PHYSICAL_ADDRESS AhciRFisPciAddr; 1998 EFI_PHYSICAL_ADDRESS AhciCmdListPciAddr; 1999 EFI_PHYSICAL_ADDRESS AhciCommandTablePciAddr; 2000 2001 Buffer = NULL; 2002 // 2003 // Collect AHCI controller information 2004 // 2005 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET); 2006 // 2007 // Get the number of command slots per port supported by this HBA. 2008 // 2009 MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1); 2010 Support64Bit = (BOOLEAN) (((Capability & BIT31) != 0) ? TRUE : FALSE); 2011 2012 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET); 2013 // 2014 // Get the highest bit of implemented ports which decides how many bytes are allocated for recived FIS. 2015 // 2016 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32(PortImplementBitMap) + 1); 2017 if (MaxPortNumber == 0) { 2018 return EFI_DEVICE_ERROR; 2019 } 2020 2021 MaxReceiveFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS); 2022 Status = PciIo->AllocateBuffer ( 2023 PciIo, 2024 AllocateAnyPages, 2025 EfiBootServicesData, 2026 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize), 2027 &Buffer, 2028 0 2029 ); 2030 2031 if (EFI_ERROR (Status)) { 2032 return EFI_OUT_OF_RESOURCES; 2033 } 2034 2035 ZeroMem (Buffer, (UINTN)MaxReceiveFisSize); 2036 2037 AhciRegisters->AhciRFis = Buffer; 2038 AhciRegisters->MaxReceiveFisSize = MaxReceiveFisSize; 2039 Bytes = (UINTN)MaxReceiveFisSize; 2040 2041 Status = PciIo->Map ( 2042 PciIo, 2043 EfiPciIoOperationBusMasterCommonBuffer, 2044 Buffer, 2045 &Bytes, 2046 &AhciRFisPciAddr, 2047 &AhciRegisters->MapRFis 2048 ); 2049 2050 if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) { 2051 // 2052 // Map error or unable to map the whole RFis buffer into a contiguous region. 2053 // 2054 Status = EFI_OUT_OF_RESOURCES; 2055 goto Error6; 2056 } 2057 2058 if ((!Support64Bit) && (AhciRFisPciAddr > 0x100000000ULL)) { 2059 // 2060 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address. 2061 // 2062 Status = EFI_DEVICE_ERROR; 2063 goto Error5; 2064 } 2065 AhciRegisters->AhciRFisPciAddr = (EFI_AHCI_RECEIVED_FIS *)(UINTN)AhciRFisPciAddr; 2066 2067 // 2068 // Allocate memory for command list 2069 // Note that the implemenation is a single task model which only use a command list for all ports. 2070 // 2071 Buffer = NULL; 2072 MaxCommandListSize = MaxCommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST); 2073 Status = PciIo->AllocateBuffer ( 2074 PciIo, 2075 AllocateAnyPages, 2076 EfiBootServicesData, 2077 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize), 2078 &Buffer, 2079 0 2080 ); 2081 2082 if (EFI_ERROR (Status)) { 2083 // 2084 // Free mapped resource. 2085 // 2086 Status = EFI_OUT_OF_RESOURCES; 2087 goto Error5; 2088 } 2089 2090 ZeroMem (Buffer, (UINTN)MaxCommandListSize); 2091 2092 AhciRegisters->AhciCmdList = Buffer; 2093 AhciRegisters->MaxCommandListSize = MaxCommandListSize; 2094 Bytes = (UINTN)MaxCommandListSize; 2095 2096 Status = PciIo->Map ( 2097 PciIo, 2098 EfiPciIoOperationBusMasterCommonBuffer, 2099 Buffer, 2100 &Bytes, 2101 &AhciCmdListPciAddr, 2102 &AhciRegisters->MapCmdList 2103 ); 2104 2105 if (EFI_ERROR (Status) || (Bytes != MaxCommandListSize)) { 2106 // 2107 // Map error or unable to map the whole cmd list buffer into a contiguous region. 2108 // 2109 Status = EFI_OUT_OF_RESOURCES; 2110 goto Error4; 2111 } 2112 2113 if ((!Support64Bit) && (AhciCmdListPciAddr > 0x100000000ULL)) { 2114 // 2115 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address. 2116 // 2117 Status = EFI_DEVICE_ERROR; 2118 goto Error3; 2119 } 2120 AhciRegisters->AhciCmdListPciAddr = (EFI_AHCI_COMMAND_LIST *)(UINTN)AhciCmdListPciAddr; 2121 2122 // 2123 // Allocate memory for command table 2124 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries. 2125 // 2126 Buffer = NULL; 2127 MaxCommandTableSize = sizeof (EFI_AHCI_COMMAND_TABLE); 2128 2129 Status = PciIo->AllocateBuffer ( 2130 PciIo, 2131 AllocateAnyPages, 2132 EfiBootServicesData, 2133 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize), 2134 &Buffer, 2135 0 2136 ); 2137 2138 if (EFI_ERROR (Status)) { 2139 // 2140 // Free mapped resource. 2141 // 2142 Status = EFI_OUT_OF_RESOURCES; 2143 goto Error3; 2144 } 2145 2146 ZeroMem (Buffer, (UINTN)MaxCommandTableSize); 2147 2148 AhciRegisters->AhciCommandTable = Buffer; 2149 AhciRegisters->MaxCommandTableSize = MaxCommandTableSize; 2150 Bytes = (UINTN)MaxCommandTableSize; 2151 2152 Status = PciIo->Map ( 2153 PciIo, 2154 EfiPciIoOperationBusMasterCommonBuffer, 2155 Buffer, 2156 &Bytes, 2157 &AhciCommandTablePciAddr, 2158 &AhciRegisters->MapCommandTable 2159 ); 2160 2161 if (EFI_ERROR (Status) || (Bytes != MaxCommandTableSize)) { 2162 // 2163 // Map error or unable to map the whole cmd list buffer into a contiguous region. 2164 // 2165 Status = EFI_OUT_OF_RESOURCES; 2166 goto Error2; 2167 } 2168 2169 if ((!Support64Bit) && (AhciCommandTablePciAddr > 0x100000000ULL)) { 2170 // 2171 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address. 2172 // 2173 Status = EFI_DEVICE_ERROR; 2174 goto Error1; 2175 } 2176 AhciRegisters->AhciCommandTablePciAddr = (EFI_AHCI_COMMAND_TABLE *)(UINTN)AhciCommandTablePciAddr; 2177 2178 return EFI_SUCCESS; 2179 // 2180 // Map error or unable to map the whole CmdList buffer into a contiguous region. 2181 // 2182 Error1: 2183 PciIo->Unmap ( 2184 PciIo, 2185 AhciRegisters->MapCommandTable 2186 ); 2187 Error2: 2188 PciIo->FreeBuffer ( 2189 PciIo, 2190 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize), 2191 AhciRegisters->AhciCommandTable 2192 ); 2193 Error3: 2194 PciIo->Unmap ( 2195 PciIo, 2196 AhciRegisters->MapCmdList 2197 ); 2198 Error4: 2199 PciIo->FreeBuffer ( 2200 PciIo, 2201 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize), 2202 AhciRegisters->AhciCmdList 2203 ); 2204 Error5: 2205 PciIo->Unmap ( 2206 PciIo, 2207 AhciRegisters->MapRFis 2208 ); 2209 Error6: 2210 PciIo->FreeBuffer ( 2211 PciIo, 2212 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize), 2213 AhciRegisters->AhciRFis 2214 ); 2215 2216 return Status; 2217 } 2218 2219 /** 2220 Initialize ATA host controller at AHCI mode. 2221 2222 The function is designed to initialize ATA host controller. 2223 2224 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance. 2225 2226 **/ 2227 EFI_STATUS 2228 EFIAPI 2229 AhciModeInitialization ( 2230 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance 2231 ) 2232 { 2233 EFI_STATUS Status; 2234 EFI_PCI_IO_PROTOCOL *PciIo; 2235 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit; 2236 UINT32 Capability; 2237 UINT8 MaxPortNumber; 2238 UINT32 PortImplementBitMap; 2239 2240 EFI_AHCI_REGISTERS *AhciRegisters; 2241 2242 UINT8 Port; 2243 DATA_64 Data64; 2244 UINT32 Offset; 2245 UINT32 Data; 2246 EFI_IDENTIFY_DATA Buffer; 2247 EFI_ATA_DEVICE_TYPE DeviceType; 2248 EFI_ATA_COLLECTIVE_MODE *SupportedModes; 2249 EFI_ATA_TRANSFER_MODE TransferMode; 2250 UINT32 PhyDetectDelay; 2251 UINT32 Value; 2252 2253 if (Instance == NULL) { 2254 return EFI_INVALID_PARAMETER; 2255 } 2256 2257 PciIo = Instance->PciIo; 2258 IdeInit = Instance->IdeControllerInit; 2259 2260 Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT); 2261 2262 if (EFI_ERROR (Status)) { 2263 return EFI_DEVICE_ERROR; 2264 } 2265 2266 // 2267 // Collect AHCI controller information 2268 // 2269 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET); 2270 2271 // 2272 // Make sure that GHC.AE bit is set before accessing any AHCI registers. 2273 // 2274 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET); 2275 2276 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) { 2277 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE); 2278 } 2279 2280 // 2281 // Enable 64-bit DMA support in the PCI layer if this controller 2282 // supports it. 2283 // 2284 if ((Capability & EFI_AHCI_CAP_S64A) != 0) { 2285 Status = PciIo->Attributes ( 2286 PciIo, 2287 EfiPciIoAttributeOperationEnable, 2288 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE, 2289 NULL 2290 ); 2291 if (EFI_ERROR (Status)) { 2292 DEBUG ((EFI_D_WARN, 2293 "AhciModeInitialization: failed to enable 64-bit DMA on 64-bit capable controller (%r)\n", 2294 Status)); 2295 } 2296 } 2297 2298 // 2299 // Get the number of command slots per port supported by this HBA. 2300 // 2301 MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1); 2302 2303 // 2304 // Get the bit map of those ports exposed by this HBA. 2305 // It indicates which ports that the HBA supports are available for software to use. 2306 // 2307 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET); 2308 2309 AhciRegisters = &Instance->AhciRegisters; 2310 Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters); 2311 2312 if (EFI_ERROR (Status)) { 2313 return EFI_OUT_OF_RESOURCES; 2314 } 2315 2316 for (Port = 0; Port < EFI_AHCI_MAX_PORTS; Port ++) { 2317 if ((PortImplementBitMap & (BIT0 << Port)) != 0) { 2318 // 2319 // According to AHCI spec, MaxPortNumber should be equal or greater than the number of implemented ports. 2320 // 2321 if ((MaxPortNumber--) == 0) { 2322 // 2323 // Should never be here. 2324 // 2325 ASSERT (FALSE); 2326 return EFI_SUCCESS; 2327 } 2328 2329 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port); 2330 2331 // 2332 // Initialize FIS Base Address Register and Command List Base Address Register for use. 2333 // 2334 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFisPciAddr) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port; 2335 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB; 2336 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32); 2337 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU; 2338 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32); 2339 2340 Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdListPciAddr); 2341 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB; 2342 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32); 2343 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU; 2344 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32); 2345 2346 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 2347 Data = AhciReadReg (PciIo, Offset); 2348 if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) { 2349 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_POD); 2350 } 2351 2352 if ((Capability & EFI_AHCI_CAP_SSS) != 0) { 2353 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_SUD); 2354 } 2355 2356 // 2357 // Disable aggressive power management. 2358 // 2359 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL; 2360 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_INIT); 2361 // 2362 // Disable the reporting of the corresponding interrupt to system software. 2363 // 2364 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE; 2365 AhciAndReg (PciIo, Offset, 0); 2366 2367 // 2368 // Now inform the IDE Controller Init Module. 2369 // 2370 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, Port); 2371 2372 // 2373 // Enable FIS Receive DMA engine for the first D2H FIS. 2374 // 2375 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 2376 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE); 2377 2378 // 2379 // Wait no longer than 10 ms to wait the Phy to detect the presence of a device. 2380 // It's the requirment from SATA1.0a spec section 5.2. 2381 // 2382 PhyDetectDelay = EFI_AHCI_BUS_PHY_DETECT_TIMEOUT; 2383 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS; 2384 do { 2385 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK; 2386 if ((Data == EFI_AHCI_PORT_SSTS_DET_PCE) || (Data == EFI_AHCI_PORT_SSTS_DET)) { 2387 break; 2388 } 2389 2390 MicroSecondDelay (1000); 2391 PhyDetectDelay--; 2392 } while (PhyDetectDelay > 0); 2393 2394 if (PhyDetectDelay == 0) { 2395 // 2396 // No device detected at this port. 2397 // Clear PxCMD.SUD for those ports at which there are no device present. 2398 // 2399 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD; 2400 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_SUD)); 2401 continue; 2402 } 2403 2404 // 2405 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ 2406 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec. 2407 // 2408 PhyDetectDelay = 16 * 1000; 2409 do { 2410 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR; 2411 if (AhciReadReg(PciIo, Offset) != 0) { 2412 AhciWriteReg (PciIo, Offset, AhciReadReg(PciIo, Offset)); 2413 } 2414 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD; 2415 2416 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_TFD_MASK; 2417 if (Data == 0) { 2418 break; 2419 } 2420 2421 MicroSecondDelay (1000); 2422 PhyDetectDelay--; 2423 } while (PhyDetectDelay > 0); 2424 2425 if (PhyDetectDelay == 0) { 2426 DEBUG ((EFI_D_ERROR, "Port %d Device presence detected but phy not ready (TFD=0x%X)\n", Port, Data)); 2427 continue; 2428 } 2429 2430 // 2431 // When the first D2H register FIS is received, the content of PxSIG register is updated. 2432 // 2433 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG; 2434 Status = AhciWaitMmioSet ( 2435 PciIo, 2436 Offset, 2437 0x0000FFFF, 2438 0x00000101, 2439 EFI_TIMER_PERIOD_SECONDS(16) 2440 ); 2441 if (EFI_ERROR (Status)) { 2442 continue; 2443 } 2444 2445 Data = AhciReadReg (PciIo, Offset); 2446 if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATAPI_DEVICE_SIG) { 2447 Status = AhciIdentifyPacket (PciIo, AhciRegisters, Port, 0, &Buffer); 2448 2449 if (EFI_ERROR (Status)) { 2450 continue; 2451 } 2452 2453 DeviceType = EfiIdeCdrom; 2454 } else if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATA_DEVICE_SIG) { 2455 Status = AhciIdentify (PciIo, AhciRegisters, Port, 0, &Buffer); 2456 2457 if (EFI_ERROR (Status)) { 2458 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED)); 2459 continue; 2460 } 2461 2462 DeviceType = EfiIdeHarddisk; 2463 } else { 2464 continue; 2465 } 2466 DEBUG ((EFI_D_INFO, "port [%d] port mulitplier [%d] has a [%a]\n", 2467 Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk")); 2468 2469 // 2470 // If the device is a hard disk, then try to enable S.M.A.R.T feature 2471 // 2472 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) { 2473 AhciAtaSmartSupport ( 2474 PciIo, 2475 AhciRegisters, 2476 Port, 2477 0, 2478 &Buffer, 2479 NULL 2480 ); 2481 } 2482 2483 // 2484 // Submit identify data to IDE controller init driver 2485 // 2486 IdeInit->SubmitData (IdeInit, Port, 0, &Buffer); 2487 2488 // 2489 // Now start to config ide device parameter and transfer mode. 2490 // 2491 Status = IdeInit->CalculateMode ( 2492 IdeInit, 2493 Port, 2494 0, 2495 &SupportedModes 2496 ); 2497 if (EFI_ERROR (Status)) { 2498 DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status)); 2499 continue; 2500 } 2501 2502 // 2503 // Set best supported PIO mode on this IDE device 2504 // 2505 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) { 2506 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO; 2507 } else { 2508 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO; 2509 } 2510 2511 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode); 2512 2513 // 2514 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't 2515 // be set together. Only one DMA mode can be set to a device. If setting 2516 // DMA mode operation fails, we can continue moving on because we only use 2517 // PIO mode at boot time. DMA modes are used by certain kind of OS booting 2518 // 2519 if (SupportedModes->UdmaMode.Valid) { 2520 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA; 2521 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode); 2522 } else if (SupportedModes->MultiWordDmaMode.Valid) { 2523 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA; 2524 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode; 2525 } 2526 2527 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode)); 2528 if (EFI_ERROR (Status)) { 2529 DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status)); 2530 continue; 2531 } 2532 2533 // 2534 // Found a ATA or ATAPI device, add it into the device list. 2535 // 2536 CreateNewDeviceInfo (Instance, Port, 0xFFFF, DeviceType, &Buffer); 2537 if (DeviceType == EfiIdeHarddisk) { 2538 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE)); 2539 } 2540 } 2541 } 2542 2543 return EFI_SUCCESS; 2544 } 2545 2546