2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "AtaAtapiPassThru.h"
18 read a one-byte data from a IDE port.
20 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
21 @param Port The IDE Port number
23 @return the one-byte data read from IDE port
28 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
34 ASSERT (PciIo
!= NULL
);
38 // perform 1-byte data read from register
43 EFI_PCI_IO_PASS_THROUGH_BAR
,
52 write a 1-byte data to a specific IDE port.
54 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
55 @param Port The IDE port to be writen
56 @param Data The data to write to the port
61 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
66 ASSERT (PciIo
!= NULL
);
69 // perform 1-byte data write to register
74 EFI_PCI_IO_PASS_THROUGH_BAR
,
82 write a 1-word data to a specific IDE port.
84 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
85 @param Port The IDE port to be writen
86 @param Data The data to write to the port
91 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
96 ASSERT (PciIo
!= NULL
);
99 // perform 1-word data write to register
104 EFI_PCI_IO_PASS_THROUGH_BAR
,
112 write a 2-word data to a specific IDE port.
114 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
115 @param Port The IDE port to be writen
116 @param Data The data to write to the port
121 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
126 ASSERT (PciIo
!= NULL
);
129 // perform 2-word data write to register
134 EFI_PCI_IO_PASS_THROUGH_BAR
,
142 Write multiple words of data to the IDE data port.
143 Call the IO abstraction once to do the complete read,
144 not one word at a time
146 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
147 @param Port IO port to read
148 @param Count No. of UINT16's to read
149 @param Buffer Pointer to the data buffer for read
154 IdeWritePortWMultiple (
155 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
161 ASSERT (PciIo
!= NULL
);
162 ASSERT (Buffer
!= NULL
);
165 // perform UINT16 data write to the FIFO
169 EfiPciIoWidthFifoUint16
,
170 EFI_PCI_IO_PASS_THROUGH_BAR
,
179 Reads multiple words of data from the IDE data port.
180 Call the IO abstraction once to do the complete read,
181 not one word at a time
183 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
184 @param Port IO port to read
185 @param Count Number of UINT16's to read
186 @param Buffer Pointer to the data buffer for read
191 IdeReadPortWMultiple (
192 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
198 ASSERT (PciIo
!= NULL
);
199 ASSERT (Buffer
!= NULL
);
202 // Perform UINT16 data read from FIFO
206 EfiPciIoWidthFifoUint16
,
207 EFI_PCI_IO_PASS_THROUGH_BAR
,
216 This function is used to analyze the Status Register and print out
217 some debug information and if there is ERR bit set in the Status
218 Register, the Error Register's value is also be parsed and print out.
220 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
221 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
222 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
227 DumpAllIdeRegisters (
228 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
229 IN EFI_IDE_REGISTERS
*IdeRegisters
,
230 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
233 EFI_ATA_STATUS_BLOCK StatusBlock
;
235 ASSERT (PciIo
!= NULL
);
236 ASSERT (IdeRegisters
!= NULL
);
238 ZeroMem (&StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
240 StatusBlock
.AtaStatus
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
241 StatusBlock
.AtaError
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
242 StatusBlock
.AtaSectorCount
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
243 StatusBlock
.AtaSectorCountExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
244 StatusBlock
.AtaSectorNumber
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
245 StatusBlock
.AtaSectorNumberExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
246 StatusBlock
.AtaCylinderLow
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
247 StatusBlock
.AtaCylinderLowExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
248 StatusBlock
.AtaCylinderHigh
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
249 StatusBlock
.AtaCylinderHighExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
250 StatusBlock
.AtaDeviceHead
= IdeReadPortB (PciIo
, IdeRegisters
->Head
);
252 if (AtaStatusBlock
!= NULL
) {
254 // Dump the content of all ATA registers.
256 CopyMem (AtaStatusBlock
, &StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
260 if ((StatusBlock
.AtaStatus
& ATA_STSREG_DWF
) != 0) {
261 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock
.AtaStatus
));
264 if ((StatusBlock
.AtaStatus
& ATA_STSREG_CORR
) != 0) {
265 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock
.AtaStatus
));
268 if ((StatusBlock
.AtaStatus
& ATA_STSREG_ERR
) != 0) {
269 if ((StatusBlock
.AtaError
& ATA_ERRREG_BBK
) != 0) {
270 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock
.AtaError
));
273 if ((StatusBlock
.AtaError
& ATA_ERRREG_UNC
) != 0) {
274 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock
.AtaError
));
277 if ((StatusBlock
.AtaError
& ATA_ERRREG_MC
) != 0) {
278 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock
.AtaError
));
281 if ((StatusBlock
.AtaError
& ATA_ERRREG_ABRT
) != 0) {
282 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock
.AtaError
));
285 if ((StatusBlock
.AtaError
& ATA_ERRREG_TK0NF
) != 0) {
286 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock
.AtaError
));
289 if ((StatusBlock
.AtaError
& ATA_ERRREG_AMNF
) != 0) {
290 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock
.AtaError
));
297 This function is used to analyze the Status Register at the condition that BSY is zero.
298 if there is ERR bit set in the Status Register, then return error.
300 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
301 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
303 @retval EFI_SUCCESS No err information in the Status Register.
304 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
309 CheckStatusRegister (
310 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
311 IN EFI_IDE_REGISTERS
*IdeRegisters
314 UINT8 StatusRegister
;
316 ASSERT (PciIo
!= NULL
);
317 ASSERT (IdeRegisters
!= NULL
);
319 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
321 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
322 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
325 return EFI_DEVICE_ERROR
;
332 This function is used to poll for the DRQ bit clear in the Status
333 Register. DRQ is cleared when the device is finished transferring data.
334 So this function is called after data transfer is finished.
336 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
337 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
338 @param Timeout The time to complete the command, uses 100ns as a unit.
340 @retval EFI_SUCCESS DRQ bit clear within the time out.
342 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
345 Read Status Register will clear interrupt status.
351 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
352 IN EFI_IDE_REGISTERS
*IdeRegisters
,
357 UINT8 StatusRegister
;
359 ASSERT (PciIo
!= NULL
);
360 ASSERT (IdeRegisters
!= NULL
);
362 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
364 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
367 // Wait for BSY == 0, then judge if DRQ is clear
369 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
370 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
371 return EFI_DEVICE_ERROR
;
378 // Stall for 100 microseconds.
380 MicroSecondDelay (100);
389 This function is used to poll for the DRQ bit clear in the Alternate
390 Status Register. DRQ is cleared when the device is finished
391 transferring data. So this function is called after data transfer
394 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
395 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
396 @param Timeout The time to complete the command, uses 100ns as a unit.
398 @retval EFI_SUCCESS DRQ bit clear within the time out.
400 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
401 @note Read Alternate Status Register will not clear interrupt status.
407 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
408 IN EFI_IDE_REGISTERS
*IdeRegisters
,
415 ASSERT (PciIo
!= NULL
);
416 ASSERT (IdeRegisters
!= NULL
);
418 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
420 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
423 // Wait for BSY == 0, then judge if DRQ is clear
425 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
426 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
427 return EFI_DEVICE_ERROR
;
434 // Stall for 100 microseconds.
436 MicroSecondDelay (100);
446 This function is used to poll for the DRQ bit set in the
448 DRQ is set when the device is ready to transfer data. So this function
449 is called after the command is sent to the device and before required
452 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
453 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
454 @param Timeout The time to complete the command, uses 100ns as a unit.
456 @retval EFI_SUCCESS DRQ bit set within the time out.
457 @retval EFI_TIMEOUT DRQ bit not set within the time out.
458 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
460 @note Read Status Register will clear interrupt status.
466 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
467 IN EFI_IDE_REGISTERS
*IdeRegisters
,
472 UINT8 StatusRegister
;
475 ASSERT (PciIo
!= NULL
);
476 ASSERT (IdeRegisters
!= NULL
);
478 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
481 // Read Status Register will clear interrupt
483 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
486 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
488 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
489 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
490 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
492 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
495 return EFI_DEVICE_ERROR
;
498 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
501 return EFI_NOT_READY
;
506 // Stall for 100 microseconds.
508 MicroSecondDelay (100);
516 This function is used to poll for the DRQ bit set in the Alternate Status Register.
517 DRQ is set when the device is ready to transfer data. So this function is called after
518 the command is sent to the device and before required data is transferred.
520 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
521 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
522 @param Timeout The time to complete the command, uses 100ns as a unit.
524 @retval EFI_SUCCESS DRQ bit set within the time out.
525 @retval EFI_TIMEOUT DRQ bit not set within the time out.
526 @retval EFI_ABORTED DRQ bit not set caused by the command abort.
527 @note Read Alternate Status Register will not clear interrupt status.
533 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
534 IN EFI_IDE_REGISTERS
*IdeRegisters
,
542 ASSERT (PciIo
!= NULL
);
543 ASSERT (IdeRegisters
!= NULL
);
545 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
549 // Read Alternate Status Register will not clear interrupt status
551 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
553 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
555 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
556 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
557 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
559 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
562 return EFI_DEVICE_ERROR
;
565 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
568 return EFI_NOT_READY
;
573 // Stall for 100 microseconds.
575 MicroSecondDelay (100);
584 This function is used to poll for the DRDY bit set in the Status Register. DRDY
585 bit is set when the device is ready to accept command. Most ATA commands must be
586 sent after DRDY set except the ATAPI Packet Command.
588 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
589 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
590 @param Timeout The time to complete the command, uses 100ns as a unit.
592 @retval EFI_SUCCESS DRDY bit set within the time out.
593 @retval EFI_TIMEOUT DRDY bit not set within the time out.
595 @note Read Status Register will clear interrupt status.
600 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
601 IN EFI_IDE_REGISTERS
*IdeRegisters
,
606 UINT8 StatusRegister
;
609 ASSERT (PciIo
!= NULL
);
610 ASSERT (IdeRegisters
!= NULL
);
612 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
614 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
616 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
618 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
619 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
620 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
622 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
625 return EFI_DEVICE_ERROR
;
628 if ((StatusRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
631 return EFI_DEVICE_ERROR
;
636 // Stall for 100 microseconds.
638 MicroSecondDelay (100);
647 This function is used to poll for the DRDY bit set in the Alternate Status Register.
648 DRDY bit is set when the device is ready to accept command. Most ATA commands must
649 be sent after DRDY set except the ATAPI Packet Command.
651 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
652 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
653 @param Timeout The time to complete the command, uses 100ns as a unit.
655 @retval EFI_SUCCESS DRDY bit set within the time out.
656 @retval EFI_TIMEOUT DRDY bit not set within the time out.
658 @note Read Alternate Status Register will clear interrupt status.
664 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
665 IN EFI_IDE_REGISTERS
*IdeRegisters
,
673 ASSERT (PciIo
!= NULL
);
674 ASSERT (IdeRegisters
!= NULL
);
676 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
678 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
680 // Wait for BSY == 0, then judge if DRDY is set or ERR is set
682 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
683 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
684 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
686 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
689 return EFI_DEVICE_ERROR
;
692 if ((AltRegister
& ATA_STSREG_DRDY
) == ATA_STSREG_DRDY
) {
695 return EFI_DEVICE_ERROR
;
700 // Stall for 100 microseconds.
702 MicroSecondDelay (100);
711 This function is used to poll for the BSY bit clear in the Status Register. BSY
712 is clear when the device is not busy. Every command must be sent after device is not busy.
714 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
715 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
716 @param Timeout The time to complete the command, uses 100ns as a unit.
718 @retval EFI_SUCCESS BSY bit clear within the time out.
719 @retval EFI_TIMEOUT BSY bit not clear within the time out.
721 @note Read Status Register will clear interrupt status.
726 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
727 IN EFI_IDE_REGISTERS
*IdeRegisters
,
732 UINT8 StatusRegister
;
734 ASSERT (PciIo
!= NULL
);
735 ASSERT (IdeRegisters
!= NULL
);
737 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
739 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
741 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
746 // Stall for 100 microseconds.
748 MicroSecondDelay (100);
758 This function is used to poll for the BSY bit clear in the Status Register. BSY
759 is clear when the device is not busy. Every command must be sent after device is not busy.
761 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
762 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
763 @param Timeout The time to complete the command, uses 100ns as a unit.
765 @retval EFI_SUCCESS BSY bit clear within the time out.
766 @retval EFI_TIMEOUT BSY bit not clear within the time out.
768 @note Read Status Register will clear interrupt status.
773 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
774 IN EFI_IDE_REGISTERS
*IdeRegisters
,
779 UINT8 AltStatusRegister
;
781 ASSERT (PciIo
!= NULL
);
782 ASSERT (IdeRegisters
!= NULL
);
784 Delay
= (UINT32
) (DivU64x32(Timeout
, 1000) + 1);
786 AltStatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
788 if ((AltStatusRegister
& ATA_STSREG_BSY
) == 0x00) {
793 // Stall for 100 microseconds.
795 MicroSecondDelay (100);
805 Get IDE i/o port registers' base addresses by mode.
807 In 'Compatibility' mode, use fixed addresses.
808 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
811 The steps to get IDE i/o port registers' base addresses for each channel
814 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
815 controller's Configuration Space to determine the operating mode.
817 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
818 ___________________________________________
819 | | Command Block | Control Block |
820 | Channel | Registers | Registers |
821 |___________|_______________|_______________|
822 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
823 |___________|_______________|_______________|
824 | Secondary | 170h - 177h | 376h - 377h |
825 |___________|_______________|_______________|
827 Table 1. Compatibility resource mappings
829 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
830 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
831 ___________________________________________________
832 | | Command Block | Control Block |
833 | Channel | Registers | Registers |
834 |___________|___________________|___________________|
835 | Primary | BAR at offset 0x10| BAR at offset 0x14|
836 |___________|___________________|___________________|
837 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
838 |___________|___________________|___________________|
840 Table 2. BARs for Register Mapping
842 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
843 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
844 store the IDE i/o port registers' base addresses
846 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
847 @retval EFI_SUCCESS Get the Base address successfully
848 @retval Other Read the pci configureation data error
853 GetIdeRegisterIoAddr (
854 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
855 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
860 UINT16 CommandBlockBaseAddr
;
861 UINT16 ControlBlockBaseAddr
;
862 UINT16 BusMasterBaseAddr
;
864 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
865 return EFI_INVALID_PARAMETER
;
868 Status
= PciIo
->Pci
.Read (
876 if (EFI_ERROR (Status
)) {
880 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
882 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
883 CommandBlockBaseAddr
= 0x1f0;
884 ControlBlockBaseAddr
= 0x3f6;
887 // The BARs should be of IO type
889 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
890 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
891 return EFI_UNSUPPORTED
;
894 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
895 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
899 // Calculate IDE primary channel I/O register base address.
901 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
902 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
903 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
904 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
905 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
906 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
907 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
908 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
909 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
910 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
912 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
913 CommandBlockBaseAddr
= 0x170;
914 ControlBlockBaseAddr
= 0x376;
917 // The BARs should be of IO type
919 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
920 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
921 return EFI_UNSUPPORTED
;
924 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
925 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
929 // Calculate IDE secondary channel I/O register base address.
931 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
932 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
933 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
934 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
935 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
936 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
937 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
938 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
939 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
940 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
946 This function is used to implement the Soft Reset on the specified device. But,
947 the ATA Soft Reset mechanism is so strong a reset method that it will force
948 resetting on both devices connected to the same cable.
950 It is called by IdeBlkIoReset(), a interface function of Block
953 This function can also be used by the ATAPI device to perform reset when
954 ATAPI Reset command is failed.
956 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
957 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
958 @param Timeout The time to complete the command, uses 100ns as a unit.
960 @retval EFI_SUCCESS Soft reset completes successfully.
961 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
963 @note The registers initial values after ATA soft reset are different
964 to the ATA device and ATAPI device.
969 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
970 IN EFI_IDE_REGISTERS
*IdeRegisters
,
978 // disable Interrupt and set SRST bit to initiate soft reset
980 DeviceControl
= ATA_CTLREG_SRST
| ATA_CTLREG_IEN_L
;
982 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
985 // SRST should assert for at least 5 us, we use 10 us for
986 // better compatibility
988 MicroSecondDelay (10);
991 // Enable interrupt to support UDMA, and clear SRST bit
994 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
997 // Wait for at least 10 ms to check BSY status, we use 10 ms
998 // for better compatibility
1000 MicroSecondDelay (10000);
1003 // slave device needs at most 31ms to clear BSY
1005 if (WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
) == EFI_TIMEOUT
) {
1006 return EFI_DEVICE_ERROR
;
1013 Send ATA Ext command into device with NON_DATA protocol.
1015 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1016 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1017 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1018 @param Timeout The time to complete the command, uses 100ns as a unit.
1020 @retval EFI_SUCCESS Reading succeed
1021 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1027 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1028 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1029 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1037 ASSERT (PciIo
!= NULL
);
1038 ASSERT (IdeRegisters
!= NULL
);
1039 ASSERT (AtaCommandBlock
!= NULL
);
1041 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1042 AtaCommand
= AtaCommandBlock
->AtaCommand
;
1044 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1045 if (EFI_ERROR (Status
)) {
1046 return EFI_DEVICE_ERROR
;
1050 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1052 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
1055 // set all the command parameters
1056 // Before write to all the following registers, BSY and DRQ must be 0.
1058 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
1059 if (EFI_ERROR (Status
)) {
1060 return EFI_DEVICE_ERROR
;
1064 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1066 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
1067 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
1070 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1072 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
1073 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
1076 // Fill the start LBA registers, which are also two-byte FIFO
1078 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
1079 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
1081 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
1082 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
1084 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
1085 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
1088 // Send command via Command Register
1090 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
1093 // Stall at least 400 microseconds.
1095 MicroSecondDelay (400);
1101 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
1103 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1105 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1106 @param[in, out] Buffer A pointer to the source buffer for the data.
1107 @param[in] ByteCount The length of the data.
1108 @param[in] Read Flag used to determine the data transfer direction.
1109 Read equals 1, means data transferred from device
1110 to host;Read equals 0, means data transferred
1111 from host to device.
1112 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1113 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1114 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1115 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1116 used by non-blocking mode.
1118 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1119 @retval EFI_DEVICE_ERROR command sent failed.
1125 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1126 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1127 IN OUT VOID
*Buffer
,
1128 IN UINT64 ByteCount
,
1130 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1131 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1133 IN ATA_NONBLOCK_TASK
*Task
1141 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1142 return EFI_INVALID_PARAMETER
;
1146 // Issue ATA command
1148 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1149 if (EFI_ERROR (Status
)) {
1150 Status
= EFI_DEVICE_ERROR
;
1154 Buffer16
= (UINT16
*) Buffer
;
1157 // According to PIO data in protocol, host can perform a series of reads to
1158 // the data register after each time device set DRQ ready;
1159 // The data size of "a series of read" is command specific.
1160 // For most ATA command, data size received from device will not exceed
1161 // 1 sector, hence the data size for "a series of read" can be the whole data
1162 // size of one command request.
1163 // For ATA command such as Read Sector command, the data size of one ATA
1164 // command request is often larger than 1 sector, according to the
1165 // Read Sector command, the data size of "a series of read" is exactly 1
1167 // Here for simplification reason, we specify the data size for
1168 // "a series of read" to 1 sector (256 words) if data size of one ATA command
1169 // request is larger than 256 words.
1174 // used to record bytes of currently transfered data
1178 while (WordCount
< RShiftU64(ByteCount
, 1)) {
1180 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
1182 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1183 if (EFI_ERROR (Status
)) {
1184 Status
= EFI_DEVICE_ERROR
;
1189 // Get the byte count for one series of read
1191 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1192 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1196 IdeReadPortWMultiple (
1203 IdeWritePortWMultiple (
1211 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1212 if (EFI_ERROR (Status
)) {
1213 Status
= EFI_DEVICE_ERROR
;
1217 WordCount
+= Increment
;
1218 Buffer16
+= Increment
;
1221 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1222 if (EFI_ERROR (Status
)) {
1223 Status
= EFI_DEVICE_ERROR
;
1229 // Dump All Ide registers to ATA_STATUS_BLOCK
1231 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1234 // Not support the Non-blocking now,just do the blocking process.
1240 Send ATA command into device with NON_DATA protocol
1242 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1244 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1245 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1247 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1248 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1249 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1250 used by non-blocking mode.
1252 @retval EFI_SUCCESS Reading succeed
1253 @retval EFI_ABORTED Command failed
1254 @retval EFI_DEVICE_ERROR Device status error.
1259 AtaNonDataCommandIn (
1260 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1261 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1262 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1263 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1265 IN ATA_NONBLOCK_TASK
*Task
1270 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1271 return EFI_INVALID_PARAMETER
;
1275 // Issue ATA command
1277 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1278 if (EFI_ERROR (Status
)) {
1279 Status
= EFI_DEVICE_ERROR
;
1284 // Wait for command completion
1286 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1287 if (EFI_ERROR (Status
)) {
1288 Status
= EFI_DEVICE_ERROR
;
1292 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1293 if (EFI_ERROR (Status
)) {
1294 Status
= EFI_DEVICE_ERROR
;
1300 // Dump All Ide registers to ATA_STATUS_BLOCK
1302 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1305 // Not support the Non-blocking now,just do the blocking process.
1311 Wait for memory to be set.
1313 @param[in] PciIo The PCI IO protocol instance.
1314 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1316 @retval EFI_DEVICE_ERROR The memory is not set.
1317 @retval EFI_TIMEOUT The memory setting is time out.
1318 @retval EFI_SUCCESS The memory is correct set.
1323 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1324 IN EFI_IDE_REGISTERS
*IdeRegisters
1327 UINT8 RegisterValue
;
1329 UINT16 IoPortForBmis
;
1335 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1336 if (EFI_ERROR (Status
)) {
1337 Status
= EFI_DEVICE_ERROR
;
1341 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1342 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1343 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1344 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1345 Status
= EFI_DEVICE_ERROR
;
1349 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1350 Status
= EFI_SUCCESS
;
1354 // Stall for 1 milliseconds.
1356 MicroSecondDelay (1000);
1364 Check if the memory to be set.
1366 @param[in] PciIo The PCI IO protocol instance.
1367 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1368 used by non-blocking mode.
1369 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1371 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1372 @retval EFI_NOT_READY The memory is not set.
1373 @retval EFI_TIMEOUT The memory setting is time out.
1374 @retval EFI_SUCCESS The memory is correct set.
1379 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1380 IN ATA_NONBLOCK_TASK
*Task
,
1381 IN EFI_IDE_REGISTERS
*IdeRegisters
1384 UINT8 RegisterValue
;
1385 UINT16 IoPortForBmis
;
1390 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1391 if (EFI_ERROR (Status
)) {
1392 return EFI_DEVICE_ERROR
;
1395 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1396 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1398 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1399 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1400 return EFI_DEVICE_ERROR
;
1403 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1407 if (Task
->RetryTimes
== 0) {
1411 // The memory is not set.
1413 return EFI_NOT_READY
;
1418 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1420 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1422 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1423 @param[in] Read Flag used to determine the data transfer
1424 direction. Read equals 1, means data transferred
1425 from device to host;Read equals 0, means data
1426 transferred from host to device.
1427 @param[in] DataBuffer A pointer to the source buffer for the data.
1428 @param[in] DataLength The length of the data.
1429 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1430 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1431 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1432 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1433 used by non-blocking mode.
1435 @retval EFI_SUCCESS the operation is successful.
1436 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1437 @retval EFI_UNSUPPORTED Unknown channel or operations command
1438 @retval EFI_DEVICE_ERROR Ata command execute failed
1444 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1445 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1447 IN VOID
*DataBuffer
,
1448 IN UINT64 DataLength
,
1449 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1450 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1452 IN ATA_NONBLOCK_TASK
*Task
1456 UINT16 IoPortForBmic
;
1457 UINT16 IoPortForBmis
;
1458 UINT16 IoPortForBmid
;
1461 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1463 EFI_ATA_DMA_PRD
*PrdBaseAddr
;
1464 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1467 UINT8 RegisterValue
;
1470 UINTN ByteRemaining
;
1471 UINT8 DeviceControl
;
1474 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1475 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1478 EFI_PCI_IO_PROTOCOL
*PciIo
;
1482 Status
= EFI_SUCCESS
;
1487 PciIo
= Instance
->PciIo
;
1489 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1490 return EFI_INVALID_PARAMETER
;
1494 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1496 // Delay 1ms to simulate the blocking time out checking.
1498 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1499 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1500 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1502 // Stall for 1 milliseconds.
1504 MicroSecondDelay (1000);
1506 gBS
->RestoreTPL (OldTpl
);
1509 // The data buffer should be even alignment
1511 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1512 return EFI_INVALID_PARAMETER
;
1516 // Set relevant IO Port address.
1518 IoPortForBmic
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1519 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1520 IoPortForBmid
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1523 // For Blocking mode, start the command.
1524 // For non-blocking mode, when the command is not started, start it, otherwise
1525 // go to check the status.
1527 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1529 // Calculate the number of PRD entry.
1530 // Every entry in PRD table can specify a 64K memory region.
1532 PrdTableNum
= (UINTN
)(RShiftU64(DataLength
, 16) + 1);
1535 // Make sure that the memory region of PRD table is not cross 64K boundary
1537 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1538 if (PrdTableSize
> 0x10000) {
1539 return EFI_INVALID_PARAMETER
;
1543 // Allocate buffer for PRD table initialization.
1545 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1546 Status
= PciIo
->AllocateBuffer (
1549 EfiBootServicesData
,
1551 (VOID
**)&PrdBaseAddr
,
1554 if (EFI_ERROR (Status
)) {
1555 return EFI_OUT_OF_RESOURCES
;
1558 ByteCount
= EFI_PAGES_TO_SIZE (PageCount
);
1559 Status
= PciIo
->Map (
1561 EfiPciIoOperationBusMasterCommonBuffer
,
1567 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (PageCount
))) {
1569 // If the data length actually mapped is not equal to the requested amount,
1570 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1571 // Can't handle this case.
1573 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1574 return EFI_OUT_OF_RESOURCES
;
1577 ZeroMem ((VOID
*) ((UINTN
) PrdBaseAddr
), ByteCount
);
1580 // Map the host address of DataBuffer to DMA master address.
1583 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1585 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1588 ByteCount
= (UINTN
)DataLength
;
1589 Status
= PciIo
->Map (
1597 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1598 PciIo
->Unmap (PciIo
, PrdTableMap
);
1599 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1600 return EFI_OUT_OF_RESOURCES
;
1604 // According to Ata spec, it requires the buffer address and size to be even.
1606 ASSERT ((BufferMapAddress
& 0x1) == 0);
1607 ASSERT ((ByteCount
& 0x1) == 0);
1610 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1612 ByteRemaining
= ByteCount
;
1613 TempPrdBaseAddr
= PrdBaseAddr
;
1614 while (ByteRemaining
!= 0) {
1615 if (ByteRemaining
<= 0x10000) {
1616 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1617 TempPrdBaseAddr
->ByteCount
= (UINT16
) ByteRemaining
;
1618 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1622 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1623 TempPrdBaseAddr
->ByteCount
= (UINT16
) 0x0;
1625 ByteRemaining
-= 0x10000;
1626 BufferMapAddress
+= 0x10000;
1631 // Start to enable the DMA operation
1633 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1635 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1638 // Enable interrupt to support UDMA
1641 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1644 // Read BMIS register and clear ERROR and INTR bit
1646 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmis
);
1647 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1648 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1651 // Set the base address to BMID register
1653 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1656 // Set BMIC register to identify the operation direction
1658 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1660 RegisterValue
|= BMIC_NREAD
;
1662 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1664 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1668 // Max transfer number of sectors for one command is 65536(32Mbyte),
1669 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1670 // So set the variable Count to 2000, for about 2 second Timeout time.
1672 Task
->RetryTimes
= 2000;
1673 Task
->Map
= BufferMap
;
1674 Task
->TableMap
= PrdTableMap
;
1675 Task
->MapBaseAddress
= PrdBaseAddr
;
1676 Task
->PageCount
= PageCount
;
1677 Task
->IsStart
= TRUE
;
1681 // Issue ATA command
1683 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1685 if (EFI_ERROR (Status
)) {
1686 Status
= EFI_DEVICE_ERROR
;
1690 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1691 if (EFI_ERROR (Status
)) {
1692 Status
= EFI_DEVICE_ERROR
;
1696 // Set START bit of BMIC register
1698 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1699 RegisterValue
|= BMIC_START
;
1700 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1705 // Check the INTERRUPT and ERROR bit of BMIS
1706 // Max transfer number of sectors for one command is 65536(32Mbyte),
1707 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1708 // So set the variable Count to 2000, for about 2 second Timeout time.
1711 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1713 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
);
1717 // For blocking mode, clear registers and free buffers.
1718 // For non blocking mode, when the related registers have been set or time
1719 // out, or a error has been happened, it needs to clear the register and free
1722 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1724 // Read BMIS register and clear ERROR and INTR bit
1726 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1727 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1728 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1731 // Read Status Register of IDE device to clear interrupt
1733 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1736 // Clear START bit of BMIC register
1738 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1739 RegisterValue
&= ~((UINT8
) BMIC_START
);
1740 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1743 // Disable interrupt of Select device
1745 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1746 DeviceControl
|= ATA_CTLREG_IEN_L
;
1747 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1749 // Stall for 10 milliseconds.
1751 MicroSecondDelay (10000);
1757 // Free all allocated resource
1759 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1761 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1762 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1763 PciIo
->Unmap (PciIo
, Task
->Map
);
1765 PciIo
->Unmap (PciIo
, PrdTableMap
);
1766 PciIo
->FreeBuffer (PciIo
, PageCount
, PrdBaseAddr
);
1767 PciIo
->Unmap (PciIo
, BufferMap
);
1771 // Dump All Ide registers to ATA_STATUS_BLOCK
1773 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1780 This function reads the pending data in the device.
1782 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1783 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1785 @retval EFI_SUCCESS Successfully read.
1786 @retval EFI_NOT_READY The BSY is set avoiding reading.
1791 AtaPacketReadPendingData (
1792 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1793 IN EFI_IDE_REGISTERS
*IdeRegisters
1797 UINT16 TempWordBuffer
;
1799 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1800 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1801 return EFI_NOT_READY
;
1804 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1805 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1806 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1807 IdeReadPortWMultiple (
1813 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1820 This function is called by AtaPacketCommandExecute().
1821 It is used to transfer data between host and device. The data direction is specified
1822 by the fourth parameter.
1824 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1825 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1826 @param Buffer Buffer contained data transferred between host and device.
1827 @param ByteCount Data size in byte unit of the buffer.
1828 @param Read Flag used to determine the data transfer direction.
1829 Read equals 1, means data transferred from device to host;
1830 Read equals 0, means data transferred from host to device.
1831 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1832 , uses 100ns as a unit.
1834 @retval EFI_SUCCESS data is transferred successfully.
1835 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1839 AtaPacketReadWrite (
1840 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1841 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1842 IN OUT VOID
*Buffer
,
1843 IN UINT64 ByteCount
,
1848 UINT32 RequiredWordCount
;
1849 UINT32 ActualWordCount
;
1855 // No data transfer is premitted.
1857 if (ByteCount
== 0) {
1862 RequiredWordCount
= (UINT32
)RShiftU64(ByteCount
, 1);
1864 // ActuralWordCount means the word count of data really transferred.
1866 ActualWordCount
= 0;
1868 while (ActualWordCount
< RequiredWordCount
) {
1870 // before each data transfer stream, the host should poll DRQ bit ready,
1871 // to see whether indicates device is ready to transfer data.
1873 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1874 if (EFI_ERROR (Status
)) {
1875 return CheckStatusRegister (PciIo
, IdeRegisters
);
1879 // get current data transfer size from Cylinder Registers.
1881 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1882 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1883 WordCount
= WordCount
& 0xffff;
1886 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1889 IdeReadPortWMultiple (
1896 IdeWritePortWMultiple (
1905 // read status register to check whether error happens.
1907 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1908 if (EFI_ERROR (Status
)) {
1909 return EFI_DEVICE_ERROR
;
1912 PtrBuffer
+= WordCount
;
1913 ActualWordCount
+= WordCount
;
1918 // In the case where the drive wants to send more data than we need to read,
1919 // the DRQ bit will be set and cause delays from DRQClear2().
1920 // We need to read data from the drive until it clears DRQ so we can move on.
1922 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1926 // read status register to check whether error happens.
1928 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1929 if (EFI_ERROR (Status
)) {
1930 return EFI_DEVICE_ERROR
;
1934 // After data transfer is completed, normally, DRQ bit should clear.
1936 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1937 if (EFI_ERROR (Status
)) {
1938 return EFI_DEVICE_ERROR
;
1945 This function is used to send out ATAPI commands conforms to the Packet Command
1946 with PIO Data In Protocol.
1948 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1949 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1950 store the IDE i/o port registers' base addresses
1951 @param[in] Channel The channel number of device.
1952 @param[in] Device The device number of device.
1953 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
1955 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1956 and device sends data successfully.
1957 @retval EFI_DEVICE_ERROR the device failed to send data.
1962 AtaPacketCommandExecute (
1963 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1964 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1967 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
1970 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1973 UINT8 PacketCommand
[12];
1975 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1978 // Fill ATAPI Command Packet according to CDB.
1979 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1981 if (Packet
->CdbLength
> 12) {
1982 return EFI_INVALID_PARAMETER
;
1985 ZeroMem (PacketCommand
, 12);
1986 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
1991 AtaCommandBlock
.AtaFeatures
= 0x00;
1993 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1994 // determine how many data should be transferred.
1996 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
1997 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
1998 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
1999 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
2001 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
2003 // Disable interrupt
2005 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
2008 // Issue ATA PACKET command firstly
2010 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
2011 if (EFI_ERROR (Status
)) {
2015 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
2016 if (EFI_ERROR (Status
)) {
2021 // Send out ATAPI command packet
2023 for (Count
= 0; Count
< 6; Count
++) {
2024 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
2026 // Stall for 10 microseconds.
2028 MicroSecondDelay (10);
2032 // Read/Write the data of ATAPI Command
2034 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
2035 Status
= AtaPacketReadWrite (
2038 Packet
->InDataBuffer
,
2039 Packet
->InTransferLength
,
2044 Status
= AtaPacketReadWrite (
2047 Packet
->OutDataBuffer
,
2048 Packet
->OutTransferLength
,
2059 Set the calculated Best transfer mode to a detected device.
2061 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2062 @param Channel The channel number of device.
2063 @param Device The device number of device.
2064 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
2065 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2067 @retval EFI_SUCCESS Set transfer mode successfully.
2068 @retval EFI_DEVICE_ERROR Set transfer mode failed.
2069 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2074 SetDeviceTransferMode (
2075 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2078 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
2079 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2083 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2085 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2087 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
2088 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2089 AtaCommandBlock
.AtaFeatures
= 0x03;
2090 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
2093 // Send SET FEATURE command (sub command 0x03) to set pio mode.
2095 Status
= AtaNonDataCommandIn (
2097 &Instance
->IdeRegisters
[Channel
],
2108 Set drive parameters for devices not support PACKETS command.
2110 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2111 @param Channel The channel number of device.
2112 @param Device The device number of device.
2113 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
2114 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2116 @retval EFI_SUCCESS Set drive parameter successfully.
2117 @retval EFI_DEVICE_ERROR Set drive parameter failed.
2118 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2123 SetDriveParameters (
2124 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2127 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
2128 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2132 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2134 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2136 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
2137 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
2138 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) + DriveParameters
->Heads
);
2141 // Send Init drive parameters
2143 Status
= AtaNonDataCommandIn (
2145 &Instance
->IdeRegisters
[Channel
],
2153 // Send Set Multiple parameters
2155 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
2156 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2157 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2159 Status
= AtaNonDataCommandIn (
2161 &Instance
->IdeRegisters
[Channel
],
2172 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2174 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2175 @param Channel The channel number of device.
2176 @param Device The device number of device.
2177 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2179 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2180 @retval Others Fail to get return status data.
2185 IdeAtaSmartReturnStatusCheck (
2186 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2189 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2193 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2197 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2199 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2200 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2201 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2202 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2203 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2206 // Send S.M.A.R.T Read Return Status command to device
2208 Status
= AtaNonDataCommandIn (
2210 &Instance
->IdeRegisters
[Channel
],
2217 if (EFI_ERROR (Status
)) {
2218 REPORT_STATUS_CODE (
2219 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2220 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
2222 return EFI_DEVICE_ERROR
;
2225 REPORT_STATUS_CODE (
2227 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
2230 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2231 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2233 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2235 // The threshold exceeded condition is not detected by the device
2237 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2238 REPORT_STATUS_CODE (
2240 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
2242 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2244 // The threshold exceeded condition is detected by the device
2246 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2247 REPORT_STATUS_CODE (
2249 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
2257 Enable SMART command of the disk if supported.
2259 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2260 @param Channel The channel number of device.
2261 @param Device The device number of device.
2262 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2263 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2268 IdeAtaSmartSupport (
2269 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2272 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2273 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2277 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2280 // Detect if the device supports S.M.A.R.T.
2282 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2284 // S.M.A.R.T is not supported by the device
2286 DEBUG ((EFI_D_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2287 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2288 REPORT_STATUS_CODE (
2289 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2290 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2294 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2296 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2298 REPORT_STATUS_CODE (
2300 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2303 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2305 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2306 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
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 Enable command to device
2314 Status
= AtaNonDataCommandIn (
2316 &Instance
->IdeRegisters
[Channel
],
2323 if (!EFI_ERROR (Status
)) {
2325 // Send S.M.A.R.T AutoSave command to device
2327 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2329 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2330 AtaCommandBlock
.AtaFeatures
= 0xD2;
2331 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2332 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2333 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2334 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2336 Status
= AtaNonDataCommandIn (
2338 &Instance
->IdeRegisters
[Channel
],
2344 if (!EFI_ERROR (Status
)) {
2345 Status
= IdeAtaSmartReturnStatusCheck (
2355 DEBUG ((EFI_D_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2356 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2365 Sends out an ATA Identify Command to the specified device.
2367 This function is called by DiscoverIdeDevice() during its device
2368 identification. It sends out the ATA Identify Command to the
2369 specified device. Only ATA device responses to this command. If
2370 the command succeeds, it returns the Identify data structure which
2371 contains information about the device. This function extracts the
2372 information it needs to fill the IDE_BLK_IO_DEV data structure,
2373 including device type, media block size, media capacity, and etc.
2375 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2376 @param Channel The channel number of device.
2377 @param Device The device number of device.
2378 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2379 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2381 @retval EFI_SUCCESS Identify ATA device successfully.
2382 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2383 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2389 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2392 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2393 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2397 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2399 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2401 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2402 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2404 Status
= AtaPioDataInOut (
2406 &Instance
->IdeRegisters
[Channel
],
2408 sizeof (EFI_IDENTIFY_DATA
),
2420 This function is called by DiscoverIdeDevice() during its device
2422 Its main purpose is to get enough information for the device media
2423 to fill in the Media data structure of the Block I/O Protocol interface.
2425 There are 5 steps to reach such objective:
2426 1. Sends out the ATAPI Identify Command to the specified device.
2427 Only ATAPI device responses to this command. If the command succeeds,
2428 it returns the Identify data structure which filled with information
2429 about the device. Since the ATAPI device contains removable media,
2430 the only meaningful information is the device module name.
2431 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2432 This command will return inquiry data of the device, which contains
2433 the device type information.
2434 3. Allocate sense data space for future use. We don't detect the media
2435 presence here to improvement boot performance, especially when CD
2436 media is present. The media detection will be performed just before
2437 each BLK_IO read/write
2439 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2440 @param Channel The channel number of device.
2441 @param Device The device number of device.
2442 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2443 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2445 @retval EFI_SUCCESS Identify ATAPI device successfully.
2446 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2447 is not supported by this IDE driver.
2448 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2454 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2457 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2458 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2462 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2464 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2466 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2467 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2470 // Send ATAPI Identify Command to get IDENTIFY data.
2472 Status
= AtaPioDataInOut (
2474 &Instance
->IdeRegisters
[Channel
],
2476 sizeof (EFI_IDENTIFY_DATA
),
2489 This function is used for detect whether the IDE device exists in the
2490 specified Channel as the specified Device Number.
2492 There is two IDE channels: one is Primary Channel, the other is
2493 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2494 Different channel has different register group.
2496 On each IDE channel, at most two IDE devices attach,
2497 one is called Device 0 (Master device), the other is called Device 1
2498 (Slave device). The devices on the same channel co-use the same register
2499 group, so before sending out a command for a specified device via command
2500 register, it is a must to select the current device to accept the command
2501 by set the device number in the Head/Device Register.
2503 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2504 @param IdeChannel The channel number of device.
2506 @retval EFI_SUCCESS successfully detects device.
2507 @retval other any failure during detection process will return this value.
2512 DetectAndConfigIdeDevice (
2513 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2518 UINT8 SectorCountReg
;
2522 EFI_ATA_DEVICE_TYPE DeviceType
;
2524 EFI_IDE_REGISTERS
*IdeRegisters
;
2525 EFI_IDENTIFY_DATA Buffer
;
2527 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2528 EFI_PCI_IO_PROTOCOL
*PciIo
;
2530 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2531 EFI_ATA_TRANSFER_MODE TransferMode
;
2532 EFI_ATA_DRIVE_PARMS DriveParameters
;
2534 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2535 IdeInit
= Instance
->IdeControllerInit
;
2536 PciIo
= Instance
->PciIo
;
2538 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2540 // Send ATA Device Execut Diagnostic command.
2541 // This command should work no matter DRDY is ready or not
2543 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2545 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2546 if (EFI_ERROR (Status
)) {
2547 DEBUG((EFI_D_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2552 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2554 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2556 // Stall for 1 milliseconds.
2558 MicroSecondDelay (1000);
2560 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2561 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2562 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2563 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2566 // Refer to ATA/ATAPI 4 Spec, section 9.1
2568 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2569 DeviceType
= EfiIdeHarddisk
;
2570 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2571 DeviceType
= EfiIdeCdrom
;
2577 // Send IDENTIFY cmd to the device to test if it is really attached.
2579 if (DeviceType
== EfiIdeHarddisk
) {
2580 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2582 // if identifying ata device is failure, then try to send identify packet cmd.
2584 if (EFI_ERROR (Status
)) {
2585 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2587 DeviceType
= EfiIdeCdrom
;
2588 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2591 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2593 // if identifying atapi device is failure, then try to send identify cmd.
2595 if (EFI_ERROR (Status
)) {
2596 DeviceType
= EfiIdeHarddisk
;
2597 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2601 if (EFI_ERROR (Status
)) {
2603 // No device is found at this port
2608 DEBUG ((EFI_D_INFO
, "[%a] channel [%a] [%a] device\n",
2609 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2610 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2612 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2614 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2615 IdeAtaSmartSupport (
2625 // Submit identify data to IDE controller init driver
2627 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2630 // Now start to config ide device parameter and transfer mode.
2632 Status
= IdeInit
->CalculateMode (
2638 if (EFI_ERROR (Status
)) {
2639 DEBUG ((EFI_D_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2644 // Set best supported PIO mode on this IDE device
2646 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2647 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2649 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2652 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2654 if (SupportedModes
->ExtModeCount
== 0){
2655 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2657 if (EFI_ERROR (Status
)) {
2658 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2664 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2665 // be set together. Only one DMA mode can be set to a device. If setting
2666 // DMA mode operation fails, we can continue moving on because we only use
2667 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2669 if (SupportedModes
->UdmaMode
.Valid
) {
2670 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2671 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2672 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2674 if (EFI_ERROR (Status
)) {
2675 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2678 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2679 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2680 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2681 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2683 if (EFI_ERROR (Status
)) {
2684 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2690 // Set Parameters for the device:
2692 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2694 if (DeviceType
== EfiIdeHarddisk
) {
2696 // Init driver parameters
2698 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2699 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2700 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2702 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2706 // Set IDE controller Timing Blocks in the PCI Configuration Space
2708 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2711 // IDE controller and IDE device timing is configured successfully.
2712 // Now insert the device into device list.
2714 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2715 if (EFI_ERROR (Status
)) {
2719 if (DeviceType
== EfiIdeHarddisk
) {
2720 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2728 Initialize ATA host controller at IDE mode.
2730 The function is designed to initialize ATA host controller.
2732 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2737 IdeModeInitialization (
2738 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2742 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2743 EFI_PCI_IO_PROTOCOL
*PciIo
;
2746 BOOLEAN ChannelEnabled
;
2749 IdeInit
= Instance
->IdeControllerInit
;
2750 PciIo
= Instance
->PciIo
;
2751 Channel
= IdeInit
->ChannelCount
;
2754 // Obtain IDE IO port registers' base addresses
2756 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2757 if (EFI_ERROR (Status
)) {
2761 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2762 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2765 // now obtain channel information fron IdeControllerInit protocol.
2767 Status
= IdeInit
->GetChannelInfo (
2773 if (EFI_ERROR (Status
)) {
2774 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
2778 if (!ChannelEnabled
) {
2782 ASSERT (MaxDevices
<= 2);
2784 // Now inform the IDE Controller Init Module.
2786 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2789 // No reset channel function implemented.
2791 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2794 // Now inform the IDE Controller Init Module.
2796 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2799 // Detect all attached ATA devices and set the transfer mode for each device.
2801 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2805 // All configurations done! Notify IdeController to do post initialization
2806 // work such as saving IDE controller PCI settings for S3 resume
2808 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);