2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2015, 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 BSY bit cleared and DRQ bit set within the
473 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
475 @retval EFI_ABORTED Polling abandoned due to command abort.
477 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
479 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
480 reported "command complete" by clearing DRQ
483 @note Read Status Register will clear interrupt status.
489 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
490 IN EFI_IDE_REGISTERS
*IdeRegisters
,
495 UINT8 StatusRegister
;
497 BOOLEAN InfiniteWait
;
499 ASSERT (PciIo
!= NULL
);
500 ASSERT (IdeRegisters
!= NULL
);
505 InfiniteWait
= FALSE
;
508 Delay
= DivU64x32(Timeout
, 1000) + 1;
511 // Read Status Register will clear interrupt
513 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
516 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
518 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
519 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
520 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
522 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
525 return EFI_DEVICE_ERROR
;
528 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
531 return EFI_NOT_READY
;
536 // Stall for 100 microseconds.
538 MicroSecondDelay (100);
541 } while (InfiniteWait
|| (Delay
> 0));
546 This function is used to poll for the DRQ bit set in the Alternate Status Register.
547 DRQ is set when the device is ready to transfer data. So this function is called after
548 the command is sent to the device and before required data is transferred.
550 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
551 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
552 @param Timeout The time to complete the command, uses 100ns as a unit.
554 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
557 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
559 @retval EFI_ABORTED Polling abandoned due to command abort.
561 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
563 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
564 reported "command complete" by clearing DRQ
567 @note Read Alternate Status Register will not clear interrupt status.
573 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
574 IN EFI_IDE_REGISTERS
*IdeRegisters
,
581 BOOLEAN InfiniteWait
;
583 ASSERT (PciIo
!= NULL
);
584 ASSERT (IdeRegisters
!= NULL
);
589 InfiniteWait
= FALSE
;
592 Delay
= DivU64x32(Timeout
, 1000) + 1;
596 // Read Alternate Status Register will not clear interrupt status
598 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
600 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
602 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
603 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
604 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
606 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
609 return EFI_DEVICE_ERROR
;
612 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
615 return EFI_NOT_READY
;
620 // Stall for 100 microseconds.
622 MicroSecondDelay (100);
625 } while (InfiniteWait
|| (Delay
> 0));
631 This function is used to poll for the DRDY bit set in the Status Register. DRDY
632 bit is set when the device is ready to accept command. Most ATA commands must be
633 sent after DRDY set except the ATAPI Packet Command.
635 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
636 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
637 @param Timeout The time to complete the command, uses 100ns as a unit.
639 @retval EFI_SUCCESS DRDY bit set within the time out.
640 @retval EFI_TIMEOUT DRDY bit not set within the time out.
642 @note Read Status Register will clear interrupt status.
647 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
648 IN EFI_IDE_REGISTERS
*IdeRegisters
,
653 UINT8 StatusRegister
;
655 BOOLEAN InfiniteWait
;
657 ASSERT (PciIo
!= NULL
);
658 ASSERT (IdeRegisters
!= NULL
);
663 InfiniteWait
= FALSE
;
666 Delay
= DivU64x32(Timeout
, 1000) + 1;
668 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
670 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
672 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
673 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
674 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
676 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
679 return EFI_DEVICE_ERROR
;
682 if ((StatusRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
685 return EFI_DEVICE_ERROR
;
690 // Stall for 100 microseconds.
692 MicroSecondDelay (100);
695 } while (InfiniteWait
|| (Delay
> 0));
701 This function is used to poll for the DRDY bit set in the Alternate Status Register.
702 DRDY bit is set when the device is ready to accept command. Most ATA commands must
703 be sent after DRDY set except the ATAPI Packet Command.
705 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
706 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
707 @param Timeout The time to complete the command, uses 100ns as a unit.
709 @retval EFI_SUCCESS DRDY bit set within the time out.
710 @retval EFI_TIMEOUT DRDY bit not set within the time out.
712 @note Read Alternate Status Register will clear interrupt status.
718 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
719 IN EFI_IDE_REGISTERS
*IdeRegisters
,
726 BOOLEAN InfiniteWait
;
728 ASSERT (PciIo
!= NULL
);
729 ASSERT (IdeRegisters
!= NULL
);
734 InfiniteWait
= FALSE
;
737 Delay
= DivU64x32(Timeout
, 1000) + 1;
739 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
741 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
743 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
744 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
745 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
747 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
750 return EFI_DEVICE_ERROR
;
753 if ((AltRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
756 return EFI_DEVICE_ERROR
;
761 // Stall for 100 microseconds.
763 MicroSecondDelay (100);
766 } while (InfiniteWait
|| (Delay
> 0));
772 This function is used to poll for the BSY bit clear in the Status Register. BSY
773 is clear when the device is not busy. Every command must be sent after device is not busy.
775 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
776 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
777 @param Timeout The time to complete the command, uses 100ns as a unit.
779 @retval EFI_SUCCESS BSY bit clear within the time out.
780 @retval EFI_TIMEOUT BSY bit not clear within the time out.
782 @note Read Status Register will clear interrupt status.
787 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
788 IN EFI_IDE_REGISTERS
*IdeRegisters
,
793 UINT8 StatusRegister
;
794 BOOLEAN InfiniteWait
;
796 ASSERT (PciIo
!= NULL
);
797 ASSERT (IdeRegisters
!= NULL
);
802 InfiniteWait
= FALSE
;
805 Delay
= DivU64x32(Timeout
, 1000) + 1;
807 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
809 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
814 // Stall for 100 microseconds.
816 MicroSecondDelay (100);
820 } while (InfiniteWait
|| (Delay
> 0));
826 This function is used to poll for the BSY bit clear in the Status Register. BSY
827 is clear when the device is not busy. Every command must be sent after device is not busy.
829 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
830 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
831 @param Timeout The time to complete the command, uses 100ns as a unit.
833 @retval EFI_SUCCESS BSY bit clear within the time out.
834 @retval EFI_TIMEOUT BSY bit not clear within the time out.
836 @note Read Status Register will clear interrupt status.
841 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
842 IN EFI_IDE_REGISTERS
*IdeRegisters
,
847 UINT8 AltStatusRegister
;
848 BOOLEAN InfiniteWait
;
850 ASSERT (PciIo
!= NULL
);
851 ASSERT (IdeRegisters
!= NULL
);
856 InfiniteWait
= FALSE
;
859 Delay
= DivU64x32(Timeout
, 1000) + 1;
861 AltStatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
863 if ((AltStatusRegister
& ATA_STSREG_BSY
) == 0x00) {
868 // Stall for 100 microseconds.
870 MicroSecondDelay (100);
874 } while (InfiniteWait
|| (Delay
> 0));
880 Get IDE i/o port registers' base addresses by mode.
882 In 'Compatibility' mode, use fixed addresses.
883 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
886 The steps to get IDE i/o port registers' base addresses for each channel
889 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
890 controller's Configuration Space to determine the operating mode.
892 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
893 ___________________________________________
894 | | Command Block | Control Block |
895 | Channel | Registers | Registers |
896 |___________|_______________|_______________|
897 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
898 |___________|_______________|_______________|
899 | Secondary | 170h - 177h | 376h - 377h |
900 |___________|_______________|_______________|
902 Table 1. Compatibility resource mappings
904 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
905 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
906 ___________________________________________________
907 | | Command Block | Control Block |
908 | Channel | Registers | Registers |
909 |___________|___________________|___________________|
910 | Primary | BAR at offset 0x10| BAR at offset 0x14|
911 |___________|___________________|___________________|
912 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
913 |___________|___________________|___________________|
915 Table 2. BARs for Register Mapping
917 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
918 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
919 store the IDE i/o port registers' base addresses
921 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
922 @retval EFI_SUCCESS Get the Base address successfully
923 @retval Other Read the pci configureation data error
928 GetIdeRegisterIoAddr (
929 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
930 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
935 UINT16 CommandBlockBaseAddr
;
936 UINT16 ControlBlockBaseAddr
;
937 UINT16 BusMasterBaseAddr
;
939 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
940 return EFI_INVALID_PARAMETER
;
943 Status
= PciIo
->Pci
.Read (
951 if (EFI_ERROR (Status
)) {
955 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
957 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
958 CommandBlockBaseAddr
= 0x1f0;
959 ControlBlockBaseAddr
= 0x3f6;
962 // The BARs should be of IO type
964 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
965 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
966 return EFI_UNSUPPORTED
;
969 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
970 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
974 // Calculate IDE primary channel I/O register base address.
976 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
977 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
978 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
979 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
980 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
981 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
982 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
983 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
984 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
985 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
987 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
988 CommandBlockBaseAddr
= 0x170;
989 ControlBlockBaseAddr
= 0x376;
992 // The BARs should be of IO type
994 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
995 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
996 return EFI_UNSUPPORTED
;
999 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
1000 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
1004 // Calculate IDE secondary channel I/O register base address.
1006 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
1007 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
1008 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
1009 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
1010 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
1011 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
1012 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
1013 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
1014 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
1015 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
1021 This function is used to implement the Soft Reset on the specified device. But,
1022 the ATA Soft Reset mechanism is so strong a reset method that it will force
1023 resetting on both devices connected to the same cable.
1025 It is called by IdeBlkIoReset(), a interface function of Block
1028 This function can also be used by the ATAPI device to perform reset when
1029 ATAPI Reset command is failed.
1031 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1032 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1033 @param Timeout The time to complete the command, uses 100ns as a unit.
1035 @retval EFI_SUCCESS Soft reset completes successfully.
1036 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1038 @note The registers initial values after ATA soft reset are different
1039 to the ATA device and ATAPI device.
1044 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1045 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1049 UINT8 DeviceControl
;
1053 // disable Interrupt and set SRST bit to initiate soft reset
1055 DeviceControl
= ATA_CTLREG_SRST
| ATA_CTLREG_IEN_L
;
1057 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1060 // SRST should assert for at least 5 us, we use 10 us for
1061 // better compatibility
1063 MicroSecondDelay (10);
1066 // Enable interrupt to support UDMA, and clear SRST bit
1069 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1072 // Wait for at least 10 ms to check BSY status, we use 10 ms
1073 // for better compatibility
1075 MicroSecondDelay (10000);
1078 // slave device needs at most 31ms to clear BSY
1080 if (WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
) == EFI_TIMEOUT
) {
1081 return EFI_DEVICE_ERROR
;
1088 Send ATA Ext command into device with NON_DATA protocol.
1090 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1091 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1092 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1093 @param Timeout The time to complete the command, uses 100ns as a unit.
1095 @retval EFI_SUCCESS Reading succeed
1096 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1102 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1103 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1104 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1112 ASSERT (PciIo
!= NULL
);
1113 ASSERT (IdeRegisters
!= NULL
);
1114 ASSERT (AtaCommandBlock
!= NULL
);
1116 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1117 AtaCommand
= AtaCommandBlock
->AtaCommand
;
1119 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1120 if (EFI_ERROR (Status
)) {
1121 return EFI_DEVICE_ERROR
;
1125 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1127 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
1130 // set all the command parameters
1131 // Before write to all the following registers, BSY and DRQ must be 0.
1133 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
1134 if (EFI_ERROR (Status
)) {
1135 return EFI_DEVICE_ERROR
;
1139 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1141 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
1142 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
1145 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1147 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
1148 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
1151 // Fill the start LBA registers, which are also two-byte FIFO
1153 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
1154 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
1156 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
1157 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
1159 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
1160 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
1163 // Send command via Command Register
1165 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
1168 // Stall at least 400 microseconds.
1170 MicroSecondDelay (400);
1176 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
1178 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1180 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1181 @param[in, out] Buffer A pointer to the source buffer for the data.
1182 @param[in] ByteCount The length of the data.
1183 @param[in] Read Flag used to determine the data transfer direction.
1184 Read equals 1, means data transferred from device
1185 to host;Read equals 0, means data transferred
1186 from host to device.
1187 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1188 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1189 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1190 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1191 used by non-blocking mode.
1193 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1194 @retval EFI_DEVICE_ERROR command sent failed.
1200 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1201 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1202 IN OUT VOID
*Buffer
,
1203 IN UINT64 ByteCount
,
1205 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1206 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1208 IN ATA_NONBLOCK_TASK
*Task
1216 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1217 return EFI_INVALID_PARAMETER
;
1221 // Issue ATA command
1223 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1224 if (EFI_ERROR (Status
)) {
1225 Status
= EFI_DEVICE_ERROR
;
1229 Buffer16
= (UINT16
*) Buffer
;
1232 // According to PIO data in protocol, host can perform a series of reads to
1233 // the data register after each time device set DRQ ready;
1234 // The data size of "a series of read" is command specific.
1235 // For most ATA command, data size received from device will not exceed
1236 // 1 sector, hence the data size for "a series of read" can be the whole data
1237 // size of one command request.
1238 // For ATA command such as Read Sector command, the data size of one ATA
1239 // command request is often larger than 1 sector, according to the
1240 // Read Sector command, the data size of "a series of read" is exactly 1
1242 // Here for simplification reason, we specify the data size for
1243 // "a series of read" to 1 sector (256 words) if data size of one ATA command
1244 // request is larger than 256 words.
1249 // used to record bytes of currently transfered data
1253 while (WordCount
< RShiftU64(ByteCount
, 1)) {
1255 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
1257 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1258 if (EFI_ERROR (Status
)) {
1259 Status
= EFI_DEVICE_ERROR
;
1264 // Get the byte count for one series of read
1266 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1267 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1271 IdeReadPortWMultiple (
1278 IdeWritePortWMultiple (
1286 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1287 if (EFI_ERROR (Status
)) {
1288 Status
= EFI_DEVICE_ERROR
;
1292 WordCount
+= Increment
;
1293 Buffer16
+= Increment
;
1296 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1297 if (EFI_ERROR (Status
)) {
1298 Status
= EFI_DEVICE_ERROR
;
1304 // Dump All Ide registers to ATA_STATUS_BLOCK
1306 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1309 // Not support the Non-blocking now,just do the blocking process.
1315 Send ATA command into device with NON_DATA protocol
1317 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1319 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1320 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1322 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1323 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1324 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1325 used by non-blocking mode.
1327 @retval EFI_SUCCESS Reading succeed
1328 @retval EFI_ABORTED Command failed
1329 @retval EFI_DEVICE_ERROR Device status error.
1334 AtaNonDataCommandIn (
1335 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1336 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1337 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1338 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1340 IN ATA_NONBLOCK_TASK
*Task
1345 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1346 return EFI_INVALID_PARAMETER
;
1350 // Issue ATA command
1352 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1353 if (EFI_ERROR (Status
)) {
1354 Status
= EFI_DEVICE_ERROR
;
1359 // Wait for command completion
1361 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1362 if (EFI_ERROR (Status
)) {
1363 Status
= EFI_DEVICE_ERROR
;
1367 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1368 if (EFI_ERROR (Status
)) {
1369 Status
= EFI_DEVICE_ERROR
;
1375 // Dump All Ide registers to ATA_STATUS_BLOCK
1377 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1380 // Not support the Non-blocking now,just do the blocking process.
1386 Wait for memory to be set.
1388 @param[in] PciIo The PCI IO protocol instance.
1389 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1390 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1392 @retval EFI_DEVICE_ERROR The memory is not set.
1393 @retval EFI_TIMEOUT The memory setting is time out.
1394 @retval EFI_SUCCESS The memory is correct set.
1399 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1400 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1404 UINT8 RegisterValue
;
1406 UINT16 IoPortForBmis
;
1408 BOOLEAN InfiniteWait
;
1411 InfiniteWait
= TRUE
;
1413 InfiniteWait
= FALSE
;
1416 Delay
= DivU64x32 (Timeout
, 1000) + 1;
1419 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1420 if (EFI_ERROR (Status
)) {
1421 Status
= EFI_DEVICE_ERROR
;
1425 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1426 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1427 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1428 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1429 Status
= EFI_DEVICE_ERROR
;
1433 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1434 Status
= EFI_SUCCESS
;
1438 // Stall for 100 microseconds.
1440 MicroSecondDelay (100);
1442 } while (InfiniteWait
|| (Delay
> 0));
1448 Check if the memory to be set.
1450 @param[in] PciIo The PCI IO protocol instance.
1451 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1452 used by non-blocking mode.
1453 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1455 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1456 @retval EFI_NOT_READY The memory is not set.
1457 @retval EFI_TIMEOUT The memory setting is time out.
1458 @retval EFI_SUCCESS The memory is correct set.
1463 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1464 IN ATA_NONBLOCK_TASK
*Task
,
1465 IN EFI_IDE_REGISTERS
*IdeRegisters
1468 UINT8 RegisterValue
;
1469 UINT16 IoPortForBmis
;
1474 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1475 if (EFI_ERROR (Status
)) {
1476 return EFI_DEVICE_ERROR
;
1479 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1480 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1482 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1483 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1484 return EFI_DEVICE_ERROR
;
1487 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1491 if (!Task
->InfiniteWait
&& (Task
->RetryTimes
== 0)) {
1495 // The memory is not set.
1497 return EFI_NOT_READY
;
1502 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1504 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1506 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1507 @param[in] Read Flag used to determine the data transfer
1508 direction. Read equals 1, means data transferred
1509 from device to host;Read equals 0, means data
1510 transferred from host to device.
1511 @param[in] DataBuffer A pointer to the source buffer for the data.
1512 @param[in] DataLength The length of the data.
1513 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1514 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1515 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1516 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1517 used by non-blocking mode.
1519 @retval EFI_SUCCESS the operation is successful.
1520 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1521 @retval EFI_UNSUPPORTED Unknown channel or operations command
1522 @retval EFI_DEVICE_ERROR Ata command execute failed
1528 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1529 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1531 IN VOID
*DataBuffer
,
1532 IN UINT64 DataLength
,
1533 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1534 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1536 IN ATA_NONBLOCK_TASK
*Task
1540 UINT16 IoPortForBmic
;
1541 UINT16 IoPortForBmis
;
1542 UINT16 IoPortForBmid
;
1545 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1547 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr
;
1548 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1551 UINT8 RegisterValue
;
1554 UINTN ByteRemaining
;
1555 UINT8 DeviceControl
;
1558 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1559 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1562 EFI_PCI_IO_PROTOCOL
*PciIo
;
1565 UINTN AlignmentMask
;
1566 UINTN RealPageCount
;
1567 EFI_PHYSICAL_ADDRESS BaseAddr
;
1568 EFI_PHYSICAL_ADDRESS BaseMapAddr
;
1570 Status
= EFI_SUCCESS
;
1576 PciIo
= Instance
->PciIo
;
1578 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1579 return EFI_INVALID_PARAMETER
;
1583 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1585 // Delay 1ms to simulate the blocking time out checking.
1587 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1588 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1589 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1591 // Stall for 1 milliseconds.
1593 MicroSecondDelay (1000);
1595 gBS
->RestoreTPL (OldTpl
);
1598 // The data buffer should be even alignment
1600 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1601 return EFI_INVALID_PARAMETER
;
1605 // Set relevant IO Port address.
1607 IoPortForBmic
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1608 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1609 IoPortForBmid
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1612 // For Blocking mode, start the command.
1613 // For non-blocking mode, when the command is not started, start it, otherwise
1614 // go to check the status.
1616 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1618 // Calculate the number of PRD entry.
1619 // Every entry in PRD table can specify a 64K memory region.
1621 PrdTableNum
= (UINTN
)(RShiftU64(DataLength
, 16) + 1);
1624 // Make sure that the memory region of PRD table is not cross 64K boundary
1626 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1627 if (PrdTableSize
> 0x10000) {
1628 return EFI_INVALID_PARAMETER
;
1632 // Allocate buffer for PRD table initialization.
1633 // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1634 // boundary and the table cannot cross a 64K boundary in memory.
1636 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1637 RealPageCount
= PageCount
+ EFI_SIZE_TO_PAGES (SIZE_64KB
);
1640 // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1642 ASSERT (RealPageCount
> PageCount
);
1644 Status
= PciIo
->AllocateBuffer (
1647 EfiBootServicesData
,
1652 if (EFI_ERROR (Status
)) {
1653 return EFI_OUT_OF_RESOURCES
;
1656 ByteCount
= EFI_PAGES_TO_SIZE (RealPageCount
);
1657 Status
= PciIo
->Map (
1659 EfiPciIoOperationBusMasterCommonBuffer
,
1660 (VOID
*)(UINTN
)BaseAddr
,
1665 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (RealPageCount
))) {
1667 // If the data length actually mapped is not equal to the requested amount,
1668 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1669 // Can't handle this case.
1671 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1672 return EFI_OUT_OF_RESOURCES
;
1675 ZeroMem ((VOID
*) ((UINTN
) BaseAddr
), ByteCount
);
1678 // Calculate the 64K align address as PRD Table base address.
1680 AlignmentMask
= SIZE_64KB
- 1;
1681 PrdTableBaseAddr
= ((UINTN
) BaseAddr
+ AlignmentMask
) & ~AlignmentMask
;
1682 PrdTableMapAddr
= ((UINTN
) BaseMapAddr
+ AlignmentMask
) & ~AlignmentMask
;
1685 // Map the host address of DataBuffer to DMA master address.
1688 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1690 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1693 ByteCount
= (UINTN
)DataLength
;
1694 Status
= PciIo
->Map (
1702 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1703 PciIo
->Unmap (PciIo
, PrdTableMap
);
1704 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1705 return EFI_OUT_OF_RESOURCES
;
1709 // According to Ata spec, it requires the buffer address and size to be even.
1711 ASSERT ((BufferMapAddress
& 0x1) == 0);
1712 ASSERT ((ByteCount
& 0x1) == 0);
1715 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1717 ByteRemaining
= ByteCount
;
1718 TempPrdBaseAddr
= (EFI_ATA_DMA_PRD
*)(UINTN
)PrdTableBaseAddr
;
1719 while (ByteRemaining
!= 0) {
1720 if (ByteRemaining
<= 0x10000) {
1721 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1722 TempPrdBaseAddr
->ByteCount
= (UINT16
) ByteRemaining
;
1723 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1727 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1728 TempPrdBaseAddr
->ByteCount
= (UINT16
) 0x0;
1730 ByteRemaining
-= 0x10000;
1731 BufferMapAddress
+= 0x10000;
1736 // Start to enable the DMA operation
1738 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1740 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1743 // Enable interrupt to support UDMA
1746 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1749 // Read BMIS register and clear ERROR and INTR bit
1751 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmis
);
1752 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1753 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1756 // Set the base address to BMID register
1758 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1761 // Set BMIC register to identify the operation direction
1763 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1765 RegisterValue
|= BMIC_NREAD
;
1767 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1769 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1772 Task
->Map
= BufferMap
;
1773 Task
->TableMap
= PrdTableMap
;
1774 Task
->MapBaseAddress
= (EFI_ATA_DMA_PRD
*)(UINTN
)BaseAddr
;
1775 Task
->PageCount
= RealPageCount
;
1776 Task
->IsStart
= TRUE
;
1780 // Issue ATA command
1782 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1784 if (EFI_ERROR (Status
)) {
1785 Status
= EFI_DEVICE_ERROR
;
1789 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1790 if (EFI_ERROR (Status
)) {
1791 Status
= EFI_DEVICE_ERROR
;
1795 // Set START bit of BMIC register
1797 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1798 RegisterValue
|= BMIC_START
;
1799 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1804 // Check the INTERRUPT and ERROR bit of BMIS
1807 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1809 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
, Timeout
);
1813 // For blocking mode, clear registers and free buffers.
1814 // For non blocking mode, when the related registers have been set or time
1815 // out, or a error has been happened, it needs to clear the register and free
1818 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1820 // Read BMIS register and clear ERROR and INTR bit
1822 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1823 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1824 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1827 // Read Status Register of IDE device to clear interrupt
1829 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1832 // Clear START bit of BMIC register
1834 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1835 RegisterValue
&= ~((UINT8
) BMIC_START
);
1836 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1839 // Disable interrupt of Select device
1841 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1842 DeviceControl
|= ATA_CTLREG_IEN_L
;
1843 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1845 // Stall for 10 milliseconds.
1847 MicroSecondDelay (10000);
1853 // Free all allocated resource
1855 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1857 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1858 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1859 PciIo
->Unmap (PciIo
, Task
->Map
);
1861 PciIo
->Unmap (PciIo
, PrdTableMap
);
1862 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1863 PciIo
->Unmap (PciIo
, BufferMap
);
1867 // Dump All Ide registers to ATA_STATUS_BLOCK
1869 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1876 This function reads the pending data in the device.
1878 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1879 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1881 @retval EFI_SUCCESS Successfully read.
1882 @retval EFI_NOT_READY The BSY is set avoiding reading.
1887 AtaPacketReadPendingData (
1888 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1889 IN EFI_IDE_REGISTERS
*IdeRegisters
1893 UINT16 TempWordBuffer
;
1895 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1896 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1897 return EFI_NOT_READY
;
1900 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1901 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1902 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1903 IdeReadPortWMultiple (
1909 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1916 This function is called by AtaPacketCommandExecute().
1917 It is used to transfer data between host and device. The data direction is specified
1918 by the fourth parameter.
1920 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1921 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1922 @param Buffer Buffer contained data transferred between host and device.
1923 @param ByteCount Data size in byte unit of the buffer.
1924 @param Read Flag used to determine the data transfer direction.
1925 Read equals 1, means data transferred from device to host;
1926 Read equals 0, means data transferred from host to device.
1927 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1928 , uses 100ns as a unit.
1930 @retval EFI_SUCCESS data is transferred successfully.
1931 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1935 AtaPacketReadWrite (
1936 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1937 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1938 IN OUT VOID
*Buffer
,
1939 IN OUT UINT32
*ByteCount
,
1944 UINT32 RequiredWordCount
;
1945 UINT32 ActualWordCount
;
1951 RequiredWordCount
= *ByteCount
>> 1;
1954 // No data transfer is premitted.
1956 if (RequiredWordCount
== 0) {
1961 // ActualWordCount means the word count of data really transferred.
1963 ActualWordCount
= 0;
1965 while (ActualWordCount
< RequiredWordCount
) {
1967 // before each data transfer stream, the host should poll DRQ bit ready,
1968 // to see whether indicates device is ready to transfer data.
1970 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1971 if (EFI_ERROR (Status
)) {
1972 if (Status
== EFI_NOT_READY
) {
1974 // Device provided less data than we intended to read, or wanted less
1975 // data than we intended to write, but it may still be successful.
1984 // get current data transfer size from Cylinder Registers.
1986 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1987 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1988 WordCount
= WordCount
& 0xffff;
1991 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1994 IdeReadPortWMultiple (
2001 IdeWritePortWMultiple (
2010 // read status register to check whether error happens.
2012 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
2013 if (EFI_ERROR (Status
)) {
2014 return EFI_DEVICE_ERROR
;
2017 PtrBuffer
+= WordCount
;
2018 ActualWordCount
+= WordCount
;
2023 // In the case where the drive wants to send more data than we need to read,
2024 // the DRQ bit will be set and cause delays from DRQClear2().
2025 // We need to read data from the drive until it clears DRQ so we can move on.
2027 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
2031 // read status register to check whether error happens.
2033 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
2034 if (EFI_ERROR (Status
)) {
2035 return EFI_DEVICE_ERROR
;
2039 // After data transfer is completed, normally, DRQ bit should clear.
2041 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
2042 if (EFI_ERROR (Status
)) {
2043 return EFI_DEVICE_ERROR
;
2046 *ByteCount
= ActualWordCount
<< 1;
2051 This function is used to send out ATAPI commands conforms to the Packet Command
2052 with PIO Data In Protocol.
2054 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
2055 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
2056 store the IDE i/o port registers' base addresses
2057 @param[in] Channel The channel number of device.
2058 @param[in] Device The device number of device.
2059 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
2061 @retval EFI_SUCCESS send out the ATAPI packet command successfully
2062 and device sends data successfully.
2063 @retval EFI_DEVICE_ERROR the device failed to send data.
2068 AtaPacketCommandExecute (
2069 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
2070 IN EFI_IDE_REGISTERS
*IdeRegisters
,
2073 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
2076 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2079 UINT8 PacketCommand
[12];
2081 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2084 // Fill ATAPI Command Packet according to CDB.
2085 // For Atapi cmd, its length should be less than or equal to 12 bytes.
2087 if (Packet
->CdbLength
> 12) {
2088 return EFI_INVALID_PARAMETER
;
2091 ZeroMem (PacketCommand
, 12);
2092 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
2097 AtaCommandBlock
.AtaFeatures
= 0x00;
2099 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
2100 // determine how many data should be transferred.
2102 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
2103 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
2104 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
2105 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
2107 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
2109 // Disable interrupt
2111 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
2114 // Issue ATA PACKET command firstly
2116 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
2117 if (EFI_ERROR (Status
)) {
2121 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
2122 if (EFI_ERROR (Status
)) {
2127 // Send out ATAPI command packet
2129 for (Count
= 0; Count
< 6; Count
++) {
2130 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
2132 // Stall for 10 microseconds.
2134 MicroSecondDelay (10);
2138 // Read/Write the data of ATAPI Command
2140 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
2141 Status
= AtaPacketReadWrite (
2144 Packet
->InDataBuffer
,
2145 &Packet
->InTransferLength
,
2150 Status
= AtaPacketReadWrite (
2153 Packet
->OutDataBuffer
,
2154 &Packet
->OutTransferLength
,
2165 Set the calculated Best transfer mode to a detected device.
2167 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2168 @param Channel The channel number of device.
2169 @param Device The device number of device.
2170 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
2171 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2173 @retval EFI_SUCCESS Set transfer mode successfully.
2174 @retval EFI_DEVICE_ERROR Set transfer mode failed.
2175 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2180 SetDeviceTransferMode (
2181 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2184 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
2185 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2189 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2191 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2193 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
2194 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2195 AtaCommandBlock
.AtaFeatures
= 0x03;
2196 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
2199 // Send SET FEATURE command (sub command 0x03) to set pio mode.
2201 Status
= AtaNonDataCommandIn (
2203 &Instance
->IdeRegisters
[Channel
],
2214 Set drive parameters for devices not support PACKETS command.
2216 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2217 @param Channel The channel number of device.
2218 @param Device The device number of device.
2219 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
2220 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2222 @retval EFI_SUCCESS Set drive parameter successfully.
2223 @retval EFI_DEVICE_ERROR Set drive parameter failed.
2224 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2229 SetDriveParameters (
2230 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2233 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
2234 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2238 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2240 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2242 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
2243 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
2244 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) + DriveParameters
->Heads
);
2247 // Send Init drive parameters
2249 Status
= AtaNonDataCommandIn (
2251 &Instance
->IdeRegisters
[Channel
],
2259 // Send Set Multiple parameters
2261 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
2262 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2263 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2265 Status
= AtaNonDataCommandIn (
2267 &Instance
->IdeRegisters
[Channel
],
2278 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2280 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2281 @param Channel The channel number of device.
2282 @param Device The device number of device.
2283 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2285 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2286 @retval Others Fail to get return status data.
2291 IdeAtaSmartReturnStatusCheck (
2292 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2295 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2299 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2303 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2305 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2306 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2307 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2308 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2309 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2312 // Send S.M.A.R.T Read Return Status command to device
2314 Status
= AtaNonDataCommandIn (
2316 &Instance
->IdeRegisters
[Channel
],
2323 if (EFI_ERROR (Status
)) {
2324 REPORT_STATUS_CODE (
2325 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2326 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
2328 return EFI_DEVICE_ERROR
;
2331 REPORT_STATUS_CODE (
2333 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
2336 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2337 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2339 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2341 // The threshold exceeded condition is not detected by the device
2343 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2344 REPORT_STATUS_CODE (
2346 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
2348 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2350 // The threshold exceeded condition is detected by the device
2352 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2353 REPORT_STATUS_CODE (
2355 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
2363 Enable SMART command of the disk if supported.
2365 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2366 @param Channel The channel number of device.
2367 @param Device The device number of device.
2368 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2369 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2374 IdeAtaSmartSupport (
2375 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2378 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2379 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2383 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2386 // Detect if the device supports S.M.A.R.T.
2388 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2390 // S.M.A.R.T is not supported by the device
2392 DEBUG ((EFI_D_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2393 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2394 REPORT_STATUS_CODE (
2395 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2396 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2400 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2402 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2404 REPORT_STATUS_CODE (
2406 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2409 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2411 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2412 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2413 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2414 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2415 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2418 // Send S.M.A.R.T Enable command to device
2420 Status
= AtaNonDataCommandIn (
2422 &Instance
->IdeRegisters
[Channel
],
2429 if (!EFI_ERROR (Status
)) {
2431 // Send S.M.A.R.T AutoSave command to device
2433 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2435 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2436 AtaCommandBlock
.AtaFeatures
= 0xD2;
2437 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2438 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2439 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2440 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2442 Status
= AtaNonDataCommandIn (
2444 &Instance
->IdeRegisters
[Channel
],
2450 if (!EFI_ERROR (Status
)) {
2451 Status
= IdeAtaSmartReturnStatusCheck (
2461 DEBUG ((EFI_D_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2462 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2471 Sends out an ATA Identify Command to the specified device.
2473 This function is called by DiscoverIdeDevice() during its device
2474 identification. It sends out the ATA Identify Command to the
2475 specified device. Only ATA device responses to this command. If
2476 the command succeeds, it returns the Identify data structure which
2477 contains information about the device. This function extracts the
2478 information it needs to fill the IDE_BLK_IO_DEV data structure,
2479 including device type, media block size, media capacity, and etc.
2481 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2482 @param Channel The channel number of device.
2483 @param Device The device number of device.
2484 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2485 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2487 @retval EFI_SUCCESS Identify ATA device successfully.
2488 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2489 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2495 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2498 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2499 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2503 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2505 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2507 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2508 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2510 Status
= AtaPioDataInOut (
2512 &Instance
->IdeRegisters
[Channel
],
2514 sizeof (EFI_IDENTIFY_DATA
),
2526 This function is called by DiscoverIdeDevice() during its device
2528 Its main purpose is to get enough information for the device media
2529 to fill in the Media data structure of the Block I/O Protocol interface.
2531 There are 5 steps to reach such objective:
2532 1. Sends out the ATAPI Identify Command to the specified device.
2533 Only ATAPI device responses to this command. If the command succeeds,
2534 it returns the Identify data structure which filled with information
2535 about the device. Since the ATAPI device contains removable media,
2536 the only meaningful information is the device module name.
2537 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2538 This command will return inquiry data of the device, which contains
2539 the device type information.
2540 3. Allocate sense data space for future use. We don't detect the media
2541 presence here to improvement boot performance, especially when CD
2542 media is present. The media detection will be performed just before
2543 each BLK_IO read/write
2545 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2546 @param Channel The channel number of device.
2547 @param Device The device number of device.
2548 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2549 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2551 @retval EFI_SUCCESS Identify ATAPI device successfully.
2552 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2553 is not supported by this IDE driver.
2554 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2560 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2563 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2564 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2568 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2570 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2572 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2573 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2576 // Send ATAPI Identify Command to get IDENTIFY data.
2578 Status
= AtaPioDataInOut (
2580 &Instance
->IdeRegisters
[Channel
],
2582 sizeof (EFI_IDENTIFY_DATA
),
2595 This function is used for detect whether the IDE device exists in the
2596 specified Channel as the specified Device Number.
2598 There is two IDE channels: one is Primary Channel, the other is
2599 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2600 Different channel has different register group.
2602 On each IDE channel, at most two IDE devices attach,
2603 one is called Device 0 (Master device), the other is called Device 1
2604 (Slave device). The devices on the same channel co-use the same register
2605 group, so before sending out a command for a specified device via command
2606 register, it is a must to select the current device to accept the command
2607 by set the device number in the Head/Device Register.
2609 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2610 @param IdeChannel The channel number of device.
2612 @retval EFI_SUCCESS successfully detects device.
2613 @retval other any failure during detection process will return this value.
2618 DetectAndConfigIdeDevice (
2619 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2624 UINT8 SectorCountReg
;
2628 EFI_ATA_DEVICE_TYPE DeviceType
;
2630 EFI_IDE_REGISTERS
*IdeRegisters
;
2631 EFI_IDENTIFY_DATA Buffer
;
2633 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2634 EFI_PCI_IO_PROTOCOL
*PciIo
;
2636 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2637 EFI_ATA_TRANSFER_MODE TransferMode
;
2638 EFI_ATA_DRIVE_PARMS DriveParameters
;
2640 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2641 IdeInit
= Instance
->IdeControllerInit
;
2642 PciIo
= Instance
->PciIo
;
2644 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2646 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2648 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2651 // Send ATA Device Execut Diagnostic command.
2652 // This command should work no matter DRDY is ready or not
2654 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2656 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2657 if (EFI_ERROR (Status
)) {
2658 DEBUG((EFI_D_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2663 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2665 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2667 // Stall for 1 milliseconds.
2669 MicroSecondDelay (1000);
2671 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2672 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2673 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2674 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2677 // Refer to ATA/ATAPI 4 Spec, section 9.1
2679 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2680 DeviceType
= EfiIdeHarddisk
;
2681 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2682 DeviceType
= EfiIdeCdrom
;
2688 // Send IDENTIFY cmd to the device to test if it is really attached.
2690 if (DeviceType
== EfiIdeHarddisk
) {
2691 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2693 // if identifying ata device is failure, then try to send identify packet cmd.
2695 if (EFI_ERROR (Status
)) {
2696 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2698 DeviceType
= EfiIdeCdrom
;
2699 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2702 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2704 // if identifying atapi device is failure, then try to send identify cmd.
2706 if (EFI_ERROR (Status
)) {
2707 DeviceType
= EfiIdeHarddisk
;
2708 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2712 if (EFI_ERROR (Status
)) {
2714 // No device is found at this port
2719 DEBUG ((EFI_D_INFO
, "[%a] channel [%a] [%a] device\n",
2720 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2721 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2723 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2725 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2726 IdeAtaSmartSupport (
2736 // Submit identify data to IDE controller init driver
2738 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2741 // Now start to config ide device parameter and transfer mode.
2743 Status
= IdeInit
->CalculateMode (
2749 if (EFI_ERROR (Status
)) {
2750 DEBUG ((EFI_D_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2755 // Set best supported PIO mode on this IDE device
2757 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2758 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2760 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2763 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2765 if (SupportedModes
->ExtModeCount
== 0){
2766 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2768 if (EFI_ERROR (Status
)) {
2769 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2775 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2776 // be set together. Only one DMA mode can be set to a device. If setting
2777 // DMA mode operation fails, we can continue moving on because we only use
2778 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2780 if (SupportedModes
->UdmaMode
.Valid
) {
2781 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2782 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2783 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2785 if (EFI_ERROR (Status
)) {
2786 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2789 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2790 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2791 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2792 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2794 if (EFI_ERROR (Status
)) {
2795 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2801 // Set Parameters for the device:
2803 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2805 if (DeviceType
== EfiIdeHarddisk
) {
2807 // Init driver parameters
2809 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2810 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2811 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2813 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2817 // Set IDE controller Timing Blocks in the PCI Configuration Space
2819 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2822 // IDE controller and IDE device timing is configured successfully.
2823 // Now insert the device into device list.
2825 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2826 if (EFI_ERROR (Status
)) {
2830 if (DeviceType
== EfiIdeHarddisk
) {
2831 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2839 Initialize ATA host controller at IDE mode.
2841 The function is designed to initialize ATA host controller.
2843 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2848 IdeModeInitialization (
2849 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2853 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2854 EFI_PCI_IO_PROTOCOL
*PciIo
;
2857 BOOLEAN ChannelEnabled
;
2860 IdeInit
= Instance
->IdeControllerInit
;
2861 PciIo
= Instance
->PciIo
;
2862 Channel
= IdeInit
->ChannelCount
;
2865 // Obtain IDE IO port registers' base addresses
2867 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2868 if (EFI_ERROR (Status
)) {
2872 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2873 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2876 // now obtain channel information fron IdeControllerInit protocol.
2878 Status
= IdeInit
->GetChannelInfo (
2884 if (EFI_ERROR (Status
)) {
2885 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
2889 if (!ChannelEnabled
) {
2893 ASSERT (MaxDevices
<= 2);
2895 // Now inform the IDE Controller Init Module.
2897 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2900 // No reset channel function implemented.
2902 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2905 // Now inform the IDE Controller Init Module.
2907 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2910 // Detect all attached ATA devices and set the transfer mode for each device.
2912 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2916 // All configurations done! Notify IdeController to do post initialization
2917 // work such as saving IDE controller PCI settings for S3 resume
2919 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);