2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "AtaAtapiPassThru.h"
18 read a one-byte data from a IDE port.
20 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
21 @param Port The IDE Port number
23 @return the one-byte data read from IDE port
28 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
34 ASSERT (PciIo
!= NULL
);
38 // perform 1-byte data read from register
43 EFI_PCI_IO_PASS_THROUGH_BAR
,
52 write a 1-byte data to a specific IDE port.
54 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
55 @param Port The IDE port to be writen
56 @param Data The data to write to the port
61 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
66 ASSERT (PciIo
!= NULL
);
69 // perform 1-byte data write to register
74 EFI_PCI_IO_PASS_THROUGH_BAR
,
82 write a 1-word data to a specific IDE port.
84 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
85 @param Port The IDE port to be writen
86 @param Data The data to write to the port
91 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
96 ASSERT (PciIo
!= NULL
);
99 // perform 1-word data write to register
104 EFI_PCI_IO_PASS_THROUGH_BAR
,
112 write a 2-word data to a specific IDE port.
114 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
115 @param Port The IDE port to be writen
116 @param Data The data to write to the port
121 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
126 ASSERT (PciIo
!= NULL
);
129 // perform 2-word data write to register
134 EFI_PCI_IO_PASS_THROUGH_BAR
,
142 Write multiple words of data to the IDE data port.
143 Call the IO abstraction once to do the complete read,
144 not one word at a time
146 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
147 @param Port IO port to read
148 @param Count No. of UINT16's to read
149 @param Buffer Pointer to the data buffer for read
154 IdeWritePortWMultiple (
155 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
161 ASSERT (PciIo
!= NULL
);
162 ASSERT (Buffer
!= NULL
);
165 // perform UINT16 data write to the FIFO
169 EfiPciIoWidthFifoUint16
,
170 EFI_PCI_IO_PASS_THROUGH_BAR
,
179 Reads multiple words of data from the IDE data port.
180 Call the IO abstraction once to do the complete read,
181 not one word at a time
183 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
184 @param Port IO port to read
185 @param Count Number of UINT16's to read
186 @param Buffer Pointer to the data buffer for read
191 IdeReadPortWMultiple (
192 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
198 ASSERT (PciIo
!= NULL
);
199 ASSERT (Buffer
!= NULL
);
202 // Perform UINT16 data read from FIFO
206 EfiPciIoWidthFifoUint16
,
207 EFI_PCI_IO_PASS_THROUGH_BAR
,
216 This function is used to analyze the Status Register and print out
217 some debug information and if there is ERR bit set in the Status
218 Register, the Error Register's value is also be parsed and print out.
220 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
221 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
222 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
227 DumpAllIdeRegisters (
228 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
229 IN EFI_IDE_REGISTERS
*IdeRegisters
,
230 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
233 EFI_ATA_STATUS_BLOCK StatusBlock
;
235 ASSERT (PciIo
!= NULL
);
236 ASSERT (IdeRegisters
!= NULL
);
238 ZeroMem (&StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
240 StatusBlock
.AtaStatus
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
241 StatusBlock
.AtaError
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
242 StatusBlock
.AtaSectorCount
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
243 StatusBlock
.AtaSectorCountExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
244 StatusBlock
.AtaSectorNumber
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
245 StatusBlock
.AtaSectorNumberExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
246 StatusBlock
.AtaCylinderLow
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
247 StatusBlock
.AtaCylinderLowExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
248 StatusBlock
.AtaCylinderHigh
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
249 StatusBlock
.AtaCylinderHighExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
250 StatusBlock
.AtaDeviceHead
= IdeReadPortB (PciIo
, IdeRegisters
->Head
);
252 if (AtaStatusBlock
!= NULL
) {
254 // Dump the content of all ATA registers.
256 CopyMem (AtaStatusBlock
, &StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
260 if ((StatusBlock
.AtaStatus
& ATA_STSREG_DWF
) != 0) {
261 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock
.AtaStatus
));
264 if ((StatusBlock
.AtaStatus
& ATA_STSREG_CORR
) != 0) {
265 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock
.AtaStatus
));
268 if ((StatusBlock
.AtaStatus
& ATA_STSREG_ERR
) != 0) {
269 if ((StatusBlock
.AtaError
& ATA_ERRREG_BBK
) != 0) {
270 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock
.AtaError
));
273 if ((StatusBlock
.AtaError
& ATA_ERRREG_UNC
) != 0) {
274 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock
.AtaError
));
277 if ((StatusBlock
.AtaError
& ATA_ERRREG_MC
) != 0) {
278 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock
.AtaError
));
281 if ((StatusBlock
.AtaError
& ATA_ERRREG_ABRT
) != 0) {
282 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock
.AtaError
));
285 if ((StatusBlock
.AtaError
& ATA_ERRREG_TK0NF
) != 0) {
286 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock
.AtaError
));
289 if ((StatusBlock
.AtaError
& ATA_ERRREG_AMNF
) != 0) {
290 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock
.AtaError
));
297 This function is used to analyze the Status Register at the condition that BSY is zero.
298 if there is ERR bit set in the Status Register, then return error.
300 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
301 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
303 @retval EFI_SUCCESS No err information in the Status Register.
304 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
309 CheckStatusRegister (
310 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
311 IN EFI_IDE_REGISTERS
*IdeRegisters
314 UINT8 StatusRegister
;
316 ASSERT (PciIo
!= NULL
);
317 ASSERT (IdeRegisters
!= NULL
);
319 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
321 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
322 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
325 return EFI_DEVICE_ERROR
;
332 This function is used to poll for the DRQ bit clear in the Status
333 Register. DRQ is cleared when the device is finished transferring data.
334 So this function is called after data transfer is finished.
336 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
337 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
338 @param Timeout The time to complete the command, uses 100ns as a unit.
340 @retval EFI_SUCCESS DRQ bit clear within the time out.
342 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
345 Read Status Register will clear interrupt status.
351 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
352 IN EFI_IDE_REGISTERS
*IdeRegisters
,
357 UINT8 StatusRegister
;
358 BOOLEAN InfiniteWait
;
360 ASSERT (PciIo
!= NULL
);
361 ASSERT (IdeRegisters
!= NULL
);
366 InfiniteWait
= FALSE
;
369 Delay
= DivU64x32(Timeout
, 1000) + 1;
371 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
374 // Wait for BSY == 0, then judge if DRQ is clear
376 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
377 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
378 return EFI_DEVICE_ERROR
;
385 // Stall for 100 microseconds.
387 MicroSecondDelay (100);
391 } while (InfiniteWait
|| (Delay
> 0));
396 This function is used to poll for the DRQ bit clear in the Alternate
397 Status Register. DRQ is cleared when the device is finished
398 transferring data. So this function is called after data transfer
401 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
402 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
403 @param Timeout The time to complete the command, uses 100ns as a unit.
405 @retval EFI_SUCCESS DRQ bit clear within the time out.
407 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
408 @note Read Alternate Status Register will not clear interrupt status.
414 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
415 IN EFI_IDE_REGISTERS
*IdeRegisters
,
421 BOOLEAN InfiniteWait
;
423 ASSERT (PciIo
!= NULL
);
424 ASSERT (IdeRegisters
!= NULL
);
429 InfiniteWait
= FALSE
;
432 Delay
= DivU64x32(Timeout
, 1000) + 1;
434 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
437 // Wait for BSY == 0, then judge if DRQ is clear
439 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
440 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
441 return EFI_DEVICE_ERROR
;
448 // Stall for 100 microseconds.
450 MicroSecondDelay (100);
454 } while (InfiniteWait
|| (Delay
> 0));
460 This function is used to poll for the DRQ bit set in the
462 DRQ is set when the device is ready to transfer data. So this function
463 is called after the command is sent to the device and before required
466 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
467 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
468 @param Timeout The time to complete the command, uses 100ns as a unit.
470 @retval EFI_SUCCESS DRQ bit set within the time out.
471 @retval EFI_TIMEOUT DRQ bit not set within the time out.
472 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
474 @note Read Status Register will clear interrupt status.
480 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
481 IN EFI_IDE_REGISTERS
*IdeRegisters
,
486 UINT8 StatusRegister
;
488 BOOLEAN InfiniteWait
;
490 ASSERT (PciIo
!= NULL
);
491 ASSERT (IdeRegisters
!= NULL
);
496 InfiniteWait
= FALSE
;
499 Delay
= DivU64x32(Timeout
, 1000) + 1;
502 // Read Status Register will clear interrupt
504 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
507 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
509 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
510 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
511 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
513 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
516 return EFI_DEVICE_ERROR
;
519 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
522 return EFI_NOT_READY
;
527 // Stall for 100 microseconds.
529 MicroSecondDelay (100);
532 } while (InfiniteWait
|| (Delay
> 0));
537 This function is used to poll for the DRQ bit set in the Alternate Status Register.
538 DRQ is set when the device is ready to transfer data. So this function is called after
539 the command is sent to the device and before required data is transferred.
541 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
542 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
543 @param Timeout The time to complete the command, uses 100ns as a unit.
545 @retval EFI_SUCCESS DRQ bit set within the time out.
546 @retval EFI_TIMEOUT DRQ bit not set within the time out.
547 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
548 @note Read Alternate Status Register will not clear interrupt status.
554 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
555 IN EFI_IDE_REGISTERS
*IdeRegisters
,
562 BOOLEAN InfiniteWait
;
564 ASSERT (PciIo
!= NULL
);
565 ASSERT (IdeRegisters
!= NULL
);
570 InfiniteWait
= FALSE
;
573 Delay
= DivU64x32(Timeout
, 1000) + 1;
577 // Read Alternate Status Register will not clear interrupt status
579 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
581 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
583 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
584 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
585 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
587 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
590 return EFI_DEVICE_ERROR
;
593 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
596 return EFI_NOT_READY
;
601 // Stall for 100 microseconds.
603 MicroSecondDelay (100);
606 } while (InfiniteWait
|| (Delay
> 0));
612 This function is used to poll for the DRDY bit set in the Status Register. DRDY
613 bit is set when the device is ready to accept command. Most ATA commands must be
614 sent after DRDY set except the ATAPI Packet Command.
616 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
617 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
618 @param Timeout The time to complete the command, uses 100ns as a unit.
620 @retval EFI_SUCCESS DRDY bit set within the time out.
621 @retval EFI_TIMEOUT DRDY bit not set within the time out.
623 @note Read Status Register will clear interrupt status.
628 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
629 IN EFI_IDE_REGISTERS
*IdeRegisters
,
634 UINT8 StatusRegister
;
636 BOOLEAN InfiniteWait
;
638 ASSERT (PciIo
!= NULL
);
639 ASSERT (IdeRegisters
!= NULL
);
644 InfiniteWait
= FALSE
;
647 Delay
= DivU64x32(Timeout
, 1000) + 1;
649 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
651 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
653 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
654 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
655 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
657 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
660 return EFI_DEVICE_ERROR
;
663 if ((StatusRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
666 return EFI_DEVICE_ERROR
;
671 // Stall for 100 microseconds.
673 MicroSecondDelay (100);
676 } while (InfiniteWait
|| (Delay
> 0));
682 This function is used to poll for the DRDY bit set in the Alternate Status Register.
683 DRDY bit is set when the device is ready to accept command. Most ATA commands must
684 be sent after DRDY set except the ATAPI Packet Command.
686 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
687 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
688 @param Timeout The time to complete the command, uses 100ns as a unit.
690 @retval EFI_SUCCESS DRDY bit set within the time out.
691 @retval EFI_TIMEOUT DRDY bit not set within the time out.
693 @note Read Alternate Status Register will clear interrupt status.
699 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
700 IN EFI_IDE_REGISTERS
*IdeRegisters
,
707 BOOLEAN InfiniteWait
;
709 ASSERT (PciIo
!= NULL
);
710 ASSERT (IdeRegisters
!= NULL
);
715 InfiniteWait
= FALSE
;
718 Delay
= DivU64x32(Timeout
, 1000) + 1;
720 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
722 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
724 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
725 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
726 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
728 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
731 return EFI_DEVICE_ERROR
;
734 if ((AltRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
737 return EFI_DEVICE_ERROR
;
742 // Stall for 100 microseconds.
744 MicroSecondDelay (100);
747 } while (InfiniteWait
|| (Delay
> 0));
753 This function is used to poll for the BSY bit clear in the Status Register. BSY
754 is clear when the device is not busy. Every command must be sent after device is not busy.
756 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
757 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
758 @param Timeout The time to complete the command, uses 100ns as a unit.
760 @retval EFI_SUCCESS BSY bit clear within the time out.
761 @retval EFI_TIMEOUT BSY bit not clear within the time out.
763 @note Read Status Register will clear interrupt status.
768 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
769 IN EFI_IDE_REGISTERS
*IdeRegisters
,
774 UINT8 StatusRegister
;
775 BOOLEAN InfiniteWait
;
777 ASSERT (PciIo
!= NULL
);
778 ASSERT (IdeRegisters
!= NULL
);
783 InfiniteWait
= FALSE
;
786 Delay
= DivU64x32(Timeout
, 1000) + 1;
788 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
790 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
795 // Stall for 100 microseconds.
797 MicroSecondDelay (100);
801 } while (InfiniteWait
|| (Delay
> 0));
807 This function is used to poll for the BSY bit clear in the Status Register. BSY
808 is clear when the device is not busy. Every command must be sent after device is not busy.
810 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
811 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
812 @param Timeout The time to complete the command, uses 100ns as a unit.
814 @retval EFI_SUCCESS BSY bit clear within the time out.
815 @retval EFI_TIMEOUT BSY bit not clear within the time out.
817 @note Read Status Register will clear interrupt status.
822 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
823 IN EFI_IDE_REGISTERS
*IdeRegisters
,
828 UINT8 AltStatusRegister
;
829 BOOLEAN InfiniteWait
;
831 ASSERT (PciIo
!= NULL
);
832 ASSERT (IdeRegisters
!= NULL
);
837 InfiniteWait
= FALSE
;
840 Delay
= DivU64x32(Timeout
, 1000) + 1;
842 AltStatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
844 if ((AltStatusRegister
& ATA_STSREG_BSY
) == 0x00) {
849 // Stall for 100 microseconds.
851 MicroSecondDelay (100);
855 } while (InfiniteWait
|| (Delay
> 0));
861 Get IDE i/o port registers' base addresses by mode.
863 In 'Compatibility' mode, use fixed addresses.
864 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
867 The steps to get IDE i/o port registers' base addresses for each channel
870 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
871 controller's Configuration Space to determine the operating mode.
873 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
874 ___________________________________________
875 | | Command Block | Control Block |
876 | Channel | Registers | Registers |
877 |___________|_______________|_______________|
878 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
879 |___________|_______________|_______________|
880 | Secondary | 170h - 177h | 376h - 377h |
881 |___________|_______________|_______________|
883 Table 1. Compatibility resource mappings
885 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
886 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
887 ___________________________________________________
888 | | Command Block | Control Block |
889 | Channel | Registers | Registers |
890 |___________|___________________|___________________|
891 | Primary | BAR at offset 0x10| BAR at offset 0x14|
892 |___________|___________________|___________________|
893 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
894 |___________|___________________|___________________|
896 Table 2. BARs for Register Mapping
898 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
899 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
900 store the IDE i/o port registers' base addresses
902 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
903 @retval EFI_SUCCESS Get the Base address successfully
904 @retval Other Read the pci configureation data error
909 GetIdeRegisterIoAddr (
910 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
911 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
916 UINT16 CommandBlockBaseAddr
;
917 UINT16 ControlBlockBaseAddr
;
918 UINT16 BusMasterBaseAddr
;
920 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
921 return EFI_INVALID_PARAMETER
;
924 Status
= PciIo
->Pci
.Read (
932 if (EFI_ERROR (Status
)) {
936 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
938 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
939 CommandBlockBaseAddr
= 0x1f0;
940 ControlBlockBaseAddr
= 0x3f6;
943 // The BARs should be of IO type
945 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
946 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
947 return EFI_UNSUPPORTED
;
950 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
951 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
955 // Calculate IDE primary channel I/O register base address.
957 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
958 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
959 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
960 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
961 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
962 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
963 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
964 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
965 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
966 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
968 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
969 CommandBlockBaseAddr
= 0x170;
970 ControlBlockBaseAddr
= 0x376;
973 // The BARs should be of IO type
975 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
976 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
977 return EFI_UNSUPPORTED
;
980 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
981 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
985 // Calculate IDE secondary channel I/O register base address.
987 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
988 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
989 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
990 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
991 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
992 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
993 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
994 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
995 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
996 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
1002 This function is used to implement the Soft Reset on the specified device. But,
1003 the ATA Soft Reset mechanism is so strong a reset method that it will force
1004 resetting on both devices connected to the same cable.
1006 It is called by IdeBlkIoReset(), a interface function of Block
1009 This function can also be used by the ATAPI device to perform reset when
1010 ATAPI Reset command is failed.
1012 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1013 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1014 @param Timeout The time to complete the command, uses 100ns as a unit.
1016 @retval EFI_SUCCESS Soft reset completes successfully.
1017 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1019 @note The registers initial values after ATA soft reset are different
1020 to the ATA device and ATAPI device.
1025 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1026 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1030 UINT8 DeviceControl
;
1034 // disable Interrupt and set SRST bit to initiate soft reset
1036 DeviceControl
= ATA_CTLREG_SRST
| ATA_CTLREG_IEN_L
;
1038 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1041 // SRST should assert for at least 5 us, we use 10 us for
1042 // better compatibility
1044 MicroSecondDelay (10);
1047 // Enable interrupt to support UDMA, and clear SRST bit
1050 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1053 // Wait for at least 10 ms to check BSY status, we use 10 ms
1054 // for better compatibility
1056 MicroSecondDelay (10000);
1059 // slave device needs at most 31ms to clear BSY
1061 if (WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
) == EFI_TIMEOUT
) {
1062 return EFI_DEVICE_ERROR
;
1069 Send ATA Ext command into device with NON_DATA protocol.
1071 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1072 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1073 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1074 @param Timeout The time to complete the command, uses 100ns as a unit.
1076 @retval EFI_SUCCESS Reading succeed
1077 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1083 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1084 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1085 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1093 ASSERT (PciIo
!= NULL
);
1094 ASSERT (IdeRegisters
!= NULL
);
1095 ASSERT (AtaCommandBlock
!= NULL
);
1097 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1098 AtaCommand
= AtaCommandBlock
->AtaCommand
;
1100 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1101 if (EFI_ERROR (Status
)) {
1102 return EFI_DEVICE_ERROR
;
1106 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1108 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
1111 // set all the command parameters
1112 // Before write to all the following registers, BSY and DRQ must be 0.
1114 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
1115 if (EFI_ERROR (Status
)) {
1116 return EFI_DEVICE_ERROR
;
1120 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1122 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
1123 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
1126 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1128 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
1129 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
1132 // Fill the start LBA registers, which are also two-byte FIFO
1134 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
1135 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
1137 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
1138 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
1140 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
1141 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
1144 // Send command via Command Register
1146 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
1149 // Stall at least 400 microseconds.
1151 MicroSecondDelay (400);
1157 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
1159 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1161 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1162 @param[in, out] Buffer A pointer to the source buffer for the data.
1163 @param[in] ByteCount The length of the data.
1164 @param[in] Read Flag used to determine the data transfer direction.
1165 Read equals 1, means data transferred from device
1166 to host;Read equals 0, means data transferred
1167 from host to device.
1168 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1169 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1170 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1171 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1172 used by non-blocking mode.
1174 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1175 @retval EFI_DEVICE_ERROR command sent failed.
1181 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1182 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1183 IN OUT VOID
*Buffer
,
1184 IN UINT64 ByteCount
,
1186 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1187 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1189 IN ATA_NONBLOCK_TASK
*Task
1197 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1198 return EFI_INVALID_PARAMETER
;
1202 // Issue ATA command
1204 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1205 if (EFI_ERROR (Status
)) {
1206 Status
= EFI_DEVICE_ERROR
;
1210 Buffer16
= (UINT16
*) Buffer
;
1213 // According to PIO data in protocol, host can perform a series of reads to
1214 // the data register after each time device set DRQ ready;
1215 // The data size of "a series of read" is command specific.
1216 // For most ATA command, data size received from device will not exceed
1217 // 1 sector, hence the data size for "a series of read" can be the whole data
1218 // size of one command request.
1219 // For ATA command such as Read Sector command, the data size of one ATA
1220 // command request is often larger than 1 sector, according to the
1221 // Read Sector command, the data size of "a series of read" is exactly 1
1223 // Here for simplification reason, we specify the data size for
1224 // "a series of read" to 1 sector (256 words) if data size of one ATA command
1225 // request is larger than 256 words.
1230 // used to record bytes of currently transfered data
1234 while (WordCount
< RShiftU64(ByteCount
, 1)) {
1236 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
1238 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1239 if (EFI_ERROR (Status
)) {
1240 Status
= EFI_DEVICE_ERROR
;
1245 // Get the byte count for one series of read
1247 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1248 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1252 IdeReadPortWMultiple (
1259 IdeWritePortWMultiple (
1267 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1268 if (EFI_ERROR (Status
)) {
1269 Status
= EFI_DEVICE_ERROR
;
1273 WordCount
+= Increment
;
1274 Buffer16
+= Increment
;
1277 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1278 if (EFI_ERROR (Status
)) {
1279 Status
= EFI_DEVICE_ERROR
;
1285 // Dump All Ide registers to ATA_STATUS_BLOCK
1287 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1290 // Not support the Non-blocking now,just do the blocking process.
1296 Send ATA command into device with NON_DATA protocol
1298 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1300 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1301 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1303 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1304 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1305 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1306 used by non-blocking mode.
1308 @retval EFI_SUCCESS Reading succeed
1309 @retval EFI_ABORTED Command failed
1310 @retval EFI_DEVICE_ERROR Device status error.
1315 AtaNonDataCommandIn (
1316 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1317 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1318 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1319 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1321 IN ATA_NONBLOCK_TASK
*Task
1326 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1327 return EFI_INVALID_PARAMETER
;
1331 // Issue ATA command
1333 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1334 if (EFI_ERROR (Status
)) {
1335 Status
= EFI_DEVICE_ERROR
;
1340 // Wait for command completion
1342 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1343 if (EFI_ERROR (Status
)) {
1344 Status
= EFI_DEVICE_ERROR
;
1348 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1349 if (EFI_ERROR (Status
)) {
1350 Status
= EFI_DEVICE_ERROR
;
1356 // Dump All Ide registers to ATA_STATUS_BLOCK
1358 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1361 // Not support the Non-blocking now,just do the blocking process.
1367 Wait for memory to be set.
1369 @param[in] PciIo The PCI IO protocol instance.
1370 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1371 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1373 @retval EFI_DEVICE_ERROR The memory is not set.
1374 @retval EFI_TIMEOUT The memory setting is time out.
1375 @retval EFI_SUCCESS The memory is correct set.
1380 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1381 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1385 UINT8 RegisterValue
;
1387 UINT16 IoPortForBmis
;
1389 BOOLEAN InfiniteWait
;
1392 InfiniteWait
= TRUE
;
1394 InfiniteWait
= FALSE
;
1397 Delay
= DivU64x32 (Timeout
, 1000) + 1;
1400 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1401 if (EFI_ERROR (Status
)) {
1402 Status
= EFI_DEVICE_ERROR
;
1406 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1407 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1408 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1409 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1410 Status
= EFI_DEVICE_ERROR
;
1414 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1415 Status
= EFI_SUCCESS
;
1419 // Stall for 100 microseconds.
1421 MicroSecondDelay (100);
1423 } while (InfiniteWait
|| (Delay
> 0));
1429 Check if the memory to be set.
1431 @param[in] PciIo The PCI IO protocol instance.
1432 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1433 used by non-blocking mode.
1434 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1436 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1437 @retval EFI_NOT_READY The memory is not set.
1438 @retval EFI_TIMEOUT The memory setting is time out.
1439 @retval EFI_SUCCESS The memory is correct set.
1444 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1445 IN ATA_NONBLOCK_TASK
*Task
,
1446 IN EFI_IDE_REGISTERS
*IdeRegisters
1449 UINT8 RegisterValue
;
1450 UINT16 IoPortForBmis
;
1455 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1456 if (EFI_ERROR (Status
)) {
1457 return EFI_DEVICE_ERROR
;
1460 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1461 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1463 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1464 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1465 return EFI_DEVICE_ERROR
;
1468 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1472 if (!Task
->InfiniteWait
&& (Task
->RetryTimes
== 0)) {
1476 // The memory is not set.
1478 return EFI_NOT_READY
;
1483 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1485 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1487 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1488 @param[in] Read Flag used to determine the data transfer
1489 direction. Read equals 1, means data transferred
1490 from device to host;Read equals 0, means data
1491 transferred from host to device.
1492 @param[in] DataBuffer A pointer to the source buffer for the data.
1493 @param[in] DataLength The length of the data.
1494 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1495 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1496 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1497 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1498 used by non-blocking mode.
1500 @retval EFI_SUCCESS the operation is successful.
1501 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1502 @retval EFI_UNSUPPORTED Unknown channel or operations command
1503 @retval EFI_DEVICE_ERROR Ata command execute failed
1509 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1510 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1512 IN VOID
*DataBuffer
,
1513 IN UINT64 DataLength
,
1514 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1515 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1517 IN ATA_NONBLOCK_TASK
*Task
1521 UINT16 IoPortForBmic
;
1522 UINT16 IoPortForBmis
;
1523 UINT16 IoPortForBmid
;
1526 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1528 EFI_ATA_DMA_PRD
*PrdBaseAddr
;
1529 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1532 UINT8 RegisterValue
;
1535 UINTN ByteRemaining
;
1536 UINT8 DeviceControl
;
1539 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1540 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1543 EFI_PCI_IO_PROTOCOL
*PciIo
;
1547 Status
= EFI_SUCCESS
;
1552 PciIo
= Instance
->PciIo
;
1554 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1555 return EFI_INVALID_PARAMETER
;
1559 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1561 // Delay 1ms to simulate the blocking time out checking.
1563 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1564 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1565 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1567 // Stall for 1 milliseconds.
1569 MicroSecondDelay (1000);
1571 gBS
->RestoreTPL (OldTpl
);
1574 // The data buffer should be even alignment
1576 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1577 return EFI_INVALID_PARAMETER
;
1581 // Set relevant IO Port address.
1583 IoPortForBmic
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1584 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1585 IoPortForBmid
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1588 // For Blocking mode, start the command.
1589 // For non-blocking mode, when the command is not started, start it, otherwise
1590 // go to check the status.
1592 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1594 // Calculate the number of PRD entry.
1595 // Every entry in PRD table can specify a 64K memory region.
1597 PrdTableNum
= (UINTN
)(RShiftU64(DataLength
, 16) + 1);
1600 // Make sure that the memory region of PRD table is not cross 64K boundary
1602 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1603 if (PrdTableSize
> 0x10000) {
1604 return EFI_INVALID_PARAMETER
;
1608 // Allocate buffer for PRD table initialization.
1610 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1611 Status
= PciIo
->AllocateBuffer (
1614 EfiBootServicesData
,
1616 (VOID
**)&PrdBaseAddr
,
1619 if (EFI_ERROR (Status
)) {
1620 return EFI_OUT_OF_RESOURCES
;
1623 ByteCount
= EFI_PAGES_TO_SIZE (PageCount
);
1624 Status
= PciIo
->Map (
1626 EfiPciIoOperationBusMasterCommonBuffer
,
1632 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (PageCount
))) {
1634 // If the data length actually mapped is not equal to the requested amount,
1635 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1636 // Can't handle this case.
1638 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1639 return EFI_OUT_OF_RESOURCES
;
1642 ZeroMem ((VOID
*) ((UINTN
) PrdBaseAddr
), ByteCount
);
1645 // Map the host address of DataBuffer to DMA master address.
1648 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1650 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1653 ByteCount
= (UINTN
)DataLength
;
1654 Status
= PciIo
->Map (
1662 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1663 PciIo
->Unmap (PciIo
, PrdTableMap
);
1664 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1665 return EFI_OUT_OF_RESOURCES
;
1669 // According to Ata spec, it requires the buffer address and size to be even.
1671 ASSERT ((BufferMapAddress
& 0x1) == 0);
1672 ASSERT ((ByteCount
& 0x1) == 0);
1675 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1677 ByteRemaining
= ByteCount
;
1678 TempPrdBaseAddr
= PrdBaseAddr
;
1679 while (ByteRemaining
!= 0) {
1680 if (ByteRemaining
<= 0x10000) {
1681 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1682 TempPrdBaseAddr
->ByteCount
= (UINT16
) ByteRemaining
;
1683 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1687 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1688 TempPrdBaseAddr
->ByteCount
= (UINT16
) 0x0;
1690 ByteRemaining
-= 0x10000;
1691 BufferMapAddress
+= 0x10000;
1696 // Start to enable the DMA operation
1698 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1700 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1703 // Enable interrupt to support UDMA
1706 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1709 // Read BMIS register and clear ERROR and INTR bit
1711 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmis
);
1712 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1713 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1716 // Set the base address to BMID register
1718 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1721 // Set BMIC register to identify the operation direction
1723 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1725 RegisterValue
|= BMIC_NREAD
;
1727 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1729 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1732 Task
->Map
= BufferMap
;
1733 Task
->TableMap
= PrdTableMap
;
1734 Task
->MapBaseAddress
= PrdBaseAddr
;
1735 Task
->PageCount
= PageCount
;
1736 Task
->IsStart
= TRUE
;
1740 // Issue ATA command
1742 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1744 if (EFI_ERROR (Status
)) {
1745 Status
= EFI_DEVICE_ERROR
;
1749 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1750 if (EFI_ERROR (Status
)) {
1751 Status
= EFI_DEVICE_ERROR
;
1755 // Set START bit of BMIC register
1757 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1758 RegisterValue
|= BMIC_START
;
1759 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1764 // Check the INTERRUPT and ERROR bit of BMIS
1767 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1769 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
, Timeout
);
1773 // For blocking mode, clear registers and free buffers.
1774 // For non blocking mode, when the related registers have been set or time
1775 // out, or a error has been happened, it needs to clear the register and free
1778 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1780 // Read BMIS register and clear ERROR and INTR bit
1782 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1783 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1784 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1787 // Read Status Register of IDE device to clear interrupt
1789 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1792 // Clear START bit of BMIC register
1794 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1795 RegisterValue
&= ~((UINT8
) BMIC_START
);
1796 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1799 // Disable interrupt of Select device
1801 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1802 DeviceControl
|= ATA_CTLREG_IEN_L
;
1803 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1805 // Stall for 10 milliseconds.
1807 MicroSecondDelay (10000);
1813 // Free all allocated resource
1815 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1817 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1818 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1819 PciIo
->Unmap (PciIo
, Task
->Map
);
1821 PciIo
->Unmap (PciIo
, PrdTableMap
);
1822 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1823 PciIo
->Unmap (PciIo
, BufferMap
);
1827 // Dump All Ide registers to ATA_STATUS_BLOCK
1829 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1836 This function reads the pending data in the device.
1838 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1839 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1841 @retval EFI_SUCCESS Successfully read.
1842 @retval EFI_NOT_READY The BSY is set avoiding reading.
1847 AtaPacketReadPendingData (
1848 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1849 IN EFI_IDE_REGISTERS
*IdeRegisters
1853 UINT16 TempWordBuffer
;
1855 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1856 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1857 return EFI_NOT_READY
;
1860 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1861 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1862 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1863 IdeReadPortWMultiple (
1869 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1876 This function is called by AtaPacketCommandExecute().
1877 It is used to transfer data between host and device. The data direction is specified
1878 by the fourth parameter.
1880 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1881 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1882 @param Buffer Buffer contained data transferred between host and device.
1883 @param ByteCount Data size in byte unit of the buffer.
1884 @param Read Flag used to determine the data transfer direction.
1885 Read equals 1, means data transferred from device to host;
1886 Read equals 0, means data transferred from host to device.
1887 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1888 , uses 100ns as a unit.
1890 @retval EFI_SUCCESS data is transferred successfully.
1891 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1895 AtaPacketReadWrite (
1896 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1897 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1898 IN OUT VOID
*Buffer
,
1899 IN UINT64 ByteCount
,
1904 UINT32 RequiredWordCount
;
1905 UINT32 ActualWordCount
;
1911 // No data transfer is premitted.
1913 if (ByteCount
== 0) {
1918 RequiredWordCount
= (UINT32
)RShiftU64(ByteCount
, 1);
1920 // ActuralWordCount means the word count of data really transferred.
1922 ActualWordCount
= 0;
1924 while (ActualWordCount
< RequiredWordCount
) {
1926 // before each data transfer stream, the host should poll DRQ bit ready,
1927 // to see whether indicates device is ready to transfer data.
1929 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1930 if (EFI_ERROR (Status
)) {
1931 return CheckStatusRegister (PciIo
, IdeRegisters
);
1935 // get current data transfer size from Cylinder Registers.
1937 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1938 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1939 WordCount
= WordCount
& 0xffff;
1942 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1945 IdeReadPortWMultiple (
1952 IdeWritePortWMultiple (
1961 // read status register to check whether error happens.
1963 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1964 if (EFI_ERROR (Status
)) {
1965 return EFI_DEVICE_ERROR
;
1968 PtrBuffer
+= WordCount
;
1969 ActualWordCount
+= WordCount
;
1974 // In the case where the drive wants to send more data than we need to read,
1975 // the DRQ bit will be set and cause delays from DRQClear2().
1976 // We need to read data from the drive until it clears DRQ so we can move on.
1978 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1982 // read status register to check whether error happens.
1984 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1985 if (EFI_ERROR (Status
)) {
1986 return EFI_DEVICE_ERROR
;
1990 // After data transfer is completed, normally, DRQ bit should clear.
1992 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1993 if (EFI_ERROR (Status
)) {
1994 return EFI_DEVICE_ERROR
;
2001 This function is used to send out ATAPI commands conforms to the Packet Command
2002 with PIO Data In Protocol.
2004 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
2005 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
2006 store the IDE i/o port registers' base addresses
2007 @param[in] Channel The channel number of device.
2008 @param[in] Device The device number of device.
2009 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
2011 @retval EFI_SUCCESS send out the ATAPI packet command successfully
2012 and device sends data successfully.
2013 @retval EFI_DEVICE_ERROR the device failed to send data.
2018 AtaPacketCommandExecute (
2019 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
2020 IN EFI_IDE_REGISTERS
*IdeRegisters
,
2023 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
2026 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2029 UINT8 PacketCommand
[12];
2031 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2034 // Fill ATAPI Command Packet according to CDB.
2035 // For Atapi cmd, its length should be less than or equal to 12 bytes.
2037 if (Packet
->CdbLength
> 12) {
2038 return EFI_INVALID_PARAMETER
;
2041 ZeroMem (PacketCommand
, 12);
2042 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
2047 AtaCommandBlock
.AtaFeatures
= 0x00;
2049 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
2050 // determine how many data should be transferred.
2052 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
2053 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
2054 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
2055 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
2057 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
2059 // Disable interrupt
2061 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
2064 // Issue ATA PACKET command firstly
2066 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
2067 if (EFI_ERROR (Status
)) {
2071 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
2072 if (EFI_ERROR (Status
)) {
2077 // Send out ATAPI command packet
2079 for (Count
= 0; Count
< 6; Count
++) {
2080 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
2082 // Stall for 10 microseconds.
2084 MicroSecondDelay (10);
2088 // Read/Write the data of ATAPI Command
2090 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
2091 Status
= AtaPacketReadWrite (
2094 Packet
->InDataBuffer
,
2095 Packet
->InTransferLength
,
2100 Status
= AtaPacketReadWrite (
2103 Packet
->OutDataBuffer
,
2104 Packet
->OutTransferLength
,
2115 Set the calculated Best transfer mode to a detected device.
2117 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2118 @param Channel The channel number of device.
2119 @param Device The device number of device.
2120 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
2121 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2123 @retval EFI_SUCCESS Set transfer mode successfully.
2124 @retval EFI_DEVICE_ERROR Set transfer mode failed.
2125 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2130 SetDeviceTransferMode (
2131 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2134 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
2135 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2139 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2141 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2143 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
2144 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2145 AtaCommandBlock
.AtaFeatures
= 0x03;
2146 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
2149 // Send SET FEATURE command (sub command 0x03) to set pio mode.
2151 Status
= AtaNonDataCommandIn (
2153 &Instance
->IdeRegisters
[Channel
],
2164 Set drive parameters for devices not support PACKETS command.
2166 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2167 @param Channel The channel number of device.
2168 @param Device The device number of device.
2169 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
2170 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2172 @retval EFI_SUCCESS Set drive parameter successfully.
2173 @retval EFI_DEVICE_ERROR Set drive parameter failed.
2174 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2179 SetDriveParameters (
2180 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2183 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
2184 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2188 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2190 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2192 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
2193 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
2194 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) + DriveParameters
->Heads
);
2197 // Send Init drive parameters
2199 Status
= AtaNonDataCommandIn (
2201 &Instance
->IdeRegisters
[Channel
],
2209 // Send Set Multiple parameters
2211 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
2212 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2213 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2215 Status
= AtaNonDataCommandIn (
2217 &Instance
->IdeRegisters
[Channel
],
2228 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2230 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2231 @param Channel The channel number of device.
2232 @param Device The device number of device.
2233 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2235 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2236 @retval Others Fail to get return status data.
2241 IdeAtaSmartReturnStatusCheck (
2242 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2245 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2249 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2253 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2255 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2256 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2257 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2258 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2259 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2262 // Send S.M.A.R.T Read Return Status command to device
2264 Status
= AtaNonDataCommandIn (
2266 &Instance
->IdeRegisters
[Channel
],
2273 if (EFI_ERROR (Status
)) {
2274 REPORT_STATUS_CODE (
2275 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2276 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
2278 return EFI_DEVICE_ERROR
;
2281 REPORT_STATUS_CODE (
2283 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
2286 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2287 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2289 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2291 // The threshold exceeded condition is not detected by the device
2293 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2294 REPORT_STATUS_CODE (
2296 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
2298 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2300 // The threshold exceeded condition is detected by the device
2302 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2303 REPORT_STATUS_CODE (
2305 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
2313 Enable SMART command of the disk if supported.
2315 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2316 @param Channel The channel number of device.
2317 @param Device The device number of device.
2318 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2319 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2324 IdeAtaSmartSupport (
2325 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2328 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2329 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2333 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2336 // Detect if the device supports S.M.A.R.T.
2338 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2340 // S.M.A.R.T is not supported by the device
2342 DEBUG ((EFI_D_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2343 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2344 REPORT_STATUS_CODE (
2345 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2346 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2350 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2352 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2354 REPORT_STATUS_CODE (
2356 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2359 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2361 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2362 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2363 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2364 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2365 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2368 // Send S.M.A.R.T Enable command to device
2370 Status
= AtaNonDataCommandIn (
2372 &Instance
->IdeRegisters
[Channel
],
2379 if (!EFI_ERROR (Status
)) {
2381 // Send S.M.A.R.T AutoSave command to device
2383 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2385 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2386 AtaCommandBlock
.AtaFeatures
= 0xD2;
2387 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2388 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2389 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2390 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2392 Status
= AtaNonDataCommandIn (
2394 &Instance
->IdeRegisters
[Channel
],
2400 if (!EFI_ERROR (Status
)) {
2401 Status
= IdeAtaSmartReturnStatusCheck (
2411 DEBUG ((EFI_D_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2412 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2421 Sends out an ATA Identify Command to the specified device.
2423 This function is called by DiscoverIdeDevice() during its device
2424 identification. It sends out the ATA Identify Command to the
2425 specified device. Only ATA device responses to this command. If
2426 the command succeeds, it returns the Identify data structure which
2427 contains information about the device. This function extracts the
2428 information it needs to fill the IDE_BLK_IO_DEV data structure,
2429 including device type, media block size, media capacity, and etc.
2431 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2432 @param Channel The channel number of device.
2433 @param Device The device number of device.
2434 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2435 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2437 @retval EFI_SUCCESS Identify ATA device successfully.
2438 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2439 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2445 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2448 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2449 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2453 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2455 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2457 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2458 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2460 Status
= AtaPioDataInOut (
2462 &Instance
->IdeRegisters
[Channel
],
2464 sizeof (EFI_IDENTIFY_DATA
),
2476 This function is called by DiscoverIdeDevice() during its device
2478 Its main purpose is to get enough information for the device media
2479 to fill in the Media data structure of the Block I/O Protocol interface.
2481 There are 5 steps to reach such objective:
2482 1. Sends out the ATAPI Identify Command to the specified device.
2483 Only ATAPI device responses to this command. If the command succeeds,
2484 it returns the Identify data structure which filled with information
2485 about the device. Since the ATAPI device contains removable media,
2486 the only meaningful information is the device module name.
2487 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2488 This command will return inquiry data of the device, which contains
2489 the device type information.
2490 3. Allocate sense data space for future use. We don't detect the media
2491 presence here to improvement boot performance, especially when CD
2492 media is present. The media detection will be performed just before
2493 each BLK_IO read/write
2495 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2496 @param Channel The channel number of device.
2497 @param Device The device number of device.
2498 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2499 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2501 @retval EFI_SUCCESS Identify ATAPI device successfully.
2502 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2503 is not supported by this IDE driver.
2504 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2510 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2513 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2514 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2518 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2520 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2522 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2523 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2526 // Send ATAPI Identify Command to get IDENTIFY data.
2528 Status
= AtaPioDataInOut (
2530 &Instance
->IdeRegisters
[Channel
],
2532 sizeof (EFI_IDENTIFY_DATA
),
2545 This function is used for detect whether the IDE device exists in the
2546 specified Channel as the specified Device Number.
2548 There is two IDE channels: one is Primary Channel, the other is
2549 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2550 Different channel has different register group.
2552 On each IDE channel, at most two IDE devices attach,
2553 one is called Device 0 (Master device), the other is called Device 1
2554 (Slave device). The devices on the same channel co-use the same register
2555 group, so before sending out a command for a specified device via command
2556 register, it is a must to select the current device to accept the command
2557 by set the device number in the Head/Device Register.
2559 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2560 @param IdeChannel The channel number of device.
2562 @retval EFI_SUCCESS successfully detects device.
2563 @retval other any failure during detection process will return this value.
2568 DetectAndConfigIdeDevice (
2569 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2574 UINT8 SectorCountReg
;
2578 EFI_ATA_DEVICE_TYPE DeviceType
;
2580 EFI_IDE_REGISTERS
*IdeRegisters
;
2581 EFI_IDENTIFY_DATA Buffer
;
2583 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2584 EFI_PCI_IO_PROTOCOL
*PciIo
;
2586 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2587 EFI_ATA_TRANSFER_MODE TransferMode
;
2588 EFI_ATA_DRIVE_PARMS DriveParameters
;
2590 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2591 IdeInit
= Instance
->IdeControllerInit
;
2592 PciIo
= Instance
->PciIo
;
2594 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2596 // Send ATA Device Execut Diagnostic command.
2597 // This command should work no matter DRDY is ready or not
2599 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2601 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2602 if (EFI_ERROR (Status
)) {
2603 DEBUG((EFI_D_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2608 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2610 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2612 // Stall for 1 milliseconds.
2614 MicroSecondDelay (1000);
2616 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2617 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2618 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2619 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2622 // Refer to ATA/ATAPI 4 Spec, section 9.1
2624 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2625 DeviceType
= EfiIdeHarddisk
;
2626 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2627 DeviceType
= EfiIdeCdrom
;
2633 // Send IDENTIFY cmd to the device to test if it is really attached.
2635 if (DeviceType
== EfiIdeHarddisk
) {
2636 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2638 // if identifying ata device is failure, then try to send identify packet cmd.
2640 if (EFI_ERROR (Status
)) {
2641 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2643 DeviceType
= EfiIdeCdrom
;
2644 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2647 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2649 // if identifying atapi device is failure, then try to send identify cmd.
2651 if (EFI_ERROR (Status
)) {
2652 DeviceType
= EfiIdeHarddisk
;
2653 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2657 if (EFI_ERROR (Status
)) {
2659 // No device is found at this port
2664 DEBUG ((EFI_D_INFO
, "[%a] channel [%a] [%a] device\n",
2665 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2666 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2668 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2670 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2671 IdeAtaSmartSupport (
2681 // Submit identify data to IDE controller init driver
2683 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2686 // Now start to config ide device parameter and transfer mode.
2688 Status
= IdeInit
->CalculateMode (
2694 if (EFI_ERROR (Status
)) {
2695 DEBUG ((EFI_D_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2700 // Set best supported PIO mode on this IDE device
2702 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2703 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2705 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2708 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2710 if (SupportedModes
->ExtModeCount
== 0){
2711 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2713 if (EFI_ERROR (Status
)) {
2714 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2720 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2721 // be set together. Only one DMA mode can be set to a device. If setting
2722 // DMA mode operation fails, we can continue moving on because we only use
2723 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2725 if (SupportedModes
->UdmaMode
.Valid
) {
2726 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2727 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2728 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2730 if (EFI_ERROR (Status
)) {
2731 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2734 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2735 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2736 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2737 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2739 if (EFI_ERROR (Status
)) {
2740 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2746 // Set Parameters for the device:
2748 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2750 if (DeviceType
== EfiIdeHarddisk
) {
2752 // Init driver parameters
2754 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2755 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2756 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2758 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2762 // Set IDE controller Timing Blocks in the PCI Configuration Space
2764 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2767 // IDE controller and IDE device timing is configured successfully.
2768 // Now insert the device into device list.
2770 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2771 if (EFI_ERROR (Status
)) {
2775 if (DeviceType
== EfiIdeHarddisk
) {
2776 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2784 Initialize ATA host controller at IDE mode.
2786 The function is designed to initialize ATA host controller.
2788 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2793 IdeModeInitialization (
2794 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2798 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2799 EFI_PCI_IO_PROTOCOL
*PciIo
;
2802 BOOLEAN ChannelEnabled
;
2805 IdeInit
= Instance
->IdeControllerInit
;
2806 PciIo
= Instance
->PciIo
;
2807 Channel
= IdeInit
->ChannelCount
;
2810 // Obtain IDE IO port registers' base addresses
2812 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2813 if (EFI_ERROR (Status
)) {
2817 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2818 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2821 // now obtain channel information fron IdeControllerInit protocol.
2823 Status
= IdeInit
->GetChannelInfo (
2829 if (EFI_ERROR (Status
)) {
2830 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
2834 if (!ChannelEnabled
) {
2838 ASSERT (MaxDevices
<= 2);
2840 // Now inform the IDE Controller Init Module.
2842 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2845 // No reset channel function implemented.
2847 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2850 // Now inform the IDE Controller Init Module.
2852 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2855 // Detect all attached ATA devices and set the transfer mode for each device.
2857 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2861 // All configurations done! Notify IdeController to do post initialization
2862 // work such as saving IDE controller PCI settings for S3 resume
2864 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);