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
,
173 Reads multiple words of data from the IDE data port.
174 Call the IO abstraction once to do the complete read,
175 not one word at a time
177 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
178 @param Port IO port to read
179 @param Count Number of UINT16's to read
180 @param Buffer Pointer to the data buffer for read
185 IdeReadPortWMultiple (
186 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
192 ASSERT (PciIo
!= NULL
);
193 ASSERT (Buffer
!= NULL
);
196 // Perform UINT16 data read from FIFO
200 EfiPciIoWidthFifoUint16
,
201 EFI_PCI_IO_PASS_THROUGH_BAR
,
210 This function is used to analyze the Status Register and print out
211 some debug information and if there is ERR bit set in the Status
212 Register, the Error Register's value is also be parsed and print out.
214 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
215 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
216 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
221 DumpAllIdeRegisters (
222 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
223 IN EFI_IDE_REGISTERS
*IdeRegisters
,
224 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
227 EFI_ATA_STATUS_BLOCK StatusBlock
;
229 ASSERT (PciIo
!= NULL
);
230 ASSERT (IdeRegisters
!= NULL
);
232 ZeroMem (&StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
234 StatusBlock
.AtaStatus
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
235 StatusBlock
.AtaError
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
236 StatusBlock
.AtaSectorCount
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
237 StatusBlock
.AtaSectorCountExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
238 StatusBlock
.AtaSectorNumber
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
239 StatusBlock
.AtaSectorNumberExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
240 StatusBlock
.AtaCylinderLow
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
241 StatusBlock
.AtaCylinderLowExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
242 StatusBlock
.AtaCylinderHigh
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
243 StatusBlock
.AtaCylinderHighExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
244 StatusBlock
.AtaDeviceHead
= IdeReadPortB (PciIo
, IdeRegisters
->Head
);
246 if (AtaStatusBlock
!= NULL
) {
248 // Dump the content of all ATA registers.
250 CopyMem (AtaStatusBlock
, &StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
254 if ((StatusBlock
.AtaStatus
& ATA_STSREG_DWF
) != 0) {
255 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock
.AtaStatus
));
258 if ((StatusBlock
.AtaStatus
& ATA_STSREG_CORR
) != 0) {
259 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock
.AtaStatus
));
262 if ((StatusBlock
.AtaStatus
& ATA_STSREG_ERR
) != 0) {
263 if ((StatusBlock
.AtaError
& ATA_ERRREG_BBK
) != 0) {
264 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock
.AtaError
));
267 if ((StatusBlock
.AtaError
& ATA_ERRREG_UNC
) != 0) {
268 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock
.AtaError
));
271 if ((StatusBlock
.AtaError
& ATA_ERRREG_MC
) != 0) {
272 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock
.AtaError
));
275 if ((StatusBlock
.AtaError
& ATA_ERRREG_ABRT
) != 0) {
276 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock
.AtaError
));
279 if ((StatusBlock
.AtaError
& ATA_ERRREG_TK0NF
) != 0) {
280 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock
.AtaError
));
283 if ((StatusBlock
.AtaError
& ATA_ERRREG_AMNF
) != 0) {
284 DEBUG ((DEBUG_ERROR
, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock
.AtaError
));
291 This function is used to analyze the Status Register at the condition that BSY is zero.
292 if there is ERR bit set in the Status Register, then return error.
294 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
295 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
297 @retval EFI_SUCCESS No err information in the Status Register.
298 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
303 CheckStatusRegister (
304 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
305 IN EFI_IDE_REGISTERS
*IdeRegisters
308 UINT8 StatusRegister
;
310 ASSERT (PciIo
!= NULL
);
311 ASSERT (IdeRegisters
!= NULL
);
313 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
315 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
316 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
319 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);
385 } 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);
448 } while (InfiniteWait
|| (Delay
> 0));
454 This function is used to poll for the DRQ bit set in the
456 DRQ is set when the device is ready to transfer data. So this function
457 is called after the command is sent to the device and before required
460 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
461 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
462 @param Timeout The time to complete the command, uses 100ns as a unit.
464 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
467 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
469 @retval EFI_ABORTED Polling abandoned due to command abort.
471 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
473 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
474 reported "command complete" by clearing DRQ
477 @note Read Status Register will clear interrupt status.
483 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
484 IN EFI_IDE_REGISTERS
*IdeRegisters
,
489 UINT8 StatusRegister
;
491 BOOLEAN InfiniteWait
;
493 ASSERT (PciIo
!= NULL
);
494 ASSERT (IdeRegisters
!= NULL
);
499 InfiniteWait
= FALSE
;
502 Delay
= DivU64x32(Timeout
, 1000) + 1;
505 // Read Status Register will clear interrupt
507 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
510 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
512 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
513 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
514 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
516 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));
540 This function is used to poll for the DRQ bit set in the Alternate Status Register.
541 DRQ is set when the device is ready to transfer data. So this function is called after
542 the command is sent to the device and before required data is transferred.
544 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
545 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
546 @param Timeout The time to complete the command, uses 100ns as a unit.
548 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
551 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
553 @retval EFI_ABORTED Polling abandoned due to command abort.
555 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
557 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
558 reported "command complete" by clearing DRQ
561 @note Read Alternate Status Register will not clear interrupt status.
567 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
568 IN EFI_IDE_REGISTERS
*IdeRegisters
,
575 BOOLEAN InfiniteWait
;
577 ASSERT (PciIo
!= NULL
);
578 ASSERT (IdeRegisters
!= NULL
);
583 InfiniteWait
= FALSE
;
586 Delay
= DivU64x32(Timeout
, 1000) + 1;
590 // Read Alternate Status Register will not clear interrupt status
592 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
594 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
596 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
597 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
598 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
600 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
603 return EFI_DEVICE_ERROR
;
606 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
609 return EFI_NOT_READY
;
614 // Stall for 100 microseconds.
616 MicroSecondDelay (100);
619 } while (InfiniteWait
|| (Delay
> 0));
628 This function is used to poll for the BSY bit clear in the Status Register. BSY
629 is clear when the device is not busy. Every command must be sent after device is not busy.
631 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
632 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
633 @param Timeout The time to complete the command, uses 100ns as a unit.
635 @retval EFI_SUCCESS BSY bit clear within the time out.
636 @retval EFI_TIMEOUT BSY bit not clear within the time out.
638 @note Read Status Register will clear interrupt status.
643 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
644 IN EFI_IDE_REGISTERS
*IdeRegisters
,
649 UINT8 StatusRegister
;
650 BOOLEAN InfiniteWait
;
652 ASSERT (PciIo
!= NULL
);
653 ASSERT (IdeRegisters
!= NULL
);
658 InfiniteWait
= FALSE
;
661 Delay
= DivU64x32(Timeout
, 1000) + 1;
663 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
665 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
670 // Stall for 100 microseconds.
672 MicroSecondDelay (100);
676 } while (InfiniteWait
|| (Delay
> 0));
683 Get IDE i/o port registers' base addresses by mode.
685 In 'Compatibility' mode, use fixed addresses.
686 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
689 The steps to get IDE i/o port registers' base addresses for each channel
692 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
693 controller's Configuration Space to determine the operating mode.
695 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
696 ___________________________________________
697 | | Command Block | Control Block |
698 | Channel | Registers | Registers |
699 |___________|_______________|_______________|
700 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
701 |___________|_______________|_______________|
702 | Secondary | 170h - 177h | 376h - 377h |
703 |___________|_______________|_______________|
705 Table 1. Compatibility resource mappings
707 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
708 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
709 ___________________________________________________
710 | | Command Block | Control Block |
711 | Channel | Registers | Registers |
712 |___________|___________________|___________________|
713 | Primary | BAR at offset 0x10| BAR at offset 0x14|
714 |___________|___________________|___________________|
715 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
716 |___________|___________________|___________________|
718 Table 2. BARs for Register Mapping
720 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
721 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
722 store the IDE i/o port registers' base addresses
724 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
725 @retval EFI_SUCCESS Get the Base address successfully
726 @retval Other Read the pci configuration data error
731 GetIdeRegisterIoAddr (
732 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
733 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
738 UINT16 CommandBlockBaseAddr
;
739 UINT16 ControlBlockBaseAddr
;
740 UINT16 BusMasterBaseAddr
;
742 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
743 return EFI_INVALID_PARAMETER
;
746 Status
= PciIo
->Pci
.Read (
754 if (EFI_ERROR (Status
)) {
758 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
760 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
761 CommandBlockBaseAddr
= 0x1f0;
762 ControlBlockBaseAddr
= 0x3f6;
765 // The BARs should be of IO type
767 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
768 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
769 return EFI_UNSUPPORTED
;
772 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
773 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
777 // Calculate IDE primary channel I/O register base address.
779 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
780 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
781 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
782 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
783 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
784 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
785 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
786 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
787 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
788 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
790 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
791 CommandBlockBaseAddr
= 0x170;
792 ControlBlockBaseAddr
= 0x376;
795 // The BARs should be of IO type
797 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
798 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
799 return EFI_UNSUPPORTED
;
802 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
803 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
807 // Calculate IDE secondary channel I/O register base address.
809 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
810 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
811 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
812 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
813 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
814 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
815 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
816 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
817 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
818 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
825 Send ATA Ext command into device with NON_DATA protocol.
827 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
828 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
829 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
830 @param Timeout The time to complete the command, uses 100ns as a unit.
832 @retval EFI_SUCCESS Reading succeed
833 @retval EFI_DEVICE_ERROR Error executing commands on this device.
839 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
840 IN EFI_IDE_REGISTERS
*IdeRegisters
,
841 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
849 ASSERT (PciIo
!= NULL
);
850 ASSERT (IdeRegisters
!= NULL
);
851 ASSERT (AtaCommandBlock
!= NULL
);
853 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
854 AtaCommand
= AtaCommandBlock
->AtaCommand
;
856 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
857 if (EFI_ERROR (Status
)) {
858 return EFI_DEVICE_ERROR
;
862 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
864 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
867 // set all the command parameters
868 // Before write to all the following registers, BSY and DRQ must be 0.
870 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
871 if (EFI_ERROR (Status
)) {
872 return EFI_DEVICE_ERROR
;
876 // Fill the feature register, which is a two-byte FIFO. Need write twice.
878 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
879 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
882 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
884 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
885 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
888 // Fill the start LBA registers, which are also two-byte FIFO
890 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
891 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
893 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
894 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
896 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
897 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
900 // Send command via Command Register
902 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
905 // Stall at least 400 microseconds.
907 MicroSecondDelay (400);
913 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
915 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
917 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
918 @param[in, out] Buffer A pointer to the source buffer for the data.
919 @param[in] ByteCount The length of the data.
920 @param[in] Read Flag used to determine the data transfer direction.
921 Read equals 1, means data transferred from device
922 to host;Read equals 0, means data transferred
924 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
925 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
926 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
927 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
928 used by non-blocking mode.
930 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
931 @retval EFI_DEVICE_ERROR command sent failed.
937 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
938 IN EFI_IDE_REGISTERS
*IdeRegisters
,
942 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
943 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
945 IN ATA_NONBLOCK_TASK
*Task
953 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
954 return EFI_INVALID_PARAMETER
;
960 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
961 if (EFI_ERROR (Status
)) {
962 Status
= EFI_DEVICE_ERROR
;
966 Buffer16
= (UINT16
*) Buffer
;
969 // According to PIO data in protocol, host can perform a series of reads to
970 // the data register after each time device set DRQ ready;
971 // The data size of "a series of read" is command specific.
972 // For most ATA command, data size received from device will not exceed
973 // 1 sector, hence the data size for "a series of read" can be the whole data
974 // size of one command request.
975 // For ATA command such as Read Sector command, the data size of one ATA
976 // command request is often larger than 1 sector, according to the
977 // Read Sector command, the data size of "a series of read" is exactly 1
979 // Here for simplification reason, we specify the data size for
980 // "a series of read" to 1 sector (256 words) if data size of one ATA command
981 // request is larger than 256 words.
986 // used to record bytes of currently transferred data
990 while (WordCount
< RShiftU64(ByteCount
, 1)) {
992 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
994 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
995 if (EFI_ERROR (Status
)) {
996 Status
= EFI_DEVICE_ERROR
;
1001 // Get the byte count for one series of read
1003 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1004 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1008 IdeReadPortWMultiple (
1015 IdeWritePortWMultiple (
1023 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1024 if (EFI_ERROR (Status
)) {
1025 Status
= EFI_DEVICE_ERROR
;
1029 WordCount
+= Increment
;
1030 Buffer16
+= Increment
;
1033 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1034 if (EFI_ERROR (Status
)) {
1035 Status
= EFI_DEVICE_ERROR
;
1041 // Dump All Ide registers to ATA_STATUS_BLOCK
1043 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1046 // Not support the Non-blocking now,just do the blocking process.
1052 Send ATA command into device with NON_DATA protocol
1054 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1056 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1057 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1059 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1060 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1061 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1062 used by non-blocking mode.
1064 @retval EFI_SUCCESS Reading succeed
1065 @retval EFI_ABORTED Command failed
1066 @retval EFI_DEVICE_ERROR Device status error.
1071 AtaNonDataCommandIn (
1072 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1073 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1074 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1075 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1077 IN ATA_NONBLOCK_TASK
*Task
1082 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1083 return EFI_INVALID_PARAMETER
;
1087 // Issue ATA command
1089 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1090 if (EFI_ERROR (Status
)) {
1091 Status
= EFI_DEVICE_ERROR
;
1096 // Wait for command completion
1098 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1099 if (EFI_ERROR (Status
)) {
1100 Status
= EFI_DEVICE_ERROR
;
1104 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1105 if (EFI_ERROR (Status
)) {
1106 Status
= EFI_DEVICE_ERROR
;
1112 // Dump All Ide registers to ATA_STATUS_BLOCK
1114 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1117 // Not support the Non-blocking now,just do the blocking process.
1123 Wait for memory to be set.
1125 @param[in] PciIo The PCI IO protocol instance.
1126 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1127 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1129 @retval EFI_DEVICE_ERROR The memory is not set.
1130 @retval EFI_TIMEOUT The memory setting is time out.
1131 @retval EFI_SUCCESS The memory is correct set.
1136 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1137 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1141 UINT8 RegisterValue
;
1143 UINT16 IoPortForBmis
;
1145 BOOLEAN InfiniteWait
;
1148 InfiniteWait
= TRUE
;
1150 InfiniteWait
= FALSE
;
1153 Delay
= DivU64x32 (Timeout
, 1000) + 1;
1156 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1157 if (EFI_ERROR (Status
)) {
1158 Status
= EFI_DEVICE_ERROR
;
1162 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1163 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1164 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1165 DEBUG ((DEBUG_ERROR
, "ATA UDMA operation fails\n"));
1166 Status
= EFI_DEVICE_ERROR
;
1170 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1171 Status
= EFI_SUCCESS
;
1175 // Stall for 100 microseconds.
1177 MicroSecondDelay (100);
1179 } while (InfiniteWait
|| (Delay
> 0));
1185 Check if the memory to be set.
1187 @param[in] PciIo The PCI IO protocol instance.
1188 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1189 used by non-blocking mode.
1190 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1192 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1193 @retval EFI_NOT_READY The memory is not set.
1194 @retval EFI_TIMEOUT The memory setting is time out.
1195 @retval EFI_SUCCESS The memory is correct set.
1200 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1201 IN ATA_NONBLOCK_TASK
*Task
,
1202 IN EFI_IDE_REGISTERS
*IdeRegisters
1205 UINT8 RegisterValue
;
1206 UINT16 IoPortForBmis
;
1211 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1212 if (EFI_ERROR (Status
)) {
1213 return EFI_DEVICE_ERROR
;
1216 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1217 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1219 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1220 DEBUG ((DEBUG_ERROR
, "ATA UDMA operation fails\n"));
1221 return EFI_DEVICE_ERROR
;
1224 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1228 if (!Task
->InfiniteWait
&& (Task
->RetryTimes
== 0)) {
1232 // The memory is not set.
1234 return EFI_NOT_READY
;
1239 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1241 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1243 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1244 @param[in] Read Flag used to determine the data transfer
1245 direction. Read equals 1, means data transferred
1246 from device to host;Read equals 0, means data
1247 transferred from host to device.
1248 @param[in] DataBuffer A pointer to the source buffer for the data.
1249 @param[in] DataLength The length of the data.
1250 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1251 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1252 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1253 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1254 used by non-blocking mode.
1256 @retval EFI_SUCCESS the operation is successful.
1257 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1258 @retval EFI_UNSUPPORTED Unknown channel or operations command
1259 @retval EFI_DEVICE_ERROR Ata command execute failed
1265 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1266 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1268 IN VOID
*DataBuffer
,
1269 IN UINT64 DataLength
,
1270 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1271 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1273 IN ATA_NONBLOCK_TASK
*Task
1277 UINT16 IoPortForBmic
;
1278 UINT16 IoPortForBmis
;
1279 UINT16 IoPortForBmid
;
1282 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1284 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr
;
1285 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1288 UINT8 RegisterValue
;
1291 UINTN ByteRemaining
;
1292 UINT8 DeviceControl
;
1295 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1296 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1299 EFI_PCI_IO_PROTOCOL
*PciIo
;
1302 UINTN AlignmentMask
;
1303 UINTN RealPageCount
;
1304 EFI_PHYSICAL_ADDRESS BaseAddr
;
1305 EFI_PHYSICAL_ADDRESS BaseMapAddr
;
1307 Status
= EFI_SUCCESS
;
1313 PciIo
= Instance
->PciIo
;
1315 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1316 return EFI_INVALID_PARAMETER
;
1320 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1322 // Delay 1ms to simulate the blocking time out checking.
1324 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1325 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1326 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1328 // Stall for 1 milliseconds.
1330 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
);
1506 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1509 Task
->Map
= BufferMap
;
1510 Task
->TableMap
= PrdTableMap
;
1511 Task
->MapBaseAddress
= (EFI_ATA_DMA_PRD
*)(UINTN
)BaseAddr
;
1512 Task
->PageCount
= RealPageCount
;
1513 Task
->IsStart
= TRUE
;
1517 // Issue ATA command
1519 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1521 if (EFI_ERROR (Status
)) {
1522 Status
= EFI_DEVICE_ERROR
;
1526 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1527 if (EFI_ERROR (Status
)) {
1528 Status
= EFI_DEVICE_ERROR
;
1532 // Set START bit of BMIC register
1534 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1535 RegisterValue
|= BMIC_START
;
1536 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1541 // Check the INTERRUPT and ERROR bit of BMIS
1544 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1546 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
, Timeout
);
1550 // For blocking mode, clear registers and free buffers.
1551 // For non blocking mode, when the related registers have been set or time
1552 // out, or a error has been happened, it needs to clear the register and free
1555 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1557 // Read BMIS register and clear ERROR and INTR bit
1559 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1560 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1561 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1564 // Read Status Register of IDE device to clear interrupt
1566 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1569 // Clear START bit of BMIC register
1571 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1572 RegisterValue
&= ~((UINT8
) BMIC_START
);
1573 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1576 // Disable interrupt of Select device
1578 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1579 DeviceControl
|= ATA_CTLREG_IEN_L
;
1580 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1582 // Stall for 10 milliseconds.
1584 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
);
1653 This function is called by AtaPacketCommandExecute().
1654 It is used to transfer data between host and device. The data direction is specified
1655 by the fourth parameter.
1657 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1658 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1659 @param Buffer Buffer contained data transferred between host and device.
1660 @param ByteCount Data size in byte unit of the buffer.
1661 @param Read Flag used to determine the data transfer direction.
1662 Read equals 1, means data transferred from device to host;
1663 Read equals 0, means data transferred from host to device.
1664 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1665 , uses 100ns as a unit.
1667 @retval EFI_SUCCESS data is transferred successfully.
1668 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1672 AtaPacketReadWrite (
1673 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1674 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1675 IN OUT VOID
*Buffer
,
1676 IN OUT UINT32
*ByteCount
,
1681 UINT32 RequiredWordCount
;
1682 UINT32 ActualWordCount
;
1688 RequiredWordCount
= *ByteCount
>> 1;
1691 // No data transfer is permitted.
1693 if (RequiredWordCount
== 0) {
1698 // ActualWordCount means the word count of data really transferred.
1700 ActualWordCount
= 0;
1702 while (ActualWordCount
< RequiredWordCount
) {
1704 // before each data transfer stream, the host should poll DRQ bit ready,
1705 // to see whether indicates device is ready to transfer data.
1707 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1708 if (EFI_ERROR (Status
)) {
1709 if (Status
== EFI_NOT_READY
) {
1711 // Device provided less data than we intended to read, or wanted less
1712 // data than we intended to write, but it may still be successful.
1721 // get current data transfer size from Cylinder Registers.
1723 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1724 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1725 WordCount
= WordCount
& 0xffff;
1728 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1731 IdeReadPortWMultiple (
1738 IdeWritePortWMultiple (
1747 // read status register to check whether error happens.
1749 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1750 if (EFI_ERROR (Status
)) {
1751 return EFI_DEVICE_ERROR
;
1754 PtrBuffer
+= WordCount
;
1755 ActualWordCount
+= WordCount
;
1760 // In the case where the drive wants to send more data than we need to read,
1761 // the DRQ bit will be set and cause delays from DRQClear2().
1762 // We need to read data from the drive until it clears DRQ so we can move on.
1764 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1768 // read status register to check whether error happens.
1770 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1771 if (EFI_ERROR (Status
)) {
1772 return EFI_DEVICE_ERROR
;
1776 // After data transfer is completed, normally, DRQ bit should clear.
1778 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1779 if (EFI_ERROR (Status
)) {
1780 return EFI_DEVICE_ERROR
;
1783 *ByteCount
= ActualWordCount
<< 1;
1788 This function is used to send out ATAPI commands conforms to the Packet Command
1789 with PIO Data In Protocol.
1791 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1792 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1793 store the IDE i/o port registers' base addresses
1794 @param[in] Channel The channel number of device.
1795 @param[in] Device The device number of device.
1796 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
1798 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1799 and device sends data successfully.
1800 @retval EFI_DEVICE_ERROR the device failed to send data.
1805 AtaPacketCommandExecute (
1806 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1807 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1810 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
1813 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1816 UINT8 PacketCommand
[12];
1818 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1821 // Fill ATAPI Command Packet according to CDB.
1822 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1824 if (Packet
->CdbLength
> 12) {
1825 return EFI_INVALID_PARAMETER
;
1828 ZeroMem (PacketCommand
, 12);
1829 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
1834 AtaCommandBlock
.AtaFeatures
= 0x00;
1836 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1837 // determine how many data should be transferred.
1839 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
1840 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
1841 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
1842 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
1844 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
1846 // Disable interrupt
1848 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
1851 // Issue ATA PACKET command firstly
1853 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
1854 if (EFI_ERROR (Status
)) {
1858 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
1859 if (EFI_ERROR (Status
)) {
1864 // Send out ATAPI command packet
1866 for (Count
= 0; Count
< 6; Count
++) {
1867 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
1869 // Stall for 10 microseconds.
1871 MicroSecondDelay (10);
1875 // Read/Write the data of ATAPI Command
1877 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
1878 Status
= AtaPacketReadWrite (
1881 Packet
->InDataBuffer
,
1882 &Packet
->InTransferLength
,
1887 Status
= AtaPacketReadWrite (
1890 Packet
->OutDataBuffer
,
1891 &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
2129 DEBUG ((DEBUG_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2130 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2131 REPORT_STATUS_CODE (
2132 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2133 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2137 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2139 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2141 REPORT_STATUS_CODE (
2143 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2146 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2148 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2149 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2150 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2151 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2152 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2155 // Send S.M.A.R.T Enable command to device
2157 Status
= AtaNonDataCommandIn (
2159 &Instance
->IdeRegisters
[Channel
],
2166 if (!EFI_ERROR (Status
)) {
2168 // Send S.M.A.R.T AutoSave command to device
2170 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2172 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2173 AtaCommandBlock
.AtaFeatures
= 0xD2;
2174 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2175 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2176 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2177 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2179 Status
= AtaNonDataCommandIn (
2181 &Instance
->IdeRegisters
[Channel
],
2187 if (!EFI_ERROR (Status
)) {
2188 Status
= IdeAtaSmartReturnStatusCheck (
2198 DEBUG ((DEBUG_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2199 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2208 Sends out an ATA Identify Command to the specified device.
2210 This function is called by DiscoverIdeDevice() during its device
2211 identification. It sends out the ATA Identify Command to the
2212 specified device. Only ATA device responses to this command. If
2213 the command succeeds, it returns the Identify data structure which
2214 contains information about the device. This function extracts the
2215 information it needs to fill the IDE_BLK_IO_DEV data structure,
2216 including device type, media block size, media capacity, and etc.
2218 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2219 @param Channel The channel number of device.
2220 @param Device The device number of device.
2221 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2222 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2224 @retval EFI_SUCCESS Identify ATA device successfully.
2225 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2226 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2232 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2235 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2236 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2240 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2242 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2244 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2245 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2247 Status
= AtaPioDataInOut (
2249 &Instance
->IdeRegisters
[Channel
],
2251 sizeof (EFI_IDENTIFY_DATA
),
2263 This function is called by DiscoverIdeDevice() during its device
2265 Its main purpose is to get enough information for the device media
2266 to fill in the Media data structure of the Block I/O Protocol interface.
2268 There are 5 steps to reach such objective:
2269 1. Sends out the ATAPI Identify Command to the specified device.
2270 Only ATAPI device responses to this command. If the command succeeds,
2271 it returns the Identify data structure which filled with information
2272 about the device. Since the ATAPI device contains removable media,
2273 the only meaningful information is the device module name.
2274 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2275 This command will return inquiry data of the device, which contains
2276 the device type information.
2277 3. Allocate sense data space for future use. We don't detect the media
2278 presence here to improvement boot performance, especially when CD
2279 media is present. The media detection will be performed just before
2280 each BLK_IO read/write
2282 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2283 @param Channel The channel number of device.
2284 @param Device The device number of device.
2285 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2286 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2288 @retval EFI_SUCCESS Identify ATAPI device successfully.
2289 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2290 is not supported by this IDE driver.
2291 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2297 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2300 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2301 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2305 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2307 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2309 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2310 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2313 // Send ATAPI Identify Command to get IDENTIFY data.
2315 Status
= AtaPioDataInOut (
2317 &Instance
->IdeRegisters
[Channel
],
2319 sizeof (EFI_IDENTIFY_DATA
),
2332 This function is used for detect whether the IDE device exists in the
2333 specified Channel as the specified Device Number.
2335 There is two IDE channels: one is Primary Channel, the other is
2336 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2337 Different channel has different register group.
2339 On each IDE channel, at most two IDE devices attach,
2340 one is called Device 0 (Master device), the other is called Device 1
2341 (Slave device). The devices on the same channel co-use the same register
2342 group, so before sending out a command for a specified device via command
2343 register, it is a must to select the current device to accept the command
2344 by set the device number in the Head/Device Register.
2346 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2347 @param IdeChannel The channel number of device.
2349 @retval EFI_SUCCESS successfully detects device.
2350 @retval other any failure during detection process will return this value.
2355 DetectAndConfigIdeDevice (
2356 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2361 UINT8 SectorCountReg
;
2365 EFI_ATA_DEVICE_TYPE DeviceType
;
2367 EFI_IDE_REGISTERS
*IdeRegisters
;
2368 EFI_IDENTIFY_DATA Buffer
;
2370 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2371 EFI_PCI_IO_PROTOCOL
*PciIo
;
2373 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2374 EFI_ATA_TRANSFER_MODE TransferMode
;
2375 EFI_ATA_DRIVE_PARMS DriveParameters
;
2377 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2378 IdeInit
= Instance
->IdeControllerInit
;
2379 PciIo
= Instance
->PciIo
;
2381 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2383 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2385 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2388 // Send ATA Device Execut Diagnostic command.
2389 // This command should work no matter DRDY is ready or not
2391 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2393 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2394 if (EFI_ERROR (Status
)) {
2395 DEBUG((DEBUG_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2400 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2402 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2404 // Stall for 1 milliseconds.
2406 MicroSecondDelay (1000);
2408 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2409 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2410 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2411 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2414 // Refer to ATA/ATAPI 4 Spec, section 9.1
2416 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2417 DeviceType
= EfiIdeHarddisk
;
2418 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2419 DeviceType
= EfiIdeCdrom
;
2425 // Send IDENTIFY cmd to the device to test if it is really attached.
2427 if (DeviceType
== EfiIdeHarddisk
) {
2428 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2430 // if identifying ata device is failure, then try to send identify packet cmd.
2432 if (EFI_ERROR (Status
)) {
2433 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2435 DeviceType
= EfiIdeCdrom
;
2436 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2439 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2441 // if identifying atapi device is failure, then try to send identify cmd.
2443 if (EFI_ERROR (Status
)) {
2444 DeviceType
= EfiIdeHarddisk
;
2445 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2449 if (EFI_ERROR (Status
)) {
2451 // No device is found at this port
2456 DEBUG ((DEBUG_INFO
, "[%a] channel [%a] [%a] device\n",
2457 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2458 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2460 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2462 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2463 IdeAtaSmartSupport (
2473 // Submit identify data to IDE controller init driver
2475 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2478 // Now start to config ide device parameter and transfer mode.
2480 Status
= IdeInit
->CalculateMode (
2486 if (EFI_ERROR (Status
)) {
2487 DEBUG ((DEBUG_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2492 // Set best supported PIO mode on this IDE device
2494 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2495 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2497 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2500 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2502 if (SupportedModes
->ExtModeCount
== 0){
2503 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2505 if (EFI_ERROR (Status
)) {
2506 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2512 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2513 // be set together. Only one DMA mode can be set to a device. If setting
2514 // DMA mode operation fails, we can continue moving on because we only use
2515 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2517 if (SupportedModes
->UdmaMode
.Valid
) {
2518 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2519 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2520 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2522 if (EFI_ERROR (Status
)) {
2523 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2526 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2527 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2528 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2529 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2531 if (EFI_ERROR (Status
)) {
2532 DEBUG ((DEBUG_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2538 // Set Parameters for the device:
2540 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2542 if (DeviceType
== EfiIdeHarddisk
) {
2544 // Init driver parameters
2546 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2547 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2548 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2550 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2554 // Set IDE controller Timing Blocks in the PCI Configuration Space
2556 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2559 // IDE controller and IDE device timing is configured successfully.
2560 // Now insert the device into device list.
2562 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2563 if (EFI_ERROR (Status
)) {
2567 if (DeviceType
== EfiIdeHarddisk
) {
2568 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2576 Initialize ATA host controller at IDE mode.
2578 The function is designed to initialize ATA host controller.
2580 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2585 IdeModeInitialization (
2586 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2590 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2591 EFI_PCI_IO_PROTOCOL
*PciIo
;
2594 BOOLEAN ChannelEnabled
;
2597 IdeInit
= Instance
->IdeControllerInit
;
2598 PciIo
= Instance
->PciIo
;
2599 Channel
= IdeInit
->ChannelCount
;
2602 // Obtain IDE IO port registers' base addresses
2604 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2605 if (EFI_ERROR (Status
)) {
2609 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2610 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2613 // now obtain channel information fron IdeControllerInit protocol.
2615 Status
= IdeInit
->GetChannelInfo (
2621 if (EFI_ERROR (Status
)) {
2622 DEBUG ((DEBUG_ERROR
, "[GetChannel, Status=%x]", Status
));
2626 if (!ChannelEnabled
) {
2630 ASSERT (MaxDevices
<= 2);
2632 // Now inform the IDE Controller Init Module.
2634 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2637 // No reset channel function implemented.
2639 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2642 // Now inform the IDE Controller Init Module.
2644 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2647 // Detect all attached ATA devices and set the transfer mode for each device.
2649 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2653 // All configurations done! Notify IdeController to do post initialization
2654 // work such as saving IDE controller PCI settings for S3 resume
2656 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);