2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2011, 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 The PCI IO protocol instance
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 The PCI IO protocol instance
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 PCI IO protocol instance
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 PCI IO protocol instance
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 Pointer to the EFI_PCI_IO instance
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 Pointer to the EFI_PCI_IO instance
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 ATA_ATAPI_PASS_THRU_INSTANCE 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 and print out
298 some debug information and if there is ERR bit set in the Status
299 Register, the Error Register's value is also be parsed and print out.
301 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
302 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
304 @retval EFI_SUCCESS No err information in the Status Register.
305 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
310 CheckStatusRegister (
311 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
312 IN EFI_IDE_REGISTERS
*IdeRegisters
316 UINT8 StatusRegister
;
318 ASSERT (PciIo
!= NULL
);
319 ASSERT (IdeRegisters
!= NULL
);
321 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
323 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
324 Status
= EFI_SUCCESS
;
326 Status
= EFI_DEVICE_ERROR
;
333 This function is used to poll for the DRQ bit clear in the Status
334 Register. DRQ is cleared when the device is finished transferring data.
335 So this function is called after data transfer is finished.
337 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
338 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
339 @param Timeout The time to complete the command.
341 @retval EFI_SUCCESS DRQ bit clear within the time out.
343 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
346 Read Status Register will clear interrupt status.
352 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
353 IN EFI_IDE_REGISTERS
*IdeRegisters
,
358 UINT8 StatusRegister
;
361 ASSERT (PciIo
!= NULL
);
362 ASSERT (IdeRegisters
!= NULL
);
364 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
366 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
369 // wait for BSY == 0 and DRQ == 0
371 if ((StatusRegister
& (ATA_STSREG_DRQ
| ATA_STSREG_BSY
)) == 0) {
375 if ((StatusRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
376 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
378 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
384 // Stall for 100 microseconds.
386 MicroSecondDelay (100);
399 This function is used to poll for the DRQ bit clear in the Alternate
400 Status Register. DRQ is cleared when the device is finished
401 transferring data. So this function is called after data transfer
404 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
405 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
406 @param Timeout The time to complete the command.
408 @retval EFI_SUCCESS DRQ bit clear within the time out.
410 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
411 @note Read Alternate Status Register will not clear interrupt status.
417 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
418 IN EFI_IDE_REGISTERS
*IdeRegisters
,
426 ASSERT (PciIo
!= NULL
);
427 ASSERT (IdeRegisters
!= NULL
);
429 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
431 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
434 // wait for BSY == 0 and DRQ == 0
436 if ((AltRegister
& (ATA_STSREG_DRQ
| ATA_STSREG_BSY
)) == 0) {
440 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
441 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
443 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
449 // Stall for 100 microseconds.
451 MicroSecondDelay (100);
465 This function is used to poll for the DRQ bit set in the
467 DRQ is set when the device is ready to transfer data. So this function
468 is called after the command is sent to the device and before required
471 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
472 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
473 @param Timeout The time to complete the command.
475 @retval EFI_SUCCESS DRQ bit set within the time out.
476 @retval EFI_TIMEOUT DRQ bit not set within the time out.
477 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
479 @note Read Status Register will clear interrupt status.
485 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
486 IN EFI_IDE_REGISTERS
*IdeRegisters
,
491 UINT8 StatusRegister
;
494 ASSERT (PciIo
!= NULL
);
495 ASSERT (IdeRegisters
!= NULL
);
497 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
500 // read Status Register will clear interrupt
502 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
507 if ((StatusRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
511 if ((StatusRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
512 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
514 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
520 // Stall for 100 microseconds.
522 MicroSecondDelay (100);
534 This function is used to poll for the DRQ bit set in the Alternate Status Register.
535 DRQ is set when the device is ready to transfer data. So this function is called after
536 the command is sent to the device and before required data is transferred.
538 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
539 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
540 @param Timeout The time to complete the command.
542 @retval EFI_SUCCESS DRQ bit set within the time out.
543 @retval EFI_TIMEOUT DRQ bit not set within the time out.
544 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
545 @note Read Alternate Status Register will not clear interrupt status.
551 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
552 IN EFI_IDE_REGISTERS
*IdeRegisters
,
560 ASSERT (PciIo
!= NULL
);
561 ASSERT (IdeRegisters
!= NULL
);
563 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
567 // Read Alternate Status Register will not clear interrupt status
569 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
571 // BSY == 0 , DRQ == 1
573 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
577 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
578 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
580 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
586 // Stall for 100 microseconds.
588 MicroSecondDelay (100);
601 This function is used to poll for the DRDY bit set in the Status Register. DRDY
602 bit is set when the device is ready to accept command. Most ATA commands must be
603 sent after DRDY set except the ATAPI Packet Command.
605 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
606 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
607 @param Timeout The time to complete the command.
609 @retval EFI_SUCCESS DRDY bit set within the time out.
610 @retval EFI_TIMEOUT DRDY bit not set within the time out.
612 @note Read Status Register will clear interrupt status.
617 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
618 IN EFI_IDE_REGISTERS
*IdeRegisters
,
623 UINT8 StatusRegister
;
626 ASSERT (PciIo
!= NULL
);
627 ASSERT (IdeRegisters
!= NULL
);
629 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
631 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
633 // BSY == 0 , DRDY == 1
635 if ((StatusRegister
& (ATA_STSREG_DRDY
| ATA_STSREG_BSY
)) == ATA_STSREG_DRDY
) {
639 if ((StatusRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
640 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
642 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
648 // Stall for 100 microseconds.
650 MicroSecondDelay (100);
663 This function is used to poll for the DRDY bit set in the Alternate Status Register.
664 DRDY bit is set when the device is ready to accept command. Most ATA commands must
665 be sent after DRDY set except the ATAPI Packet Command.
667 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
668 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
669 @param Timeout The time to complete the command.
671 @retval EFI_SUCCESS DRDY bit set within the time out.
672 @retval EFI_TIMEOUT DRDY bit not set within the time out.
674 @note Read Alternate Status Register will clear interrupt status.
680 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
681 IN EFI_IDE_REGISTERS
*IdeRegisters
,
689 ASSERT (PciIo
!= NULL
);
690 ASSERT (IdeRegisters
!= NULL
);
692 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
694 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
696 // BSY == 0 , DRDY == 1
698 if ((AltRegister
& (ATA_STSREG_DRDY
| ATA_STSREG_BSY
)) == ATA_STSREG_DRDY
) {
702 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_ERR
)) == ATA_STSREG_ERR
) {
703 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
705 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
711 // Stall for 100 microseconds.
713 MicroSecondDelay (100);
726 This function is used to poll for the BSY bit clear in the Status Register. BSY
727 is clear when the device is not busy. Every command must be sent after device is not busy.
729 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
730 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
731 @param Timeout The time to complete the command.
733 @retval EFI_SUCCESS BSY bit clear within the time out.
734 @retval EFI_TIMEOUT BSY bit not clear within the time out.
736 @note Read Status Register will clear interrupt status.
741 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
742 IN EFI_IDE_REGISTERS
*IdeRegisters
,
747 UINT8 StatusRegister
;
749 ASSERT (PciIo
!= NULL
);
750 ASSERT (IdeRegisters
!= NULL
);
752 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
754 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
756 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
761 // Stall for 100 microseconds.
763 MicroSecondDelay (100);
777 This function is used to poll for the BSY bit clear in the Status Register. BSY
778 is clear when the device is not busy. Every command must be sent after device is not busy.
780 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
781 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
782 @param Timeout The time to complete the command.
784 @retval EFI_SUCCESS BSY bit clear within the time out.
785 @retval EFI_TIMEOUT BSY bit not clear within the time out.
787 @note Read Status Register will clear interrupt status.
792 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
793 IN EFI_IDE_REGISTERS
*IdeRegisters
,
798 UINT8 AltStatusRegister
;
800 ASSERT (PciIo
!= NULL
);
801 ASSERT (IdeRegisters
!= NULL
);
803 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
805 AltStatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
807 if ((AltStatusRegister
& ATA_STSREG_BSY
) == 0x00) {
812 // Stall for 100 microseconds.
814 MicroSecondDelay (100);
828 Get IDE i/o port registers' base addresses by mode.
830 In 'Compatibility' mode, use fixed addresses.
831 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
834 The steps to get IDE i/o port registers' base addresses for each channel
837 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
838 controller's Configuration Space to determine the operating mode.
840 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
841 ___________________________________________
842 | | Command Block | Control Block |
843 | Channel | Registers | Registers |
844 |___________|_______________|_______________|
845 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
846 |___________|_______________|_______________|
847 | Secondary | 170h - 177h | 376h - 377h |
848 |___________|_______________|_______________|
850 Table 1. Compatibility resource mappings
852 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
853 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
854 ___________________________________________________
855 | | Command Block | Control Block |
856 | Channel | Registers | Registers |
857 |___________|___________________|___________________|
858 | Primary | BAR at offset 0x10| BAR at offset 0x14|
859 |___________|___________________|___________________|
860 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
861 |___________|___________________|___________________|
863 Table 2. BARs for Register Mapping
865 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
866 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
867 store the IDE i/o port registers' base addresses
869 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
870 @retval EFI_SUCCESS Get the Base address successfully
871 @retval Other Read the pci configureation data error
876 GetIdeRegisterIoAddr (
877 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
878 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
883 UINT16 CommandBlockBaseAddr
;
884 UINT16 ControlBlockBaseAddr
;
885 UINT16 BusMasterBaseAddr
;
887 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
888 return EFI_INVALID_PARAMETER
;
891 Status
= PciIo
->Pci
.Read (
899 if (EFI_ERROR (Status
)) {
903 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
905 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
906 CommandBlockBaseAddr
= 0x1f0;
907 ControlBlockBaseAddr
= 0x3f6;
910 // The BARs should be of IO type
912 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
913 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
914 return EFI_UNSUPPORTED
;
917 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
918 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
922 // Calculate IDE primary channel I/O register base address.
924 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
925 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
926 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
927 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
928 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
929 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
930 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
931 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
932 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
933 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
935 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
936 CommandBlockBaseAddr
= 0x170;
937 ControlBlockBaseAddr
= 0x376;
940 // The BARs should be of IO type
942 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
943 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
944 return EFI_UNSUPPORTED
;
947 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
948 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
952 // Calculate IDE secondary channel I/O register base address.
954 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
955 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
956 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
957 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
958 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
959 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
960 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
961 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
962 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
963 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
969 This function is used to implement the Soft Reset on the specified device. But,
970 the ATA Soft Reset mechanism is so strong a reset method that it will force
971 resetting on both devices connected to the same cable.
973 It is called by IdeBlkIoReset(), a interface function of Block
976 This function can also be used by the ATAPI device to perform reset when
977 ATAPI Reset command is failed.
979 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
980 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
981 @param Timeout The time to complete the command.
983 @retval EFI_SUCCESS Soft reset completes successfully.
984 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
986 @note The registers initial values after ATA soft reset are different
987 to the ATA device and ATAPI device.
992 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
993 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1001 // disable Interrupt and set SRST bit to initiate soft reset
1003 DeviceControl
= ATA_CTLREG_SRST
| ATA_CTLREG_IEN_L
;
1005 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1008 // SRST should assert for at least 5 us, we use 10 us for
1009 // better compatibility
1011 MicroSecondDelay (10);
1014 // Enable interrupt to support UDMA, and clear SRST bit
1017 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1020 // Wait for at least 10 ms to check BSY status, we use 10 ms
1021 // for better compatibility
1023 MicroSecondDelay (10000);
1026 // slave device needs at most 31ms to clear BSY
1028 if (WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
) == EFI_TIMEOUT
) {
1029 return EFI_DEVICE_ERROR
;
1036 Send ATA Ext command into device with NON_DATA protocol.
1038 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1039 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1040 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1041 @param Timeout The time to complete the command.
1043 @retval EFI_SUCCESS Reading succeed
1044 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1050 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1051 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1052 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1060 ASSERT (PciIo
!= NULL
);
1061 ASSERT (IdeRegisters
!= NULL
);
1062 ASSERT (AtaCommandBlock
!= NULL
);
1064 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1065 AtaCommand
= AtaCommandBlock
->AtaCommand
;
1067 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1068 if (EFI_ERROR (Status
)) {
1069 return EFI_DEVICE_ERROR
;
1073 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1075 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
1078 // set all the command parameters
1079 // Before write to all the following registers, BSY and DRQ must be 0.
1081 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
1082 if (EFI_ERROR (Status
)) {
1083 return EFI_DEVICE_ERROR
;
1087 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1089 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
1090 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
1093 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1095 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
1096 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
1099 // Fill the start LBA registers, which are also two-byte FIFO
1101 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
1102 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
1104 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
1105 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
1107 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
1108 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
1111 // Send command via Command Register
1113 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
1116 // Stall at least 400 microseconds.
1118 MicroSecondDelay (400);
1124 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
1126 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1128 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1129 @param[in, out] Buffer A pointer to the source buffer for the data.
1130 @param[in] ByteCount The length of the data.
1131 @param[in] Read Flag used to determine the data transfer direction.
1132 Read equals 1, means data transferred from device
1133 to host;Read equals 0, means data transferred
1134 from host to device.
1135 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1136 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1137 @param[in] Timeout The time to complete the command.
1138 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1139 used by non-blocking mode.
1141 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1142 @retval EFI_DEVICE_ERROR command sent failed.
1148 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1149 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1150 IN OUT VOID
*Buffer
,
1151 IN UINT64 ByteCount
,
1153 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1154 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1156 IN ATA_NONBLOCK_TASK
*Task
1164 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1165 return EFI_INVALID_PARAMETER
;
1169 // Issue ATA command
1171 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1172 if (EFI_ERROR (Status
)) {
1173 Status
= EFI_DEVICE_ERROR
;
1177 Buffer16
= (UINT16
*) Buffer
;
1180 // According to PIO data in protocol, host can perform a series of reads to
1181 // the data register after each time device set DRQ ready;
1182 // The data size of "a series of read" is command specific.
1183 // For most ATA command, data size received from device will not exceed
1184 // 1 sector, hence the data size for "a series of read" can be the whole data
1185 // size of one command request.
1186 // For ATA command such as Read Sector command, the data size of one ATA
1187 // command request is often larger than 1 sector, according to the
1188 // Read Sector command, the data size of "a series of read" is exactly 1
1190 // Here for simplification reason, we specify the data size for
1191 // "a series of read" to 1 sector (256 words) if data size of one ATA command
1192 // request is larger than 256 words.
1197 // used to record bytes of currently transfered data
1201 while (WordCount
< RShiftU64(ByteCount
, 1)) {
1203 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
1205 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1206 if (EFI_ERROR (Status
)) {
1207 Status
= EFI_DEVICE_ERROR
;
1212 // Get the byte count for one series of read
1214 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1215 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1219 IdeReadPortWMultiple (
1226 IdeWritePortWMultiple (
1234 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1235 if (EFI_ERROR (Status
)) {
1236 Status
= EFI_DEVICE_ERROR
;
1240 WordCount
+= Increment
;
1241 Buffer16
+= Increment
;
1244 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1245 if (EFI_ERROR (Status
)) {
1246 Status
= EFI_DEVICE_ERROR
;
1252 // Dump All Ide registers to ATA_STATUS_BLOCK
1254 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1257 // Not support the Non-blocking now,just do the blocking process.
1263 Send ATA command into device with NON_DATA protocol
1265 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1267 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1268 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1270 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1271 @param[in] Timeout The time to complete the command.
1272 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1273 used by non-blocking mode.
1275 @retval EFI_SUCCESS Reading succeed
1276 @retval EFI_ABORTED Command failed
1277 @retval EFI_DEVICE_ERROR Device status error.
1282 AtaNonDataCommandIn (
1283 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1284 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1285 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1286 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1288 IN ATA_NONBLOCK_TASK
*Task
1293 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1294 return EFI_INVALID_PARAMETER
;
1298 // Issue ATA command
1300 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1301 if (EFI_ERROR (Status
)) {
1302 Status
= EFI_DEVICE_ERROR
;
1307 // Wait for command completion
1309 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1310 if (EFI_ERROR (Status
)) {
1311 Status
= EFI_DEVICE_ERROR
;
1315 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1316 if (EFI_ERROR (Status
)) {
1317 Status
= EFI_DEVICE_ERROR
;
1323 // Dump All Ide registers to ATA_STATUS_BLOCK
1325 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1328 // Not support the Non-blocking now,just do the blocking process.
1334 Wait for memory to be set.
1336 @param[in] PciIo The PCI IO protocol instance.
1337 @param[in] PortNum The IDE Port number.
1339 @retval EFI_DEVICE_ERROR The memory is not set.
1340 @retval EFI_TIMEOUT The memory setting is time out.
1341 @retval EFI_SUCCESS The memory is correct set.
1346 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1350 UINT8 RegisterValue
;
1357 RegisterValue
= IdeReadPortB (PciIo
, PortNum
);
1359 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1360 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1361 Status
= EFI_DEVICE_ERROR
;
1365 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1366 Status
= EFI_SUCCESS
;
1367 DEBUG ((DEBUG_INFO
, "Task->RetryTimes = %x\n", Timeout
));
1371 // Stall for 1 milliseconds.
1373 MicroSecondDelay (1000);
1381 Check if the memory to be set.
1383 @param[in] PciIo The PCI IO protocol instance.
1384 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1385 used by non-blocking mode.
1386 @param[in] PortForBit The bit to be checked.
1388 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1389 @retval EFI_NOT_READY The memory is not set.
1390 @retval EFI_TIMEOUT The memory setting is time out.
1391 @retval EFI_SUCCESS The memory is correct set.
1396 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1397 IN ATA_NONBLOCK_TASK
*Task
,
1398 IN UINT16 PortForBit
1401 UINT8 RegisterValue
;
1404 RegisterValue
= IdeReadPortB(PciIo
, PortForBit
);
1406 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1407 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1408 return EFI_DEVICE_ERROR
;
1411 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1412 DEBUG ((DEBUG_INFO
, "Task->RetryTimes = %x\n", Task
->RetryTimes
));
1416 if (Task
->RetryTimes
== 0) {
1420 // The memory is not set.
1422 return EFI_NOT_READY
;
1427 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1429 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1431 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1432 @param[in] Read Flag used to determine the data transfer
1433 direction. Read equals 1, means data transferred
1434 from device to host;Read equals 0, means data
1435 transferred from host to device.
1436 @param[in] DataBuffer A pointer to the source buffer for the data.
1437 @param[in] DataLength The length of the data.
1438 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1439 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1440 @param[in] Timeout The time to complete the command.
1441 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1442 used by non-blocking mode.
1444 @retval EFI_SUCCESS the operation is successful.
1445 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1446 @retval EFI_UNSUPPORTED Unknown channel or operations command
1447 @retval EFI_DEVICE_ERROR Ata command execute failed
1453 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1454 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1456 IN VOID
*DataBuffer
,
1457 IN UINT64 DataLength
,
1458 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1459 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1461 IN ATA_NONBLOCK_TASK
*Task
1465 UINT16 IoPortForBmic
;
1466 UINT16 IoPortForBmis
;
1467 UINT16 IoPortForBmid
;
1470 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1472 EFI_ATA_DMA_PRD
*PrdBaseAddr
;
1473 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1476 UINT8 RegisterValue
;
1479 UINTN ByteRemaining
;
1480 UINT8 DeviceControl
;
1483 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1484 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1488 EFI_PCI_IO_PROTOCOL
*PciIo
;
1492 Status
= EFI_SUCCESS
;
1497 PciIo
= Instance
->PciIo
;
1499 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1500 return EFI_INVALID_PARAMETER
;
1504 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1506 // Delay 1ms to simulate the blocking time out checking.
1508 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1509 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1510 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1511 gBS
->RestoreTPL (OldTpl
);
1513 // Stall for 1 milliseconds.
1515 MicroSecondDelay (1000);
1519 // The data buffer should be even alignment
1521 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1522 return EFI_INVALID_PARAMETER
;
1526 // Set relevant IO Port address.
1528 IoPortForBmic
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1529 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1530 IoPortForBmid
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1533 // For Blocking mode, start the command.
1534 // For non-blocking mode, when the command is not started, start it, otherwise
1535 // go to check the status.
1537 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1539 // Calculate the number of PRD entry.
1540 // Every entry in PRD table can specify a 64K memory region.
1542 PrdTableNum
= (UINTN
)(RShiftU64(DataLength
, 16) + 1);
1545 // Make sure that the memory region of PRD table is not cross 64K boundary
1547 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1548 if (PrdTableSize
> 0x10000) {
1549 return EFI_INVALID_PARAMETER
;
1553 // Allocate buffer for PRD table initialization.
1555 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1556 Status
= PciIo
->AllocateBuffer (
1559 EfiBootServicesData
,
1561 (VOID
**)&PrdBaseAddr
,
1564 if (EFI_ERROR (Status
)) {
1565 return EFI_OUT_OF_RESOURCES
;
1568 ByteCount
= EFI_PAGES_TO_SIZE (PageCount
);
1569 Status
= PciIo
->Map (
1571 EfiPciIoOperationBusMasterCommonBuffer
,
1577 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (PageCount
))) {
1579 // If the data length actually mapped is not equal to the requested amount,
1580 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1581 // Can't handle this case.
1583 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1584 return EFI_OUT_OF_RESOURCES
;
1587 ZeroMem ((VOID
*) ((UINTN
) PrdBaseAddr
), ByteCount
);
1590 // Map the host address of DataBuffer to DMA master address.
1593 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1595 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1598 ByteCount
= (UINTN
)DataLength
;
1599 Status
= PciIo
->Map (
1607 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1608 PciIo
->Unmap (PciIo
, PrdTableMap
);
1609 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1610 return EFI_OUT_OF_RESOURCES
;
1614 // According to Ata spec, it requires the buffer address and size to be even.
1616 ASSERT ((BufferMapAddress
& 0x1) == 0);
1617 ASSERT ((ByteCount
& 0x1) == 0);
1620 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1622 ByteRemaining
= ByteCount
;
1623 TempPrdBaseAddr
= PrdBaseAddr
;
1624 while (ByteRemaining
!= 0) {
1625 if (ByteRemaining
<= 0x10000) {
1626 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1627 TempPrdBaseAddr
->ByteCount
= (UINT16
) ByteRemaining
;
1628 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1632 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1633 TempPrdBaseAddr
->ByteCount
= (UINT16
) 0x0;
1635 ByteRemaining
-= 0x10000;
1636 BufferMapAddress
+= 0x10000;
1641 // Start to enable the DMA operation
1643 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1644 AtaCommand
= AtaCommandBlock
->AtaCommand
;
1646 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1649 // Enable interrupt to support UDMA
1652 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1655 // Read BMIS register and clear ERROR and INTR bit
1657 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmis
);
1658 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1659 IdeWritePortB(PciIo
, IoPortForBmis
, RegisterValue
);
1662 // Set the base address to BMID register
1664 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1667 // Set BMIC register to identify the operation direction
1669 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1671 RegisterValue
|= BMIC_NREAD
;
1673 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1675 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1678 // Issue ATA command
1680 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1682 if (EFI_ERROR (Status
)) {
1683 Status
= EFI_DEVICE_ERROR
;
1688 // Set START bit of BMIC register
1690 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1691 RegisterValue
|= BMIC_START
;
1692 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1696 // Max transfer number of sectors for one command is 65536(32Mbyte),
1697 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1698 // So set the variable Count to 2000, for about 2 second Timeout time.
1700 Task
->RetryTimes
= 2000;
1701 Task
->Map
= BufferMap
;
1702 Task
->TableMap
= PrdTableMap
;
1703 Task
->MapBaseAddress
= PrdBaseAddr
;
1704 Task
->PageCount
= PageCount
;
1705 Task
->IsStart
= TRUE
;
1710 // Check the INTERRUPT and ERROR bit of BMIS
1711 // Max transfer number of sectors for one command is 65536(32Mbyte),
1712 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1713 // So set the variable Count to 2000, for about 2 second Timeout time.
1716 Status
= AtaUdmStatusCheck (PciIo
, Task
, IoPortForBmis
);
1718 Status
= AtaUdmStatusWait (PciIo
, IoPortForBmis
);
1722 // For blocking mode, clear registers and free buffers.
1723 // For non blocking mode, when the related registers have been set or time
1724 // out, or a error has been happened, it needs to clear the register and free
1727 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1729 // Read BMIS register and clear ERROR and INTR bit
1731 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1732 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1733 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1736 // Read Status Register of IDE device to clear interrupt
1738 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1741 // Clear START bit of BMIC register
1743 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1744 RegisterValue
&= ~((UINT8
) BMIC_START
);
1745 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1748 // Disable interrupt of Select device
1750 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1751 DeviceControl
|= ATA_CTLREG_IEN_L
;
1752 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1754 // Stall for 10 milliseconds.
1756 MicroSecondDelay (10000);
1762 // Free all allocated resource
1764 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1766 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1767 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1768 PciIo
->Unmap (PciIo
, Task
->Map
);
1770 PciIo
->Unmap (PciIo
, PrdTableMap
);
1771 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1772 PciIo
->Unmap (PciIo
, BufferMap
);
1776 // Dump All Ide registers to ATA_STATUS_BLOCK
1778 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1785 This function reads the pending data in the device.
1787 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1788 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1790 @retval EFI_SUCCESS Successfully read.
1791 @retval EFI_NOT_READY The BSY is set avoiding reading.
1796 AtaPacketReadPendingData (
1797 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1798 IN EFI_IDE_REGISTERS
*IdeRegisters
1802 UINT16 TempWordBuffer
;
1804 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1805 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1806 return EFI_NOT_READY
;
1809 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1810 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1811 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1812 IdeReadPortWMultiple (
1818 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1825 This function is called by AtaPacketCommandExecute().
1826 It is used to transfer data between host and device. The data direction is specified
1827 by the fourth parameter.
1829 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1830 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1831 @param Buffer Buffer contained data transferred between host and device.
1832 @param ByteCount Data size in byte unit of the buffer.
1833 @param Read Flag used to determine the data transfer direction.
1834 Read equals 1, means data transferred from device to host;
1835 Read equals 0, means data transferred from host to device.
1836 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer.
1838 @retval EFI_SUCCESS data is transferred successfully.
1839 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1843 AtaPacketReadWrite (
1844 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1845 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1846 IN OUT VOID
*Buffer
,
1847 IN UINT64 ByteCount
,
1852 UINT32 RequiredWordCount
;
1853 UINT32 ActualWordCount
;
1859 // No data transfer is premitted.
1861 if (ByteCount
== 0) {
1866 RequiredWordCount
= (UINT32
)RShiftU64(ByteCount
, 1);
1868 // ActuralWordCount means the word count of data really transferred.
1870 ActualWordCount
= 0;
1872 while (ActualWordCount
< RequiredWordCount
) {
1874 // before each data transfer stream, the host should poll DRQ bit ready,
1875 // to see whether indicates device is ready to transfer data.
1877 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1878 if (EFI_ERROR (Status
)) {
1879 return CheckStatusRegister (PciIo
, IdeRegisters
);
1883 // get current data transfer size from Cylinder Registers.
1885 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1886 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1887 WordCount
= WordCount
& 0xffff;
1890 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1893 IdeReadPortWMultiple (
1900 IdeWritePortWMultiple (
1909 // read status register to check whether error happens.
1911 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1912 if (EFI_ERROR (Status
)) {
1913 return EFI_DEVICE_ERROR
;
1916 PtrBuffer
+= WordCount
;
1917 ActualWordCount
+= WordCount
;
1922 // In the case where the drive wants to send more data than we need to read,
1923 // the DRQ bit will be set and cause delays from DRQClear2().
1924 // We need to read data from the drive until it clears DRQ so we can move on.
1926 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1930 // read status register to check whether error happens.
1932 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1933 if (EFI_ERROR (Status
)) {
1934 return EFI_DEVICE_ERROR
;
1938 // After data transfer is completed, normally, DRQ bit should clear.
1940 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
1941 if (EFI_ERROR (Status
)) {
1942 return EFI_DEVICE_ERROR
;
1949 Sumbit ATAPI request sense command.
1951 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1952 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1953 store the IDE i/o port registers' base addresses
1954 @param[in] Channel The channel number of device.
1955 @param[in] Device The device number of device.
1956 @param[in] SenseData A pointer to store sense data.
1957 @param[in] SenseDataLength The sense data length.
1958 @param[in] Timeout The timeout value to execute this cmd.
1960 @retval EFI_SUCCESS Send out the ATAPI packet command successfully.
1961 @retval EFI_DEVICE_ERROR The device failed to send data.
1966 AtaPacketRequestSense (
1967 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1968 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1972 IN UINT8 SenseDataLength
,
1976 EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET Packet
;
1980 ZeroMem (&Packet
, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
));
1983 Cdb
[0] = ATA_CMD_REQUEST_SENSE
;
1984 Cdb
[4] = SenseDataLength
;
1986 Packet
.Timeout
= Timeout
;
1988 Packet
.CdbLength
= 12;
1989 Packet
.DataDirection
= EFI_EXT_SCSI_DATA_DIRECTION_READ
;
1990 Packet
.InDataBuffer
= SenseData
;
1991 Packet
.InTransferLength
= SenseDataLength
;
1993 Status
= AtaPacketCommandExecute (PciIo
, IdeRegisters
, Channel
, Device
, &Packet
);
1999 This function is used to send out ATAPI commands conforms to the Packet Command
2000 with PIO Data In Protocol.
2002 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
2003 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
2004 store the IDE i/o port registers' base addresses
2005 @param[in] Channel The channel number of device.
2006 @param[in] Device The device number of device.
2007 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
2009 @retval EFI_SUCCESS send out the ATAPI packet command successfully
2010 and device sends data successfully.
2011 @retval EFI_DEVICE_ERROR the device failed to send data.
2016 AtaPacketCommandExecute (
2017 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
2018 IN EFI_IDE_REGISTERS
*IdeRegisters
,
2021 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
2024 EFI_STATUS PacketCommandStatus
;
2025 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2028 UINT8 PacketCommand
[12];
2030 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2033 // Fill ATAPI Command Packet according to CDB.
2034 // For Atapi cmd, its length should be less than or equal to 12 bytes.
2036 if (Packet
->CdbLength
> 12) {
2037 return EFI_INVALID_PARAMETER
;
2040 ZeroMem (PacketCommand
, 12);
2041 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
2046 AtaCommandBlock
.AtaFeatures
= 0x00;
2048 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
2049 // determine how many data should be transferred.
2051 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
2052 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
2053 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
2054 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
2056 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
2058 // Disable interrupt
2060 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
2063 // Issue ATA PACKET command firstly
2065 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
2066 if (EFI_ERROR (Status
)) {
2070 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
2071 if (EFI_ERROR (Status
)) {
2076 // Send out ATAPI command packet
2078 for (Count
= 0; Count
< 6; Count
++) {
2079 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
2081 // Stall for 10 microseconds.
2083 MicroSecondDelay (10);
2087 // Read/Write the data of ATAPI Command
2089 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
2090 PacketCommandStatus
= AtaPacketReadWrite (
2093 Packet
->InDataBuffer
,
2094 Packet
->InTransferLength
,
2099 PacketCommandStatus
= AtaPacketReadWrite (
2102 Packet
->OutDataBuffer
,
2103 Packet
->OutTransferLength
,
2109 if (!EFI_ERROR (PacketCommandStatus
)) {
2110 return PacketCommandStatus
;
2114 // Return SenseData if PacketCommandStatus matches
2115 // the following return codes.
2117 if ((PacketCommandStatus
== EFI_BAD_BUFFER_SIZE
) ||
2118 (PacketCommandStatus
== EFI_DEVICE_ERROR
) ||
2119 (PacketCommandStatus
== EFI_TIMEOUT
)) {
2122 // avoid submit request sense command continuously.
2124 if ((Packet
->SenseData
== NULL
) || (((UINT8
*)Packet
->Cdb
)[0] == ATA_CMD_REQUEST_SENSE
)) {
2125 return PacketCommandStatus
;
2128 AtaPacketRequestSense (
2134 Packet
->SenseDataLength
,
2139 return PacketCommandStatus
;
2144 Set the calculated Best transfer mode to a detected device.
2146 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2147 @param Channel The channel number of device.
2148 @param Device The device number of device.
2149 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
2150 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2152 @retval EFI_SUCCESS Set transfer mode successfully.
2153 @retval EFI_DEVICE_ERROR Set transfer mode failed.
2154 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2159 SetDeviceTransferMode (
2160 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2163 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
2164 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2168 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2170 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2172 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
2173 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2174 AtaCommandBlock
.AtaFeatures
= 0x03;
2175 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
2178 // Send SET FEATURE command (sub command 0x03) to set pio mode.
2180 Status
= AtaNonDataCommandIn (
2182 &Instance
->IdeRegisters
[Channel
],
2193 Set drive parameters for devices not support PACKETS command.
2195 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2196 @param Channel The channel number of device.
2197 @param Device The device number of device.
2198 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
2199 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2201 @retval EFI_SUCCESS Set drive parameter successfully.
2202 @retval EFI_DEVICE_ERROR Set drive parameter failed.
2203 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2208 SetDriveParameters (
2209 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2212 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
2213 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2218 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2220 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2222 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
2223 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
2224 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) + DriveParameters
->Heads
);
2227 // Send Init drive parameters
2229 Status
= AtaNonDataCommandIn (
2231 &Instance
->IdeRegisters
[Channel
],
2239 // Send Set Multiple parameters
2241 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
2242 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2243 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2245 Status
= AtaNonDataCommandIn (
2247 &Instance
->IdeRegisters
[Channel
],
2258 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2260 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2261 @param Channel The channel number of device.
2262 @param Device The device number of device.
2263 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2265 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2266 @retval Others Fail to get return status data.
2271 IdeAtaSmartReturnStatusCheck (
2272 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2275 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2279 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2283 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2285 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2286 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2287 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2288 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2289 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2292 // Send S.M.A.R.T Read Return Status command to device
2294 Status
= AtaNonDataCommandIn (
2296 &Instance
->IdeRegisters
[Channel
],
2303 if (EFI_ERROR (Status
)) {
2304 return EFI_DEVICE_ERROR
;
2307 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2308 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2310 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2312 // The threshold exceeded condition is not detected by the device
2314 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2316 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2318 // The threshold exceeded condition is detected by the device
2320 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2327 Enable SMART command of the disk if supported.
2329 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2330 @param Channel The channel number of device.
2331 @param Device The device number of device.
2332 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2333 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2338 IdeAtaSmartSupport (
2339 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2342 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2343 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2347 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2350 // Detect if the device supports S.M.A.R.T.
2352 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2354 // S.M.A.R.T is not supported by the device
2356 DEBUG ((EFI_D_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2357 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2360 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2362 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2364 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2366 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2367 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2368 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2369 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2370 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2373 // Send S.M.A.R.T Enable command to device
2375 Status
= AtaNonDataCommandIn (
2377 &Instance
->IdeRegisters
[Channel
],
2384 if (!EFI_ERROR (Status
)) {
2386 // Send S.M.A.R.T AutoSave command to device
2388 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2390 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2391 AtaCommandBlock
.AtaFeatures
= 0xD2;
2392 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2393 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2394 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2395 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2397 Status
= AtaNonDataCommandIn (
2399 &Instance
->IdeRegisters
[Channel
],
2405 if (!EFI_ERROR (Status
)) {
2406 Status
= IdeAtaSmartReturnStatusCheck (
2416 DEBUG ((EFI_D_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2417 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2426 Sends out an ATA Identify Command to the specified device.
2428 This function is called by DiscoverIdeDevice() during its device
2429 identification. It sends out the ATA Identify Command to the
2430 specified device. Only ATA device responses to this command. If
2431 the command succeeds, it returns the Identify data structure which
2432 contains information about the device. This function extracts the
2433 information it needs to fill the IDE_BLK_IO_DEV data structure,
2434 including device type, media block size, media capacity, and etc.
2436 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2437 @param Channel The channel number of device.
2438 @param Device The device number of device.
2439 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2440 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2442 @retval EFI_SUCCESS Identify ATA device successfully.
2443 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2444 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2450 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2453 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2454 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2458 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2460 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2462 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2463 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2465 Status
= AtaPioDataInOut (
2467 &Instance
->IdeRegisters
[Channel
],
2469 sizeof (EFI_IDENTIFY_DATA
),
2481 This function is called by DiscoverIdeDevice() during its device
2483 Its main purpose is to get enough information for the device media
2484 to fill in the Media data structure of the Block I/O Protocol interface.
2486 There are 5 steps to reach such objective:
2487 1. Sends out the ATAPI Identify Command to the specified device.
2488 Only ATAPI device responses to this command. If the command succeeds,
2489 it returns the Identify data structure which filled with information
2490 about the device. Since the ATAPI device contains removable media,
2491 the only meaningful information is the device module name.
2492 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2493 This command will return inquiry data of the device, which contains
2494 the device type information.
2495 3. Allocate sense data space for future use. We don't detect the media
2496 presence here to improvement boot performance, especially when CD
2497 media is present. The media detection will be performed just before
2498 each BLK_IO read/write
2500 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2501 @param Channel The channel number of device.
2502 @param Device The device number of device.
2503 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2504 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2506 @retval EFI_SUCCESS Identify ATAPI device successfully.
2507 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2508 is not supported by this IDE driver.
2509 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2515 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2518 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2519 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2523 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2525 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2527 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2528 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2531 // Send ATAPI Identify Command to get IDENTIFY data.
2533 Status
= AtaPioDataInOut (
2535 &Instance
->IdeRegisters
[Channel
],
2537 sizeof (EFI_IDENTIFY_DATA
),
2550 This function is used for detect whether the IDE device exists in the
2551 specified Channel as the specified Device Number.
2553 There is two IDE channels: one is Primary Channel, the other is
2554 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2555 Different channel has different register group.
2557 On each IDE channel, at most two IDE devices attach,
2558 one is called Device 0 (Master device), the other is called Device 1
2559 (Slave device). The devices on the same channel co-use the same register
2560 group, so before sending out a command for a specified device via command
2561 register, it is a must to select the current device to accept the command
2562 by set the device number in the Head/Device Register.
2564 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2565 @param IdeChannel The channel number of device.
2567 @retval EFI_SUCCESS successfully detects device.
2568 @retval other any failure during detection process will return this value.
2573 DetectAndConfigIdeDevice (
2574 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2579 UINT8 SectorCountReg
;
2583 EFI_ATA_DEVICE_TYPE DeviceType
;
2585 EFI_IDE_REGISTERS
*IdeRegisters
;
2586 EFI_IDENTIFY_DATA Buffer
;
2588 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2589 EFI_PCI_IO_PROTOCOL
*PciIo
;
2591 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2592 EFI_ATA_TRANSFER_MODE TransferMode
;
2593 EFI_ATA_DRIVE_PARMS DriveParameters
;
2595 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2596 IdeInit
= Instance
->IdeControllerInit
;
2597 PciIo
= Instance
->PciIo
;
2599 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2601 // Send ATA Device Execut Diagnostic command.
2602 // This command should work no matter DRDY is ready or not
2604 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2606 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2607 if (EFI_ERROR (Status
)) {
2608 DEBUG((EFI_D_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2613 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2615 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2617 // Stall for 1 milliseconds.
2619 MicroSecondDelay (1000);
2621 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2622 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2623 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2624 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2627 // Refer to ATA/ATAPI 4 Spec, section 9.1
2629 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2630 DeviceType
= EfiIdeHarddisk
;
2631 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2632 DeviceType
= EfiIdeCdrom
;
2638 // Send IDENTIFY cmd to the device to test if it is really attached.
2640 if (DeviceType
== EfiIdeHarddisk
) {
2641 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2643 // if identifying ata device is failure, then try to send identify packet cmd.
2645 if (EFI_ERROR (Status
)) {
2646 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2648 DeviceType
= EfiIdeCdrom
;
2649 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2652 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2654 // if identifying atapi device is failure, then try to send identify cmd.
2656 if (EFI_ERROR (Status
)) {
2657 DeviceType
= EfiIdeHarddisk
;
2658 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2662 if (EFI_ERROR (Status
)) {
2664 // No device is found at this port
2669 DEBUG ((EFI_D_INFO
, "[%a] channel [%a] [%a] device\n",
2670 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2671 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2673 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2675 if (DeviceType
== EfiIdeHarddisk
) {
2676 IdeAtaSmartSupport (
2686 // Submit identify data to IDE controller init driver
2688 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2691 // Now start to config ide device parameter and transfer mode.
2693 Status
= IdeInit
->CalculateMode (
2699 if (EFI_ERROR (Status
)) {
2700 DEBUG ((EFI_D_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2705 // Set best supported PIO mode on this IDE device
2707 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2708 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2710 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2713 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2715 if (SupportedModes
->ExtModeCount
== 0){
2716 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2718 if (EFI_ERROR (Status
)) {
2719 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2725 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2726 // be set together. Only one DMA mode can be set to a device. If setting
2727 // DMA mode operation fails, we can continue moving on because we only use
2728 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2730 if (SupportedModes
->UdmaMode
.Valid
) {
2731 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2732 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2733 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2735 if (EFI_ERROR (Status
)) {
2736 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2739 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2740 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2741 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2742 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2744 if (EFI_ERROR (Status
)) {
2745 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2751 // Set Parameters for the device:
2753 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2755 if (DeviceType
== EfiIdeHarddisk
) {
2757 // Init driver parameters
2759 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2760 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2761 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2763 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2767 // Set IDE controller Timing Blocks in the PCI Configuration Space
2769 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2772 // IDE controller and IDE device timing is configured successfully.
2773 // Now insert the device into device list.
2775 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2776 if (EFI_ERROR (Status
)) {
2780 if (DeviceType
== EfiIdeHarddisk
) {
2781 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2789 Initialize ATA host controller at IDE mode.
2791 The function is designed to initialize ATA host controller.
2793 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2798 IdeModeInitialization (
2799 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2804 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2805 EFI_PCI_IO_PROTOCOL
*PciIo
;
2808 BOOLEAN ChannelEnabled
;
2811 IdeInit
= Instance
->IdeControllerInit
;
2812 PciIo
= Instance
->PciIo
;
2813 EnumAll
= IdeInit
->EnumAll
;
2814 Channel
= IdeInit
->ChannelCount
;
2817 // Obtain IDE IO port registers' base addresses
2819 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2820 if (EFI_ERROR (Status
)) {
2824 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2825 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2828 // now obtain channel information fron IdeControllerInit protocol.
2830 Status
= IdeInit
->GetChannelInfo (
2836 if (EFI_ERROR (Status
)) {
2837 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
2841 if (!ChannelEnabled
) {
2845 ASSERT (MaxDevices
<= 2);
2847 // Now inform the IDE Controller Init Module.
2849 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2852 // No reset channel function implemented.
2854 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2857 // Now inform the IDE Controller Init Module.
2859 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2862 // Detect all attached ATA devices and set the transfer mode for each device.
2864 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2868 // All configurations done! Notify IdeController to do post initialization
2869 // work such as saving IDE controller PCI settings for S3 resume
2871 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);