2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "AtaAtapiPassThru.h"
12 read a one-byte data from a IDE port.
14 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
15 @param Port The IDE Port number
17 @return the one-byte data read from IDE port
22 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
28 ASSERT (PciIo
!= NULL
);
32 // perform 1-byte data read from register
37 EFI_PCI_IO_PASS_THROUGH_BAR
,
46 write a 1-byte data to a specific IDE port.
48 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
49 @param Port The IDE port to be written
50 @param Data The data to write to the port
55 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
60 ASSERT (PciIo
!= NULL
);
63 // perform 1-byte data write to register
68 EFI_PCI_IO_PASS_THROUGH_BAR
,
76 write a 1-word data to a specific IDE port.
78 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
79 @param Port The IDE port to be written
80 @param Data The data to write to the port
85 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
90 ASSERT (PciIo
!= NULL
);
93 // perform 1-word data write to register
98 EFI_PCI_IO_PASS_THROUGH_BAR
,
106 write a 2-word data to a specific IDE port.
108 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
109 @param Port The IDE port to be written
110 @param Data The data to write to the port
115 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
120 ASSERT (PciIo
!= NULL
);
123 // perform 2-word data write to register
128 EFI_PCI_IO_PASS_THROUGH_BAR
,
136 Write multiple words of data to the IDE data port.
137 Call the IO abstraction once to do the complete read,
138 not one word at a time
140 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
141 @param Port IO port to read
142 @param Count No. of UINT16's to read
143 @param Buffer Pointer to the data buffer for read
148 IdeWritePortWMultiple (
149 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
155 ASSERT (PciIo
!= NULL
);
156 ASSERT (Buffer
!= NULL
);
159 // perform UINT16 data write to the FIFO
163 EfiPciIoWidthFifoUint16
,
164 EFI_PCI_IO_PASS_THROUGH_BAR
,
172 Reads multiple words of data from the IDE data port.
173 Call the IO abstraction once to do the complete read,
174 not one word at a time
176 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
177 @param Port IO port to read
178 @param Count Number of UINT16's to read
179 @param Buffer Pointer to the data buffer for read
184 IdeReadPortWMultiple (
185 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
191 ASSERT (PciIo
!= NULL
);
192 ASSERT (Buffer
!= NULL
);
195 // Perform UINT16 data read from FIFO
199 EfiPciIoWidthFifoUint16
,
200 EFI_PCI_IO_PASS_THROUGH_BAR
,
208 This function is used to analyze the Status Register and print out
209 some debug information and if there is ERR bit set in the Status
210 Register, the Error Register's value is also be parsed and print out.
212 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
213 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
214 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
219 DumpAllIdeRegisters (
220 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
221 IN EFI_IDE_REGISTERS
*IdeRegisters
,
222 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
225 EFI_ATA_STATUS_BLOCK StatusBlock
;
227 ASSERT (PciIo
!= NULL
);
228 ASSERT (IdeRegisters
!= NULL
);
230 ZeroMem (&StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
232 StatusBlock
.AtaStatus
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
233 StatusBlock
.AtaError
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
234 StatusBlock
.AtaSectorCount
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
235 StatusBlock
.AtaSectorCountExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
236 StatusBlock
.AtaSectorNumber
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
237 StatusBlock
.AtaSectorNumberExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
238 StatusBlock
.AtaCylinderLow
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
239 StatusBlock
.AtaCylinderLowExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
240 StatusBlock
.AtaCylinderHigh
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
241 StatusBlock
.AtaCylinderHighExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
242 StatusBlock
.AtaDeviceHead
= IdeReadPortB (PciIo
, IdeRegisters
->Head
);
244 if (AtaStatusBlock
!= NULL
) {
246 // Dump the content of all ATA registers.
248 CopyMem (AtaStatusBlock
, &StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
252 if ((StatusBlock
.AtaStatus
& ATA_STSREG_DWF
) != 0) {
253 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock
.AtaStatus
));
256 if ((StatusBlock
.AtaStatus
& ATA_STSREG_CORR
) != 0) {
257 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock
.AtaStatus
));
260 if ((StatusBlock
.AtaStatus
& ATA_STSREG_ERR
) != 0) {
261 if ((StatusBlock
.AtaError
& ATA_ERRREG_BBK
) != 0) {
262 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock
.AtaError
));
265 if ((StatusBlock
.AtaError
& ATA_ERRREG_UNC
) != 0) {
266 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock
.AtaError
));
269 if ((StatusBlock
.AtaError
& ATA_ERRREG_MC
) != 0) {
270 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock
.AtaError
));
273 if ((StatusBlock
.AtaError
& ATA_ERRREG_ABRT
) != 0) {
274 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock
.AtaError
));
277 if ((StatusBlock
.AtaError
& ATA_ERRREG_TK0NF
) != 0) {
278 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock
.AtaError
));
281 if ((StatusBlock
.AtaError
& ATA_ERRREG_AMNF
) != 0) {
282 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock
.AtaError
));
290 This function is used to analyze the Status Register at the condition that BSY is zero.
291 if there is ERR bit set in the Status Register, then return error.
293 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
294 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
296 @retval EFI_SUCCESS No err information in the Status Register.
297 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
302 CheckStatusRegister (
303 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
304 IN EFI_IDE_REGISTERS
*IdeRegisters
307 UINT8 StatusRegister
;
309 ASSERT (PciIo
!= NULL
);
310 ASSERT (IdeRegisters
!= NULL
);
312 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
314 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
315 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
318 return EFI_DEVICE_ERROR
;
326 This function is used to poll for the DRQ bit clear in the Status
327 Register. DRQ is cleared when the device is finished transferring data.
328 So this function is called after data transfer is finished.
330 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
331 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
332 @param Timeout The time to complete the command, uses 100ns as a unit.
334 @retval EFI_SUCCESS DRQ bit clear within the time out.
336 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
339 Read Status Register will clear interrupt status.
345 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
346 IN EFI_IDE_REGISTERS
*IdeRegisters
,
351 UINT8 StatusRegister
;
352 BOOLEAN InfiniteWait
;
354 ASSERT (PciIo
!= NULL
);
355 ASSERT (IdeRegisters
!= NULL
);
360 InfiniteWait
= FALSE
;
363 Delay
= DivU64x32 (Timeout
, 1000) + 1;
365 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
368 // Wait for BSY == 0, then judge if DRQ is clear
370 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
371 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
372 return EFI_DEVICE_ERROR
;
379 // Stall for 100 microseconds.
381 MicroSecondDelay (100);
384 } while (InfiniteWait
|| (Delay
> 0));
390 This function is used to poll for the DRQ bit clear in the Alternate
391 Status Register. DRQ is cleared when the device is finished
392 transferring data. So this function is called after data transfer
395 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
396 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
397 @param Timeout The time to complete the command, uses 100ns as a unit.
399 @retval EFI_SUCCESS DRQ bit clear within the time out.
401 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
402 @note Read Alternate Status Register will not clear interrupt status.
408 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
409 IN EFI_IDE_REGISTERS
*IdeRegisters
,
415 BOOLEAN InfiniteWait
;
417 ASSERT (PciIo
!= NULL
);
418 ASSERT (IdeRegisters
!= NULL
);
423 InfiniteWait
= FALSE
;
426 Delay
= DivU64x32 (Timeout
, 1000) + 1;
428 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
431 // Wait for BSY == 0, then judge if DRQ is clear
433 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
434 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
435 return EFI_DEVICE_ERROR
;
442 // Stall for 100 microseconds.
444 MicroSecondDelay (100);
447 } while (InfiniteWait
|| (Delay
> 0));
453 This function is used to poll for the DRQ bit set in the
455 DRQ is set when the device is ready to transfer data. So this function
456 is called after the command is sent to the device and before required
459 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
460 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
461 @param Timeout The time to complete the command, uses 100ns as a unit.
463 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
466 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
468 @retval EFI_ABORTED Polling abandoned due to command abort.
470 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
472 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
473 reported "command complete" by clearing DRQ
476 @note Read Status Register will clear interrupt status.
482 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
483 IN EFI_IDE_REGISTERS
*IdeRegisters
,
488 UINT8 StatusRegister
;
490 BOOLEAN InfiniteWait
;
492 ASSERT (PciIo
!= NULL
);
493 ASSERT (IdeRegisters
!= NULL
);
498 InfiniteWait
= FALSE
;
501 Delay
= DivU64x32 (Timeout
, 1000) + 1;
504 // Read Status Register will clear interrupt
506 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
509 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
511 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
512 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
513 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
515 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
519 return EFI_DEVICE_ERROR
;
522 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
525 return EFI_NOT_READY
;
530 // Stall for 100 microseconds.
532 MicroSecondDelay (100);
535 } while (InfiniteWait
|| (Delay
> 0));
541 This function is used to poll for the DRQ bit set in the Alternate Status Register.
542 DRQ is set when the device is ready to transfer data. So this function is called after
543 the command is sent to the device and before required data is transferred.
545 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
546 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
547 @param Timeout The time to complete the command, uses 100ns as a unit.
549 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
552 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
554 @retval EFI_ABORTED Polling abandoned due to command abort.
556 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
558 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
559 reported "command complete" by clearing DRQ
562 @note Read Alternate Status Register will not clear interrupt status.
568 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
569 IN EFI_IDE_REGISTERS
*IdeRegisters
,
576 BOOLEAN InfiniteWait
;
578 ASSERT (PciIo
!= NULL
);
579 ASSERT (IdeRegisters
!= NULL
);
584 InfiniteWait
= FALSE
;
587 Delay
= DivU64x32 (Timeout
, 1000) + 1;
591 // Read Alternate Status Register will not clear interrupt status
593 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
595 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
597 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
598 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
599 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
601 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
605 return EFI_DEVICE_ERROR
;
608 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
611 return EFI_NOT_READY
;
616 // Stall for 100 microseconds.
618 MicroSecondDelay (100);
621 } while (InfiniteWait
|| (Delay
> 0));
627 This function is used to poll for the BSY bit clear in the Status Register. BSY
628 is clear when the device is not busy. Every command must be sent after device is not busy.
630 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
631 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
632 @param Timeout The time to complete the command, uses 100ns as a unit.
634 @retval EFI_SUCCESS BSY bit clear within the time out.
635 @retval EFI_TIMEOUT BSY bit not clear within the time out.
637 @note Read Status Register will clear interrupt status.
642 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
643 IN EFI_IDE_REGISTERS
*IdeRegisters
,
648 UINT8 StatusRegister
;
649 BOOLEAN InfiniteWait
;
651 ASSERT (PciIo
!= NULL
);
652 ASSERT (IdeRegisters
!= NULL
);
657 InfiniteWait
= FALSE
;
660 Delay
= DivU64x32 (Timeout
, 1000) + 1;
662 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
664 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
669 // Stall for 100 microseconds.
671 MicroSecondDelay (100);
674 } while (InfiniteWait
|| (Delay
> 0));
680 Get IDE i/o port registers' base addresses by mode.
682 In 'Compatibility' mode, use fixed addresses.
683 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
686 The steps to get IDE i/o port registers' base addresses for each channel
689 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
690 controller's Configuration Space to determine the operating mode.
692 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
693 ___________________________________________
694 | | Command Block | Control Block |
695 | Channel | Registers | Registers |
696 |___________|_______________|_______________|
697 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
698 |___________|_______________|_______________|
699 | Secondary | 170h - 177h | 376h - 377h |
700 |___________|_______________|_______________|
702 Table 1. Compatibility resource mappings
704 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
705 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
706 ___________________________________________________
707 | | Command Block | Control Block |
708 | Channel | Registers | Registers |
709 |___________|___________________|___________________|
710 | Primary | BAR at offset 0x10| BAR at offset 0x14|
711 |___________|___________________|___________________|
712 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
713 |___________|___________________|___________________|
715 Table 2. BARs for Register Mapping
717 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
718 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
719 store the IDE i/o port registers' base addresses
721 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
722 @retval EFI_SUCCESS Get the Base address successfully
723 @retval Other Read the pci configuration data error
728 GetIdeRegisterIoAddr (
729 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
730 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
735 UINT16 CommandBlockBaseAddr
;
736 UINT16 ControlBlockBaseAddr
;
737 UINT16 BusMasterBaseAddr
;
739 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
740 return EFI_INVALID_PARAMETER
;
743 Status
= PciIo
->Pci
.Read (
751 if (EFI_ERROR (Status
)) {
755 BusMasterBaseAddr
= (UINT16
)((PciData
.Device
.Bar
[4] & 0x0000fff0));
757 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
758 CommandBlockBaseAddr
= 0x1f0;
759 ControlBlockBaseAddr
= 0x3f6;
762 // The BARs should be of IO type
764 if (((PciData
.Device
.Bar
[0] & BIT0
) == 0) ||
765 ((PciData
.Device
.Bar
[1] & BIT0
) == 0))
767 return EFI_UNSUPPORTED
;
770 CommandBlockBaseAddr
= (UINT16
)(PciData
.Device
.Bar
[0] & 0x0000fff8);
771 ControlBlockBaseAddr
= (UINT16
)((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
775 // Calculate IDE primary channel I/O register base address.
777 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
778 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
)(CommandBlockBaseAddr
+ 0x01);
779 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
)(CommandBlockBaseAddr
+ 0x02);
780 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
)(CommandBlockBaseAddr
+ 0x03);
781 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
)(CommandBlockBaseAddr
+ 0x04);
782 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
)(CommandBlockBaseAddr
+ 0x05);
783 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
)(CommandBlockBaseAddr
+ 0x06);
784 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
)(CommandBlockBaseAddr
+ 0x07);
785 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
786 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
788 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
789 CommandBlockBaseAddr
= 0x170;
790 ControlBlockBaseAddr
= 0x376;
793 // The BARs should be of IO type
795 if (((PciData
.Device
.Bar
[2] & BIT0
) == 0) ||
796 ((PciData
.Device
.Bar
[3] & BIT0
) == 0))
798 return EFI_UNSUPPORTED
;
801 CommandBlockBaseAddr
= (UINT16
)(PciData
.Device
.Bar
[2] & 0x0000fff8);
802 ControlBlockBaseAddr
= (UINT16
)((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
806 // Calculate IDE secondary channel I/O register base address.
808 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
809 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
)(CommandBlockBaseAddr
+ 0x01);
810 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
)(CommandBlockBaseAddr
+ 0x02);
811 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
)(CommandBlockBaseAddr
+ 0x03);
812 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
)(CommandBlockBaseAddr
+ 0x04);
813 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
)(CommandBlockBaseAddr
+ 0x05);
814 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
)(CommandBlockBaseAddr
+ 0x06);
815 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
)(CommandBlockBaseAddr
+ 0x07);
816 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
817 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
)(BusMasterBaseAddr
+ 0x8);
823 Send ATA Ext command into device with NON_DATA protocol.
825 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
826 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
827 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
828 @param Timeout The time to complete the command, uses 100ns as a unit.
830 @retval EFI_SUCCESS Reading succeed
831 @retval EFI_DEVICE_ERROR Error executing commands on this device.
837 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
838 IN EFI_IDE_REGISTERS
*IdeRegisters
,
839 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
847 ASSERT (PciIo
!= NULL
);
848 ASSERT (IdeRegisters
!= NULL
);
849 ASSERT (AtaCommandBlock
!= NULL
);
851 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
852 AtaCommand
= AtaCommandBlock
->AtaCommand
;
854 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
855 if (EFI_ERROR (Status
)) {
856 return EFI_DEVICE_ERROR
;
860 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
862 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
865 // set all the command parameters
866 // Before write to all the following registers, BSY and DRQ must be 0.
868 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
869 if (EFI_ERROR (Status
)) {
870 return EFI_DEVICE_ERROR
;
874 // Fill the feature register, which is a two-byte FIFO. Need write twice.
876 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
877 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
880 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
882 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
883 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
886 // Fill the start LBA registers, which are also two-byte FIFO
888 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
889 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
891 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
892 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
894 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
895 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
898 // Send command via Command Register
900 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
903 // Stall at least 400 microseconds.
905 MicroSecondDelay (400);
911 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
913 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
915 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
916 @param[in, out] Buffer A pointer to the source buffer for the data.
917 @param[in] ByteCount The length of the data.
918 @param[in] Read Flag used to determine the data transfer direction.
919 Read equals 1, means data transferred from device
920 to host;Read equals 0, means data transferred
922 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
923 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
924 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
925 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
926 used by non-blocking mode.
928 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
929 @retval EFI_DEVICE_ERROR command sent failed.
935 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
936 IN EFI_IDE_REGISTERS
*IdeRegisters
,
940 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
941 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
943 IN ATA_NONBLOCK_TASK
*Task
951 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
952 return EFI_INVALID_PARAMETER
;
958 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
959 if (EFI_ERROR (Status
)) {
960 Status
= EFI_DEVICE_ERROR
;
964 Buffer16
= (UINT16
*)Buffer
;
967 // According to PIO data in protocol, host can perform a series of reads to
968 // the data register after each time device set DRQ ready;
969 // The data size of "a series of read" is command specific.
970 // For most ATA command, data size received from device will not exceed
971 // 1 sector, hence the data size for "a series of read" can be the whole data
972 // size of one command request.
973 // For ATA command such as Read Sector command, the data size of one ATA
974 // command request is often larger than 1 sector, according to the
975 // Read Sector command, the data size of "a series of read" is exactly 1
977 // Here for simplification reason, we specify the data size for
978 // "a series of read" to 1 sector (256 words) if data size of one ATA command
979 // request is larger than 256 words.
984 // used to record bytes of currently transferred data
988 while (WordCount
< RShiftU64 (ByteCount
, 1)) {
990 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
992 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
993 if (EFI_ERROR (Status
)) {
994 Status
= EFI_DEVICE_ERROR
;
999 // Get the byte count for one series of read
1001 if ((WordCount
+ Increment
) > RShiftU64 (ByteCount
, 1)) {
1002 Increment
= (UINTN
)(RShiftU64 (ByteCount
, 1) - WordCount
);
1006 IdeReadPortWMultiple (
1013 IdeWritePortWMultiple (
1021 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1022 if (EFI_ERROR (Status
)) {
1023 Status
= EFI_DEVICE_ERROR
;
1027 WordCount
+= Increment
;
1028 Buffer16
+= Increment
;
1031 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1032 if (EFI_ERROR (Status
)) {
1033 Status
= EFI_DEVICE_ERROR
;
1039 // Dump All Ide registers to ATA_STATUS_BLOCK
1041 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1044 // Not support the Non-blocking now,just do the blocking process.
1050 Send ATA command into device with NON_DATA protocol
1052 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1054 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1055 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1057 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1058 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1059 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1060 used by non-blocking mode.
1062 @retval EFI_SUCCESS Reading succeed
1063 @retval EFI_ABORTED Command failed
1064 @retval EFI_DEVICE_ERROR Device status error.
1069 AtaNonDataCommandIn (
1070 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1071 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1072 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1073 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1075 IN ATA_NONBLOCK_TASK
*Task
1080 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1081 return EFI_INVALID_PARAMETER
;
1085 // Issue ATA command
1087 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1088 if (EFI_ERROR (Status
)) {
1089 Status
= EFI_DEVICE_ERROR
;
1094 // Wait for command completion
1096 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1097 if (EFI_ERROR (Status
)) {
1098 Status
= EFI_DEVICE_ERROR
;
1102 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1103 if (EFI_ERROR (Status
)) {
1104 Status
= EFI_DEVICE_ERROR
;
1110 // Dump All Ide registers to ATA_STATUS_BLOCK
1112 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1115 // Not support the Non-blocking now,just do the blocking process.
1121 Wait for memory to be set.
1123 @param[in] PciIo The PCI IO protocol instance.
1124 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1125 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1127 @retval EFI_DEVICE_ERROR The memory is not set.
1128 @retval EFI_TIMEOUT The memory setting is time out.
1129 @retval EFI_SUCCESS The memory is correct set.
1134 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1135 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1139 UINT8 RegisterValue
;
1141 UINT16 IoPortForBmis
;
1143 BOOLEAN InfiniteWait
;
1146 InfiniteWait
= TRUE
;
1148 InfiniteWait
= FALSE
;
1151 Delay
= DivU64x32 (Timeout
, 1000) + 1;
1154 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1155 if (EFI_ERROR (Status
)) {
1156 Status
= EFI_DEVICE_ERROR
;
1160 IoPortForBmis
= (UINT16
)(IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1161 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1162 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1163 DEBUG ((DEBUG_ERROR
, "ATA UDMA operation fails\n"));
1164 Status
= EFI_DEVICE_ERROR
;
1168 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1169 Status
= EFI_SUCCESS
;
1174 // Stall for 100 microseconds.
1176 MicroSecondDelay (100);
1178 } while (InfiniteWait
|| (Delay
> 0));
1184 Check if the memory to be set.
1186 @param[in] PciIo The PCI IO protocol instance.
1187 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1188 used by non-blocking mode.
1189 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1191 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1192 @retval EFI_NOT_READY The memory is not set.
1193 @retval EFI_TIMEOUT The memory setting is time out.
1194 @retval EFI_SUCCESS The memory is correct set.
1199 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1200 IN ATA_NONBLOCK_TASK
*Task
,
1201 IN EFI_IDE_REGISTERS
*IdeRegisters
1204 UINT8 RegisterValue
;
1205 UINT16 IoPortForBmis
;
1210 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1211 if (EFI_ERROR (Status
)) {
1212 return EFI_DEVICE_ERROR
;
1215 IoPortForBmis
= (UINT16
)(IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1216 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1218 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1219 DEBUG ((DEBUG_ERROR
, "ATA UDMA operation fails\n"));
1220 return EFI_DEVICE_ERROR
;
1223 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1227 if (!Task
->InfiniteWait
&& (Task
->RetryTimes
== 0)) {
1231 // The memory is not set.
1233 return EFI_NOT_READY
;
1238 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1240 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1242 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1243 @param[in] Read Flag used to determine the data transfer
1244 direction. Read equals 1, means data transferred
1245 from device to host;Read equals 0, means data
1246 transferred from host to device.
1247 @param[in] DataBuffer A pointer to the source buffer for the data.
1248 @param[in] DataLength The length of the data.
1249 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1250 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1251 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1252 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1253 used by non-blocking mode.
1255 @retval EFI_SUCCESS the operation is successful.
1256 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1257 @retval EFI_UNSUPPORTED Unknown channel or operations command
1258 @retval EFI_DEVICE_ERROR Ata command execute failed
1264 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1265 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1267 IN VOID
*DataBuffer
,
1268 IN UINT64 DataLength
,
1269 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1270 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1272 IN ATA_NONBLOCK_TASK
*Task
1276 UINT16 IoPortForBmic
;
1277 UINT16 IoPortForBmis
;
1278 UINT16 IoPortForBmid
;
1281 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1283 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr
;
1284 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1287 UINT8 RegisterValue
;
1290 UINTN ByteRemaining
;
1291 UINT8 DeviceControl
;
1294 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1295 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1298 EFI_PCI_IO_PROTOCOL
*PciIo
;
1301 UINTN AlignmentMask
;
1302 UINTN RealPageCount
;
1303 EFI_PHYSICAL_ADDRESS BaseAddr
;
1304 EFI_PHYSICAL_ADDRESS BaseMapAddr
;
1306 Status
= EFI_SUCCESS
;
1312 PciIo
= Instance
->PciIo
;
1314 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1315 return EFI_INVALID_PARAMETER
;
1319 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1321 // Delay 1ms to simulate the blocking time out checking.
1323 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1324 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1325 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1327 // Stall for 1 milliseconds.
1329 MicroSecondDelay (1000);
1332 gBS
->RestoreTPL (OldTpl
);
1335 // The data buffer should be even alignment
1337 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1338 return EFI_INVALID_PARAMETER
;
1342 // Set relevant IO Port address.
1344 IoPortForBmic
= (UINT16
)(IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1345 IoPortForBmis
= (UINT16
)(IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1346 IoPortForBmid
= (UINT16
)(IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1349 // For Blocking mode, start the command.
1350 // For non-blocking mode, when the command is not started, start it, otherwise
1351 // go to check the status.
1353 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1355 // Calculate the number of PRD entry.
1356 // Every entry in PRD table can specify a 64K memory region.
1358 PrdTableNum
= (UINTN
)(RShiftU64 (DataLength
, 16) + 1);
1361 // Make sure that the memory region of PRD table is not cross 64K boundary
1363 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1364 if (PrdTableSize
> 0x10000) {
1365 return EFI_INVALID_PARAMETER
;
1369 // Allocate buffer for PRD table initialization.
1370 // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1371 // boundary and the table cannot cross a 64K boundary in memory.
1373 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1374 RealPageCount
= PageCount
+ EFI_SIZE_TO_PAGES (SIZE_64KB
);
1377 // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1379 ASSERT (RealPageCount
> PageCount
);
1381 Status
= PciIo
->AllocateBuffer (
1384 EfiBootServicesData
,
1389 if (EFI_ERROR (Status
)) {
1390 return EFI_OUT_OF_RESOURCES
;
1393 ByteCount
= EFI_PAGES_TO_SIZE (RealPageCount
);
1394 Status
= PciIo
->Map (
1396 EfiPciIoOperationBusMasterCommonBuffer
,
1397 (VOID
*)(UINTN
)BaseAddr
,
1402 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (RealPageCount
))) {
1404 // If the data length actually mapped is not equal to the requested amount,
1405 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1406 // Can't handle this case.
1408 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1409 return EFI_OUT_OF_RESOURCES
;
1412 ZeroMem ((VOID
*)((UINTN
)BaseAddr
), ByteCount
);
1415 // Calculate the 64K align address as PRD Table base address.
1417 AlignmentMask
= SIZE_64KB
- 1;
1418 PrdTableBaseAddr
= ((UINTN
)BaseAddr
+ AlignmentMask
) & ~AlignmentMask
;
1419 PrdTableMapAddr
= ((UINTN
)BaseMapAddr
+ AlignmentMask
) & ~AlignmentMask
;
1422 // Map the host address of DataBuffer to DMA master address.
1425 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1427 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1430 ByteCount
= (UINTN
)DataLength
;
1431 Status
= PciIo
->Map (
1439 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1440 PciIo
->Unmap (PciIo
, PrdTableMap
);
1441 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1442 return EFI_OUT_OF_RESOURCES
;
1446 // According to Ata spec, it requires the buffer address and size to be even.
1448 ASSERT ((BufferMapAddress
& 0x1) == 0);
1449 ASSERT ((ByteCount
& 0x1) == 0);
1452 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1454 ByteRemaining
= ByteCount
;
1455 TempPrdBaseAddr
= (EFI_ATA_DMA_PRD
*)(UINTN
)PrdTableBaseAddr
;
1456 while (ByteRemaining
!= 0) {
1457 if (ByteRemaining
<= 0x10000) {
1458 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
)((UINTN
)BufferMapAddress
);
1459 TempPrdBaseAddr
->ByteCount
= (UINT16
)ByteRemaining
;
1460 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1464 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
)((UINTN
)BufferMapAddress
);
1465 TempPrdBaseAddr
->ByteCount
= (UINT16
)0x0;
1467 ByteRemaining
-= 0x10000;
1468 BufferMapAddress
+= 0x10000;
1473 // Start to enable the DMA operation
1475 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1477 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1480 // Enable interrupt to support UDMA
1483 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1486 // Read BMIS register and clear ERROR and INTR bit
1488 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1489 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1490 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1493 // Set the base address to BMID register
1495 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1498 // Set BMIC register to identify the operation direction
1500 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmic
);
1502 RegisterValue
|= BMIC_NREAD
;
1504 RegisterValue
&= ~((UINT8
)BMIC_NREAD
);
1507 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1510 Task
->Map
= BufferMap
;
1511 Task
->TableMap
= PrdTableMap
;
1512 Task
->MapBaseAddress
= (EFI_ATA_DMA_PRD
*)(UINTN
)BaseAddr
;
1513 Task
->PageCount
= RealPageCount
;
1514 Task
->IsStart
= TRUE
;
1518 // Issue ATA command
1520 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1522 if (EFI_ERROR (Status
)) {
1523 Status
= EFI_DEVICE_ERROR
;
1527 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1528 if (EFI_ERROR (Status
)) {
1529 Status
= EFI_DEVICE_ERROR
;
1534 // Set START bit of BMIC register
1536 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmic
);
1537 RegisterValue
|= BMIC_START
;
1538 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1542 // Check the INTERRUPT and ERROR bit of BMIS
1545 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1547 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
, Timeout
);
1551 // For blocking mode, clear registers and free buffers.
1552 // For non blocking mode, when the related registers have been set or time
1553 // out, or a error has been happened, it needs to clear the register and free
1556 if ((Task
== NULL
) || (Status
!= EFI_NOT_READY
)) {
1558 // Read BMIS register and clear ERROR and INTR bit
1560 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1561 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1562 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1565 // Read Status Register of IDE device to clear interrupt
1567 RegisterValue
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
1570 // Clear START bit of BMIC register
1572 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmic
);
1573 RegisterValue
&= ~((UINT8
)BMIC_START
);
1574 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1577 // Disable interrupt of Select device
1579 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1580 DeviceControl
|= ATA_CTLREG_IEN_L
;
1581 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1583 // Stall for 10 milliseconds.
1585 MicroSecondDelay (10000);
1590 // Free all allocated resource
1592 if ((Task
== NULL
) || (Status
!= EFI_NOT_READY
)) {
1594 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1595 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1596 PciIo
->Unmap (PciIo
, Task
->Map
);
1598 PciIo
->Unmap (PciIo
, PrdTableMap
);
1599 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1600 PciIo
->Unmap (PciIo
, BufferMap
);
1604 // Dump All Ide registers to ATA_STATUS_BLOCK
1606 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1613 This function reads the pending data in the device.
1615 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1616 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1618 @retval EFI_SUCCESS Successfully read.
1619 @retval EFI_NOT_READY The BSY is set avoiding reading.
1624 AtaPacketReadPendingData (
1625 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1626 IN EFI_IDE_REGISTERS
*IdeRegisters
1630 UINT16 TempWordBuffer
;
1632 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1633 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1634 return EFI_NOT_READY
;
1637 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1638 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1639 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1640 IdeReadPortWMultiple (
1646 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1654 This function is called by AtaPacketCommandExecute().
1655 It is used to transfer data between host and device. The data direction is specified
1656 by the fourth parameter.
1658 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1659 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1660 @param Buffer Buffer contained data transferred between host and device.
1661 @param ByteCount Data size in byte unit of the buffer.
1662 @param Read Flag used to determine the data transfer direction.
1663 Read equals 1, means data transferred from device to host;
1664 Read equals 0, means data transferred from host to device.
1665 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1666 , uses 100ns as a unit.
1668 @retval EFI_SUCCESS data is transferred successfully.
1669 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1673 AtaPacketReadWrite (
1674 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1675 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1676 IN OUT VOID
*Buffer
,
1677 IN OUT UINT32
*ByteCount
,
1682 UINT32 RequiredWordCount
;
1683 UINT32 ActualWordCount
;
1689 RequiredWordCount
= *ByteCount
>> 1;
1692 // No data transfer is permitted.
1694 if (RequiredWordCount
== 0) {
1699 // ActualWordCount means the word count of data really transferred.
1701 ActualWordCount
= 0;
1703 while (ActualWordCount
< RequiredWordCount
) {
1705 // before each data transfer stream, the host should poll DRQ bit ready,
1706 // to see whether indicates device is ready to transfer data.
1708 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1709 if (EFI_ERROR (Status
)) {
1710 if (Status
== EFI_NOT_READY
) {
1712 // Device provided less data than we intended to read, or wanted less
1713 // data than we intended to write, but it may still be successful.
1722 // get current data transfer size from Cylinder Registers.
1724 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1725 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1726 WordCount
= WordCount
& 0xffff;
1729 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1732 IdeReadPortWMultiple (
1739 IdeWritePortWMultiple (
1748 // read status register to check whether error happens.
1750 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1751 if (EFI_ERROR (Status
)) {
1752 return EFI_DEVICE_ERROR
;
1755 PtrBuffer
+= WordCount
;
1756 ActualWordCount
+= WordCount
;
1761 // In the case where the drive wants to send more data than we need to read,
1762 // the DRQ bit will be set and cause delays from DRQClear2().
1763 // We need to read data from the drive until it clears DRQ so we can move on.
1765 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1769 // read status register to check whether error happens.
1771 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1772 if (EFI_ERROR (Status
)) {
1773 return EFI_DEVICE_ERROR
;
1777 // After data transfer is completed, normally, DRQ bit should clear.
1779 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1780 if (EFI_ERROR (Status
)) {
1781 return EFI_DEVICE_ERROR
;
1784 *ByteCount
= ActualWordCount
<< 1;
1789 This function is used to send out ATAPI commands conforms to the Packet Command
1790 with PIO Data In Protocol.
1792 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1793 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1794 store the IDE i/o port registers' base addresses
1795 @param[in] Channel The channel number of device.
1796 @param[in] Device The device number of device.
1797 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
1799 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1800 and device sends data successfully.
1801 @retval EFI_DEVICE_ERROR the device failed to send data.
1806 AtaPacketCommandExecute (
1807 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1808 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1811 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
1814 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1817 UINT8 PacketCommand
[12];
1819 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1822 // Fill ATAPI Command Packet according to CDB.
1823 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1825 if (Packet
->CdbLength
> 12) {
1826 return EFI_INVALID_PARAMETER
;
1829 ZeroMem (PacketCommand
, 12);
1830 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
1835 AtaCommandBlock
.AtaFeatures
= 0x00;
1837 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1838 // determine how many data should be transferred.
1840 AtaCommandBlock
.AtaCylinderLow
= (UINT8
)(ATAPI_MAX_BYTE_COUNT
& 0x00ff);
1841 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
)(ATAPI_MAX_BYTE_COUNT
>> 8);
1842 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
1843 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
1845 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
1847 // Disable interrupt
1849 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
1852 // Issue ATA PACKET command firstly
1854 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
1855 if (EFI_ERROR (Status
)) {
1859 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
1860 if (EFI_ERROR (Status
)) {
1865 // Send out ATAPI command packet
1867 for (Count
= 0; Count
< 6; Count
++) {
1868 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
1870 // Stall for 10 microseconds.
1872 MicroSecondDelay (10);
1876 // Read/Write the data of ATAPI Command
1878 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
1879 Status
= AtaPacketReadWrite (
1882 Packet
->InDataBuffer
,
1883 &Packet
->InTransferLength
,
1888 Status
= AtaPacketReadWrite (
1891 Packet
->OutDataBuffer
,
1892 &Packet
->OutTransferLength
,
1902 Set the calculated Best transfer mode to a detected device.
1904 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1905 @param Channel The channel number of device.
1906 @param Device The device number of device.
1907 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
1908 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1910 @retval EFI_SUCCESS Set transfer mode successfully.
1911 @retval EFI_DEVICE_ERROR Set transfer mode failed.
1912 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1917 SetDeviceTransferMode (
1918 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1921 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
1922 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
1926 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1928 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1930 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
1931 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
1932 AtaCommandBlock
.AtaFeatures
= 0x03;
1933 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
1936 // Send SET FEATURE command (sub command 0x03) to set pio mode.
1938 Status
= AtaNonDataCommandIn (
1940 &Instance
->IdeRegisters
[Channel
],
1951 Set drive parameters for devices not support PACKETS command.
1953 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1954 @param Channel The channel number of device.
1955 @param Device The device number of device.
1956 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
1957 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1959 @retval EFI_SUCCESS Set drive parameter successfully.
1960 @retval EFI_DEVICE_ERROR Set drive parameter failed.
1961 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1966 SetDriveParameters (
1967 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1970 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
1971 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
1975 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1977 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1979 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
1980 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
1981 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)((Device
<< 0x4) + DriveParameters
->Heads
);
1984 // Send Init drive parameters
1986 Status
= AtaNonDataCommandIn (
1988 &Instance
->IdeRegisters
[Channel
],
1996 // Send Set Multiple parameters
1998 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
1999 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2000 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2002 Status
= AtaNonDataCommandIn (
2004 &Instance
->IdeRegisters
[Channel
],
2015 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2017 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2018 @param Channel The channel number of device.
2019 @param Device The device number of device.
2020 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2022 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2023 @retval Others Fail to get return status data.
2028 IdeAtaSmartReturnStatusCheck (
2029 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2032 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2036 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2040 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2042 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2043 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2044 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2045 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2046 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)((Device
<< 0x4) | 0xe0);
2049 // Send S.M.A.R.T Read Return Status command to device
2051 Status
= AtaNonDataCommandIn (
2053 &Instance
->IdeRegisters
[Channel
],
2060 if (EFI_ERROR (Status
)) {
2061 REPORT_STATUS_CODE (
2062 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2063 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
2065 return EFI_DEVICE_ERROR
;
2068 REPORT_STATUS_CODE (
2070 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
2073 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2074 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2076 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2078 // The threshold exceeded condition is not detected by the device
2080 DEBUG ((DEBUG_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2081 REPORT_STATUS_CODE (
2083 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
2085 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2087 // The threshold exceeded condition is detected by the device
2089 DEBUG ((DEBUG_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2090 REPORT_STATUS_CODE (
2092 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
2100 Enable SMART command of the disk if supported.
2102 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2103 @param Channel The channel number of device.
2104 @param Device The device number of device.
2105 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2106 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2111 IdeAtaSmartSupport (
2112 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2115 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2116 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2120 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2123 // Detect if the device supports S.M.A.R.T.
2125 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2127 // S.M.A.R.T is not supported by the device
2131 "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2132 (Channel
== 1) ? "secondary" : "primary",
2133 (Device
== 1) ? "slave" : "master"
2135 REPORT_STATUS_CODE (
2136 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2137 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2141 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2143 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2144 REPORT_STATUS_CODE (
2146 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2149 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2151 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2152 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2153 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2154 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2155 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)((Device
<< 0x4) | 0xe0);
2158 // Send S.M.A.R.T Enable command to device
2160 Status
= AtaNonDataCommandIn (
2162 &Instance
->IdeRegisters
[Channel
],
2169 if (!EFI_ERROR (Status
)) {
2171 // Send S.M.A.R.T AutoSave command to device
2173 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2175 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2176 AtaCommandBlock
.AtaFeatures
= 0xD2;
2177 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2178 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2179 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2180 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)((Device
<< 0x4) | 0xe0);
2182 Status
= AtaNonDataCommandIn (
2184 &Instance
->IdeRegisters
[Channel
],
2190 if (!EFI_ERROR (Status
)) {
2191 Status
= IdeAtaSmartReturnStatusCheck (
2203 "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2204 (Channel
== 1) ? "secondary" : "primary",
2205 (Device
== 1) ? "slave" : "master"
2213 Sends out an ATA Identify Command to the specified device.
2215 This function is called by DiscoverIdeDevice() during its device
2216 identification. It sends out the ATA Identify Command to the
2217 specified device. Only ATA device responses to this command. If
2218 the command succeeds, it returns the Identify data structure which
2219 contains information about the device. This function extracts the
2220 information it needs to fill the IDE_BLK_IO_DEV data structure,
2221 including device type, media block size, media capacity, and etc.
2223 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2224 @param Channel The channel number of device.
2225 @param Device The device number of device.
2226 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2227 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2229 @retval EFI_SUCCESS Identify ATA device successfully.
2230 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2231 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2237 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2240 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2241 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2245 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2247 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2249 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2250 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2252 Status
= AtaPioDataInOut (
2254 &Instance
->IdeRegisters
[Channel
],
2256 sizeof (EFI_IDENTIFY_DATA
),
2268 This function is called by DiscoverIdeDevice() during its device
2270 Its main purpose is to get enough information for the device media
2271 to fill in the Media data structure of the Block I/O Protocol interface.
2273 There are 5 steps to reach such objective:
2274 1. Sends out the ATAPI Identify Command to the specified device.
2275 Only ATAPI device responses to this command. If the command succeeds,
2276 it returns the Identify data structure which filled with information
2277 about the device. Since the ATAPI device contains removable media,
2278 the only meaningful information is the device module name.
2279 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2280 This command will return inquiry data of the device, which contains
2281 the device type information.
2282 3. Allocate sense data space for future use. We don't detect the media
2283 presence here to improvement boot performance, especially when CD
2284 media is present. The media detection will be performed just before
2285 each BLK_IO read/write
2287 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2288 @param Channel The channel number of device.
2289 @param Device The device number of device.
2290 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2291 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2293 @retval EFI_SUCCESS Identify ATAPI device successfully.
2294 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2295 is not supported by this IDE driver.
2296 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2302 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2305 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2306 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2310 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2312 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2314 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2315 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2318 // Send ATAPI Identify Command to get IDENTIFY data.
2320 Status
= AtaPioDataInOut (
2322 &Instance
->IdeRegisters
[Channel
],
2324 sizeof (EFI_IDENTIFY_DATA
),
2336 This function is used for detect whether the IDE device exists in the
2337 specified Channel as the specified Device Number.
2339 There is two IDE channels: one is Primary Channel, the other is
2340 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2341 Different channel has different register group.
2343 On each IDE channel, at most two IDE devices attach,
2344 one is called Device 0 (Master device), the other is called Device 1
2345 (Slave device). The devices on the same channel co-use the same register
2346 group, so before sending out a command for a specified device via command
2347 register, it is a must to select the current device to accept the command
2348 by set the device number in the Head/Device Register.
2350 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2351 @param IdeChannel The channel number of device.
2353 @retval EFI_SUCCESS successfully detects device.
2354 @retval other any failure during detection process will return this value.
2359 DetectAndConfigIdeDevice (
2360 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2365 UINT8 SectorCountReg
;
2369 EFI_ATA_DEVICE_TYPE DeviceType
;
2371 EFI_IDE_REGISTERS
*IdeRegisters
;
2372 EFI_IDENTIFY_DATA Buffer
;
2374 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2375 EFI_PCI_IO_PROTOCOL
*PciIo
;
2377 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2378 EFI_ATA_TRANSFER_MODE TransferMode
;
2379 EFI_ATA_DRIVE_PARMS DriveParameters
;
2381 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2382 IdeInit
= Instance
->IdeControllerInit
;
2383 PciIo
= Instance
->PciIo
;
2385 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2387 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2389 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2392 // Send ATA Device Execut Diagnostic command.
2393 // This command should work no matter DRDY is ready or not
2395 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2397 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2398 if (EFI_ERROR (Status
)) {
2399 DEBUG ((DEBUG_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2404 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2406 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2408 // Stall for 1 milliseconds.
2410 MicroSecondDelay (1000);
2412 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2413 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2414 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2415 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2418 // Refer to ATA/ATAPI 4 Spec, section 9.1
2420 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2421 DeviceType
= EfiIdeHarddisk
;
2422 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2423 DeviceType
= EfiIdeCdrom
;
2429 // Send IDENTIFY cmd to the device to test if it is really attached.
2431 if (DeviceType
== EfiIdeHarddisk
) {
2432 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2434 // if identifying ata device is failure, then try to send identify packet cmd.
2436 if (EFI_ERROR (Status
)) {
2437 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2439 DeviceType
= EfiIdeCdrom
;
2440 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2443 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2445 // if identifying atapi device is failure, then try to send identify cmd.
2447 if (EFI_ERROR (Status
)) {
2448 DeviceType
= EfiIdeHarddisk
;
2449 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2453 if (EFI_ERROR (Status
)) {
2455 // No device is found at this port
2462 "[%a] channel [%a] [%a] device\n",
2463 (IdeChannel
== 1) ? "secondary" : "primary ",
2464 (IdeDevice
== 1) ? "slave " : "master",
2465 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"
2468 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2470 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2471 IdeAtaSmartSupport (
2481 // Submit identify data to IDE controller init driver
2483 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2486 // Now start to config ide device parameter and transfer mode.
2488 Status
= IdeInit
->CalculateMode (
2494 if (EFI_ERROR (Status
)) {
2495 DEBUG ((DEBUG_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2500 // Set best supported PIO mode on this IDE device
2502 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2503 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2505 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2508 TransferMode
.ModeNumber
= (UINT8
)(SupportedModes
->PioMode
.Mode
);
2510 if (SupportedModes
->ExtModeCount
== 0) {
2511 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2513 if (EFI_ERROR (Status
)) {
2514 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2520 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2521 // be set together. Only one DMA mode can be set to a device. If setting
2522 // DMA mode operation fails, we can continue moving on because we only use
2523 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2525 if (SupportedModes
->UdmaMode
.Valid
) {
2526 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2527 TransferMode
.ModeNumber
= (UINT8
)(SupportedModes
->UdmaMode
.Mode
);
2528 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2530 if (EFI_ERROR (Status
)) {
2531 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2534 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2535 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2536 TransferMode
.ModeNumber
= (UINT8
)SupportedModes
->MultiWordDmaMode
.Mode
;
2537 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2539 if (EFI_ERROR (Status
)) {
2540 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2546 // Set Parameters for the device:
2548 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2550 if (DeviceType
== EfiIdeHarddisk
) {
2552 // Init driver parameters
2554 DriveParameters
.Sector
= (UINT8
)((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2555 DriveParameters
.Heads
= (UINT8
)(((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2556 DriveParameters
.MultipleSector
= (UINT8
)((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2558 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2562 // Set IDE controller Timing Blocks in the PCI Configuration Space
2564 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2567 // IDE controller and IDE device timing is configured successfully.
2568 // Now insert the device into device list.
2570 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2571 if (EFI_ERROR (Status
)) {
2575 if (DeviceType
== EfiIdeHarddisk
) {
2576 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2584 Initialize ATA host controller at IDE mode.
2586 The function is designed to initialize ATA host controller.
2588 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2593 IdeModeInitialization (
2594 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2598 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2599 EFI_PCI_IO_PROTOCOL
*PciIo
;
2602 BOOLEAN ChannelEnabled
;
2605 IdeInit
= Instance
->IdeControllerInit
;
2606 PciIo
= Instance
->PciIo
;
2607 Channel
= IdeInit
->ChannelCount
;
2610 // Obtain IDE IO port registers' base addresses
2612 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2613 if (EFI_ERROR (Status
)) {
2617 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2618 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2621 // now obtain channel information fron IdeControllerInit protocol.
2623 Status
= IdeInit
->GetChannelInfo (
2629 if (EFI_ERROR (Status
)) {
2630 DEBUG ((DEBUG_ERROR
, "[GetChannel, Status=%x]", Status
));
2634 if (!ChannelEnabled
) {
2638 ASSERT (MaxDevices
<= 2);
2640 // Now inform the IDE Controller Init Module.
2642 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2645 // No reset channel function implemented.
2647 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2650 // Now inform the IDE Controller Init Module.
2652 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2655 // Detect all attached ATA devices and set the transfer mode for each device.
2657 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2661 // All configurations done! Notify IdeController to do post initialization
2662 // work such as saving IDE controller PCI settings for S3 resume
2664 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);