2 Header file for AHCI mode of ATA host controller.
4 Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "AtaAtapiPassThru.h"
18 read a one-byte data from a IDE port.
20 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
21 @param Port The IDE Port number
23 @return the one-byte data read from IDE port
28 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
34 ASSERT (PciIo
!= NULL
);
38 // perform 1-byte data read from register
43 EFI_PCI_IO_PASS_THROUGH_BAR
,
52 write a 1-byte data to a specific IDE port.
54 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
55 @param Port The IDE port to be writen
56 @param Data The data to write to the port
61 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
66 ASSERT (PciIo
!= NULL
);
69 // perform 1-byte data write to register
74 EFI_PCI_IO_PASS_THROUGH_BAR
,
82 write a 1-word data to a specific IDE port.
84 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
85 @param Port The IDE port to be writen
86 @param Data The data to write to the port
91 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
96 ASSERT (PciIo
!= NULL
);
99 // perform 1-word data write to register
104 EFI_PCI_IO_PASS_THROUGH_BAR
,
112 write a 2-word data to a specific IDE port.
114 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
115 @param Port The IDE port to be writen
116 @param Data The data to write to the port
121 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
126 ASSERT (PciIo
!= NULL
);
129 // perform 2-word data write to register
134 EFI_PCI_IO_PASS_THROUGH_BAR
,
142 Write multiple words of data to the IDE data port.
143 Call the IO abstraction once to do the complete read,
144 not one word at a time
146 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
147 @param Port IO port to read
148 @param Count No. of UINT16's to read
149 @param Buffer Pointer to the data buffer for read
154 IdeWritePortWMultiple (
155 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
161 ASSERT (PciIo
!= NULL
);
162 ASSERT (Buffer
!= NULL
);
165 // perform UINT16 data write to the FIFO
169 EfiPciIoWidthFifoUint16
,
170 EFI_PCI_IO_PASS_THROUGH_BAR
,
179 Reads multiple words of data from the IDE data port.
180 Call the IO abstraction once to do the complete read,
181 not one word at a time
183 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure
184 @param Port IO port to read
185 @param Count Number of UINT16's to read
186 @param Buffer Pointer to the data buffer for read
191 IdeReadPortWMultiple (
192 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
198 ASSERT (PciIo
!= NULL
);
199 ASSERT (Buffer
!= NULL
);
202 // Perform UINT16 data read from FIFO
206 EfiPciIoWidthFifoUint16
,
207 EFI_PCI_IO_PASS_THROUGH_BAR
,
216 This function is used to analyze the Status Register and print out
217 some debug information and if there is ERR bit set in the Status
218 Register, the Error Register's value is also be parsed and print out.
220 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
221 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
222 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
227 DumpAllIdeRegisters (
228 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
229 IN EFI_IDE_REGISTERS
*IdeRegisters
,
230 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
233 EFI_ATA_STATUS_BLOCK StatusBlock
;
235 ASSERT (PciIo
!= NULL
);
236 ASSERT (IdeRegisters
!= NULL
);
238 ZeroMem (&StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
240 StatusBlock
.AtaStatus
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
241 StatusBlock
.AtaError
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
242 StatusBlock
.AtaSectorCount
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
243 StatusBlock
.AtaSectorCountExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
244 StatusBlock
.AtaSectorNumber
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
245 StatusBlock
.AtaSectorNumberExp
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
246 StatusBlock
.AtaCylinderLow
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
247 StatusBlock
.AtaCylinderLowExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
248 StatusBlock
.AtaCylinderHigh
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
249 StatusBlock
.AtaCylinderHighExp
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
250 StatusBlock
.AtaDeviceHead
= IdeReadPortB (PciIo
, IdeRegisters
->Head
);
252 if (AtaStatusBlock
!= NULL
) {
254 // Dump the content of all ATA registers.
256 CopyMem (AtaStatusBlock
, &StatusBlock
, sizeof (EFI_ATA_STATUS_BLOCK
));
260 if ((StatusBlock
.AtaStatus
& ATA_STSREG_DWF
) != 0) {
261 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock
.AtaStatus
));
264 if ((StatusBlock
.AtaStatus
& ATA_STSREG_CORR
) != 0) {
265 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock
.AtaStatus
));
268 if ((StatusBlock
.AtaStatus
& ATA_STSREG_ERR
) != 0) {
269 if ((StatusBlock
.AtaError
& ATA_ERRREG_BBK
) != 0) {
270 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock
.AtaError
));
273 if ((StatusBlock
.AtaError
& ATA_ERRREG_UNC
) != 0) {
274 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock
.AtaError
));
277 if ((StatusBlock
.AtaError
& ATA_ERRREG_MC
) != 0) {
278 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock
.AtaError
));
281 if ((StatusBlock
.AtaError
& ATA_ERRREG_ABRT
) != 0) {
282 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock
.AtaError
));
285 if ((StatusBlock
.AtaError
& ATA_ERRREG_TK0NF
) != 0) {
286 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock
.AtaError
));
289 if ((StatusBlock
.AtaError
& ATA_ERRREG_AMNF
) != 0) {
290 DEBUG ((EFI_D_ERROR
, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock
.AtaError
));
297 This function is used to analyze the Status Register at the condition that BSY is zero.
298 if there is ERR bit set in the Status Register, then return error.
300 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
301 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
303 @retval EFI_SUCCESS No err information in the Status Register.
304 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
309 CheckStatusRegister (
310 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
311 IN EFI_IDE_REGISTERS
*IdeRegisters
314 UINT8 StatusRegister
;
316 ASSERT (PciIo
!= NULL
);
317 ASSERT (IdeRegisters
!= NULL
);
319 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
321 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
322 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
325 return EFI_DEVICE_ERROR
;
332 This function is used to poll for the DRQ bit clear in the Status
333 Register. DRQ is cleared when the device is finished transferring data.
334 So this function is called after data transfer is finished.
336 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
337 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
338 @param Timeout The time to complete the command, uses 100ns as a unit.
340 @retval EFI_SUCCESS DRQ bit clear within the time out.
342 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
345 Read Status Register will clear interrupt status.
351 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
352 IN EFI_IDE_REGISTERS
*IdeRegisters
,
357 UINT8 StatusRegister
;
358 BOOLEAN InfiniteWait
;
360 ASSERT (PciIo
!= NULL
);
361 ASSERT (IdeRegisters
!= NULL
);
366 InfiniteWait
= FALSE
;
369 Delay
= DivU64x32(Timeout
, 1000) + 1;
371 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
374 // Wait for BSY == 0, then judge if DRQ is clear
376 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
377 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
378 return EFI_DEVICE_ERROR
;
385 // Stall for 100 microseconds.
387 MicroSecondDelay (100);
391 } while (InfiniteWait
|| (Delay
> 0));
396 This function is used to poll for the DRQ bit clear in the Alternate
397 Status Register. DRQ is cleared when the device is finished
398 transferring data. So this function is called after data transfer
401 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
402 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
403 @param Timeout The time to complete the command, uses 100ns as a unit.
405 @retval EFI_SUCCESS DRQ bit clear within the time out.
407 @retval EFI_TIMEOUT DRQ bit not clear within the time out.
408 @note Read Alternate Status Register will not clear interrupt status.
414 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
415 IN EFI_IDE_REGISTERS
*IdeRegisters
,
421 BOOLEAN InfiniteWait
;
423 ASSERT (PciIo
!= NULL
);
424 ASSERT (IdeRegisters
!= NULL
);
429 InfiniteWait
= FALSE
;
432 Delay
= DivU64x32(Timeout
, 1000) + 1;
434 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
437 // Wait for BSY == 0, then judge if DRQ is clear
439 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
440 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
441 return EFI_DEVICE_ERROR
;
448 // Stall for 100 microseconds.
450 MicroSecondDelay (100);
454 } while (InfiniteWait
|| (Delay
> 0));
460 This function is used to poll for the DRQ bit set in the
462 DRQ is set when the device is ready to transfer data. So this function
463 is called after the command is sent to the device and before required
466 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
467 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
468 @param Timeout The time to complete the command, uses 100ns as a unit.
470 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
473 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
475 @retval EFI_ABORTED Polling abandoned due to command abort.
477 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
479 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
480 reported "command complete" by clearing DRQ
483 @note Read Status Register will clear interrupt status.
489 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
490 IN EFI_IDE_REGISTERS
*IdeRegisters
,
495 UINT8 StatusRegister
;
497 BOOLEAN InfiniteWait
;
499 ASSERT (PciIo
!= NULL
);
500 ASSERT (IdeRegisters
!= NULL
);
505 InfiniteWait
= FALSE
;
508 Delay
= DivU64x32(Timeout
, 1000) + 1;
511 // Read Status Register will clear interrupt
513 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
516 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
518 if ((StatusRegister
& ATA_STSREG_BSY
) == 0) {
519 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
520 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
522 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
525 return EFI_DEVICE_ERROR
;
528 if ((StatusRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
531 return EFI_NOT_READY
;
536 // Stall for 100 microseconds.
538 MicroSecondDelay (100);
541 } while (InfiniteWait
|| (Delay
> 0));
546 This function is used to poll for the DRQ bit set in the Alternate Status Register.
547 DRQ is set when the device is ready to transfer data. So this function is called after
548 the command is sent to the device and before required data is transferred.
550 @param PciIo A pointer to EFI_PCI_IO_PROTOCOL data structure.
551 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
552 @param Timeout The time to complete the command, uses 100ns as a unit.
554 @retval EFI_SUCCESS BSY bit cleared and DRQ bit set within the
557 @retval EFI_TIMEOUT BSY bit not cleared within the timeout.
559 @retval EFI_ABORTED Polling abandoned due to command abort.
561 @retval EFI_DEVICE_ERROR Polling abandoned due to a non-abort error.
563 @retval EFI_NOT_READY BSY bit cleared within timeout, and device
564 reported "command complete" by clearing DRQ
567 @note Read Alternate Status Register will not clear interrupt status.
573 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
574 IN EFI_IDE_REGISTERS
*IdeRegisters
,
581 BOOLEAN InfiniteWait
;
583 ASSERT (PciIo
!= NULL
);
584 ASSERT (IdeRegisters
!= NULL
);
589 InfiniteWait
= FALSE
;
592 Delay
= DivU64x32(Timeout
, 1000) + 1;
596 // Read Alternate Status Register will not clear interrupt status
598 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
600 // Wait for BSY == 0, then judge if DRQ is clear or ERR is set
602 if ((AltRegister
& ATA_STSREG_BSY
) == 0) {
603 if ((AltRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
604 ErrorRegister
= IdeReadPortB (PciIo
, IdeRegisters
->ErrOrFeature
);
606 if ((ErrorRegister
& ATA_ERRREG_ABRT
) == ATA_ERRREG_ABRT
) {
609 return EFI_DEVICE_ERROR
;
612 if ((AltRegister
& ATA_STSREG_DRQ
) == ATA_STSREG_DRQ
) {
615 return EFI_NOT_READY
;
620 // Stall for 100 microseconds.
622 MicroSecondDelay (100);
625 } while (InfiniteWait
|| (Delay
> 0));
634 This function is used to poll for the BSY bit clear in the Status Register. BSY
635 is clear when the device is not busy. Every command must be sent after device is not busy.
637 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
638 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
639 @param Timeout The time to complete the command, uses 100ns as a unit.
641 @retval EFI_SUCCESS BSY bit clear within the time out.
642 @retval EFI_TIMEOUT BSY bit not clear within the time out.
644 @note Read Status Register will clear interrupt status.
649 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
650 IN EFI_IDE_REGISTERS
*IdeRegisters
,
655 UINT8 StatusRegister
;
656 BOOLEAN InfiniteWait
;
658 ASSERT (PciIo
!= NULL
);
659 ASSERT (IdeRegisters
!= NULL
);
664 InfiniteWait
= FALSE
;
667 Delay
= DivU64x32(Timeout
, 1000) + 1;
669 StatusRegister
= IdeReadPortB (PciIo
, IdeRegisters
->CmdOrStatus
);
671 if ((StatusRegister
& ATA_STSREG_BSY
) == 0x00) {
676 // Stall for 100 microseconds.
678 MicroSecondDelay (100);
682 } while (InfiniteWait
|| (Delay
> 0));
689 Get IDE i/o port registers' base addresses by mode.
691 In 'Compatibility' mode, use fixed addresses.
692 In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
695 The steps to get IDE i/o port registers' base addresses for each channel
698 1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
699 controller's Configuration Space to determine the operating mode.
701 2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
702 ___________________________________________
703 | | Command Block | Control Block |
704 | Channel | Registers | Registers |
705 |___________|_______________|_______________|
706 | Primary | 1F0h - 1F7h | 3F6h - 3F7h |
707 |___________|_______________|_______________|
708 | Secondary | 170h - 177h | 376h - 377h |
709 |___________|_______________|_______________|
711 Table 1. Compatibility resource mappings
713 b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
714 in IDE controller's PCI Configuration Space, shown in the Table 2 below.
715 ___________________________________________________
716 | | Command Block | Control Block |
717 | Channel | Registers | Registers |
718 |___________|___________________|___________________|
719 | Primary | BAR at offset 0x10| BAR at offset 0x14|
720 |___________|___________________|___________________|
721 | Secondary | BAR at offset 0x18| BAR at offset 0x1C|
722 |___________|___________________|___________________|
724 Table 2. BARs for Register Mapping
726 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
727 @param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
728 store the IDE i/o port registers' base addresses
730 @retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
731 @retval EFI_SUCCESS Get the Base address successfully
732 @retval Other Read the pci configureation data error
737 GetIdeRegisterIoAddr (
738 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
739 IN OUT EFI_IDE_REGISTERS
*IdeRegisters
744 UINT16 CommandBlockBaseAddr
;
745 UINT16 ControlBlockBaseAddr
;
746 UINT16 BusMasterBaseAddr
;
748 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
)) {
749 return EFI_INVALID_PARAMETER
;
752 Status
= PciIo
->Pci
.Read (
760 if (EFI_ERROR (Status
)) {
764 BusMasterBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[4] & 0x0000fff0));
766 if ((PciData
.Hdr
.ClassCode
[0] & IDE_PRIMARY_OPERATING_MODE
) == 0) {
767 CommandBlockBaseAddr
= 0x1f0;
768 ControlBlockBaseAddr
= 0x3f6;
771 // The BARs should be of IO type
773 if ((PciData
.Device
.Bar
[0] & BIT0
) == 0 ||
774 (PciData
.Device
.Bar
[1] & BIT0
) == 0) {
775 return EFI_UNSUPPORTED
;
778 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[0] & 0x0000fff8);
779 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[1] & 0x0000fffc) + 2);
783 // Calculate IDE primary channel I/O register base address.
785 IdeRegisters
[EfiIdePrimary
].Data
= CommandBlockBaseAddr
;
786 IdeRegisters
[EfiIdePrimary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
787 IdeRegisters
[EfiIdePrimary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
788 IdeRegisters
[EfiIdePrimary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
789 IdeRegisters
[EfiIdePrimary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
790 IdeRegisters
[EfiIdePrimary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
791 IdeRegisters
[EfiIdePrimary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
792 IdeRegisters
[EfiIdePrimary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
793 IdeRegisters
[EfiIdePrimary
].AltOrDev
= ControlBlockBaseAddr
;
794 IdeRegisters
[EfiIdePrimary
].BusMasterBaseAddr
= BusMasterBaseAddr
;
796 if ((PciData
.Hdr
.ClassCode
[0] & IDE_SECONDARY_OPERATING_MODE
) == 0) {
797 CommandBlockBaseAddr
= 0x170;
798 ControlBlockBaseAddr
= 0x376;
801 // The BARs should be of IO type
803 if ((PciData
.Device
.Bar
[2] & BIT0
) == 0 ||
804 (PciData
.Device
.Bar
[3] & BIT0
) == 0) {
805 return EFI_UNSUPPORTED
;
808 CommandBlockBaseAddr
= (UINT16
) (PciData
.Device
.Bar
[2] & 0x0000fff8);
809 ControlBlockBaseAddr
= (UINT16
) ((PciData
.Device
.Bar
[3] & 0x0000fffc) + 2);
813 // Calculate IDE secondary channel I/O register base address.
815 IdeRegisters
[EfiIdeSecondary
].Data
= CommandBlockBaseAddr
;
816 IdeRegisters
[EfiIdeSecondary
].ErrOrFeature
= (UINT16
) (CommandBlockBaseAddr
+ 0x01);
817 IdeRegisters
[EfiIdeSecondary
].SectorCount
= (UINT16
) (CommandBlockBaseAddr
+ 0x02);
818 IdeRegisters
[EfiIdeSecondary
].SectorNumber
= (UINT16
) (CommandBlockBaseAddr
+ 0x03);
819 IdeRegisters
[EfiIdeSecondary
].CylinderLsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x04);
820 IdeRegisters
[EfiIdeSecondary
].CylinderMsb
= (UINT16
) (CommandBlockBaseAddr
+ 0x05);
821 IdeRegisters
[EfiIdeSecondary
].Head
= (UINT16
) (CommandBlockBaseAddr
+ 0x06);
822 IdeRegisters
[EfiIdeSecondary
].CmdOrStatus
= (UINT16
) (CommandBlockBaseAddr
+ 0x07);
823 IdeRegisters
[EfiIdeSecondary
].AltOrDev
= ControlBlockBaseAddr
;
824 IdeRegisters
[EfiIdeSecondary
].BusMasterBaseAddr
= (UINT16
) (BusMasterBaseAddr
+ 0x8);
831 Send ATA Ext command into device with NON_DATA protocol.
833 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
834 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
835 @param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
836 @param Timeout The time to complete the command, uses 100ns as a unit.
838 @retval EFI_SUCCESS Reading succeed
839 @retval EFI_DEVICE_ERROR Error executing commands on this device.
845 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
846 IN EFI_IDE_REGISTERS
*IdeRegisters
,
847 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
855 ASSERT (PciIo
!= NULL
);
856 ASSERT (IdeRegisters
!= NULL
);
857 ASSERT (AtaCommandBlock
!= NULL
);
859 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
860 AtaCommand
= AtaCommandBlock
->AtaCommand
;
862 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
863 if (EFI_ERROR (Status
)) {
864 return EFI_DEVICE_ERROR
;
868 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
870 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
) (0xe0 | DeviceHead
));
873 // set all the command parameters
874 // Before write to all the following registers, BSY and DRQ must be 0.
876 Status
= DRQClear2 (PciIo
, IdeRegisters
, Timeout
);
877 if (EFI_ERROR (Status
)) {
878 return EFI_DEVICE_ERROR
;
882 // Fill the feature register, which is a two-byte FIFO. Need write twice.
884 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeaturesExp
);
885 IdeWritePortB (PciIo
, IdeRegisters
->ErrOrFeature
, AtaCommandBlock
->AtaFeatures
);
888 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
890 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCountExp
);
891 IdeWritePortB (PciIo
, IdeRegisters
->SectorCount
, AtaCommandBlock
->AtaSectorCount
);
894 // Fill the start LBA registers, which are also two-byte FIFO
896 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumberExp
);
897 IdeWritePortB (PciIo
, IdeRegisters
->SectorNumber
, AtaCommandBlock
->AtaSectorNumber
);
899 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLowExp
);
900 IdeWritePortB (PciIo
, IdeRegisters
->CylinderLsb
, AtaCommandBlock
->AtaCylinderLow
);
902 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHighExp
);
903 IdeWritePortB (PciIo
, IdeRegisters
->CylinderMsb
, AtaCommandBlock
->AtaCylinderHigh
);
906 // Send command via Command Register
908 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, AtaCommand
);
911 // Stall at least 400 microseconds.
913 MicroSecondDelay (400);
919 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
921 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
923 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
924 @param[in, out] Buffer A pointer to the source buffer for the data.
925 @param[in] ByteCount The length of the data.
926 @param[in] Read Flag used to determine the data transfer direction.
927 Read equals 1, means data transferred from device
928 to host;Read equals 0, means data transferred
930 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
931 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
932 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
933 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
934 used by non-blocking mode.
936 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
937 @retval EFI_DEVICE_ERROR command sent failed.
943 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
944 IN EFI_IDE_REGISTERS
*IdeRegisters
,
948 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
949 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
951 IN ATA_NONBLOCK_TASK
*Task
959 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (Buffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
960 return EFI_INVALID_PARAMETER
;
966 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
967 if (EFI_ERROR (Status
)) {
968 Status
= EFI_DEVICE_ERROR
;
972 Buffer16
= (UINT16
*) Buffer
;
975 // According to PIO data in protocol, host can perform a series of reads to
976 // the data register after each time device set DRQ ready;
977 // The data size of "a series of read" is command specific.
978 // For most ATA command, data size received from device will not exceed
979 // 1 sector, hence the data size for "a series of read" can be the whole data
980 // size of one command request.
981 // For ATA command such as Read Sector command, the data size of one ATA
982 // command request is often larger than 1 sector, according to the
983 // Read Sector command, the data size of "a series of read" is exactly 1
985 // Here for simplification reason, we specify the data size for
986 // "a series of read" to 1 sector (256 words) if data size of one ATA command
987 // request is larger than 256 words.
992 // used to record bytes of currently transfered data
996 while (WordCount
< RShiftU64(ByteCount
, 1)) {
998 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready
1000 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1001 if (EFI_ERROR (Status
)) {
1002 Status
= EFI_DEVICE_ERROR
;
1007 // Get the byte count for one series of read
1009 if ((WordCount
+ Increment
) > RShiftU64(ByteCount
, 1)) {
1010 Increment
= (UINTN
)(RShiftU64(ByteCount
, 1) - WordCount
);
1014 IdeReadPortWMultiple (
1021 IdeWritePortWMultiple (
1029 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1030 if (EFI_ERROR (Status
)) {
1031 Status
= EFI_DEVICE_ERROR
;
1035 WordCount
+= Increment
;
1036 Buffer16
+= Increment
;
1039 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1040 if (EFI_ERROR (Status
)) {
1041 Status
= EFI_DEVICE_ERROR
;
1047 // Dump All Ide registers to ATA_STATUS_BLOCK
1049 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1052 // Not support the Non-blocking now,just do the blocking process.
1058 Send ATA command into device with NON_DATA protocol
1060 @param[in] PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE
1062 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1063 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data
1065 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1066 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1067 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1068 used by non-blocking mode.
1070 @retval EFI_SUCCESS Reading succeed
1071 @retval EFI_ABORTED Command failed
1072 @retval EFI_DEVICE_ERROR Device status error.
1077 AtaNonDataCommandIn (
1078 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1079 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1080 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1081 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1083 IN ATA_NONBLOCK_TASK
*Task
1088 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (AtaCommandBlock
== NULL
)) {
1089 return EFI_INVALID_PARAMETER
;
1093 // Issue ATA command
1095 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1096 if (EFI_ERROR (Status
)) {
1097 Status
= EFI_DEVICE_ERROR
;
1102 // Wait for command completion
1104 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, Timeout
);
1105 if (EFI_ERROR (Status
)) {
1106 Status
= EFI_DEVICE_ERROR
;
1110 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1111 if (EFI_ERROR (Status
)) {
1112 Status
= EFI_DEVICE_ERROR
;
1118 // Dump All Ide registers to ATA_STATUS_BLOCK
1120 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1123 // Not support the Non-blocking now,just do the blocking process.
1129 Wait for memory to be set.
1131 @param[in] PciIo The PCI IO protocol instance.
1132 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1133 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1135 @retval EFI_DEVICE_ERROR The memory is not set.
1136 @retval EFI_TIMEOUT The memory setting is time out.
1137 @retval EFI_SUCCESS The memory is correct set.
1142 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1143 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1147 UINT8 RegisterValue
;
1149 UINT16 IoPortForBmis
;
1151 BOOLEAN InfiniteWait
;
1154 InfiniteWait
= TRUE
;
1156 InfiniteWait
= FALSE
;
1159 Delay
= DivU64x32 (Timeout
, 1000) + 1;
1162 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1163 if (EFI_ERROR (Status
)) {
1164 Status
= EFI_DEVICE_ERROR
;
1168 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1169 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1170 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Timeout
== 0)) {
1171 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1172 Status
= EFI_DEVICE_ERROR
;
1176 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1177 Status
= EFI_SUCCESS
;
1181 // Stall for 100 microseconds.
1183 MicroSecondDelay (100);
1185 } while (InfiniteWait
|| (Delay
> 0));
1191 Check if the memory to be set.
1193 @param[in] PciIo The PCI IO protocol instance.
1194 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1195 used by non-blocking mode.
1196 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1198 @retval EFI_DEVICE_ERROR The memory setting met a issue.
1199 @retval EFI_NOT_READY The memory is not set.
1200 @retval EFI_TIMEOUT The memory setting is time out.
1201 @retval EFI_SUCCESS The memory is correct set.
1206 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1207 IN ATA_NONBLOCK_TASK
*Task
,
1208 IN EFI_IDE_REGISTERS
*IdeRegisters
1211 UINT8 RegisterValue
;
1212 UINT16 IoPortForBmis
;
1217 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1218 if (EFI_ERROR (Status
)) {
1219 return EFI_DEVICE_ERROR
;
1222 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1223 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1225 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1226 DEBUG ((EFI_D_ERROR
, "ATA UDMA operation fails\n"));
1227 return EFI_DEVICE_ERROR
;
1230 if ((RegisterValue
& BMIS_INTERRUPT
) != 0) {
1234 if (!Task
->InfiniteWait
&& (Task
->RetryTimes
== 0)) {
1238 // The memory is not set.
1240 return EFI_NOT_READY
;
1245 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1247 @param[in] Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data
1249 @param[in] IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1250 @param[in] Read Flag used to determine the data transfer
1251 direction. Read equals 1, means data transferred
1252 from device to host;Read equals 0, means data
1253 transferred from host to device.
1254 @param[in] DataBuffer A pointer to the source buffer for the data.
1255 @param[in] DataLength The length of the data.
1256 @param[in] AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
1257 @param[in, out] AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1258 @param[in] Timeout The time to complete the command, uses 100ns as a unit.
1259 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1260 used by non-blocking mode.
1262 @retval EFI_SUCCESS the operation is successful.
1263 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1264 @retval EFI_UNSUPPORTED Unknown channel or operations command
1265 @retval EFI_DEVICE_ERROR Ata command execute failed
1271 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1272 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1274 IN VOID
*DataBuffer
,
1275 IN UINT64 DataLength
,
1276 IN EFI_ATA_COMMAND_BLOCK
*AtaCommandBlock
,
1277 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
,
1279 IN ATA_NONBLOCK_TASK
*Task
1283 UINT16 IoPortForBmic
;
1284 UINT16 IoPortForBmis
;
1285 UINT16 IoPortForBmid
;
1288 EFI_PHYSICAL_ADDRESS PrdTableMapAddr
;
1290 EFI_PHYSICAL_ADDRESS PrdTableBaseAddr
;
1291 EFI_ATA_DMA_PRD
*TempPrdBaseAddr
;
1294 UINT8 RegisterValue
;
1297 UINTN ByteRemaining
;
1298 UINT8 DeviceControl
;
1301 EFI_PHYSICAL_ADDRESS BufferMapAddress
;
1302 EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
;
1305 EFI_PCI_IO_PROTOCOL
*PciIo
;
1308 UINTN AlignmentMask
;
1309 UINTN RealPageCount
;
1310 EFI_PHYSICAL_ADDRESS BaseAddr
;
1311 EFI_PHYSICAL_ADDRESS BaseMapAddr
;
1313 Status
= EFI_SUCCESS
;
1319 PciIo
= Instance
->PciIo
;
1321 if ((PciIo
== NULL
) || (IdeRegisters
== NULL
) || (DataBuffer
== NULL
) || (AtaCommandBlock
== NULL
)) {
1322 return EFI_INVALID_PARAMETER
;
1326 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1328 // Delay 1ms to simulate the blocking time out checking.
1330 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1331 while ((Task
== NULL
) && (!IsListEmpty (&Instance
->NonBlockingTaskList
))) {
1332 AsyncNonBlockingTransferRoutine (NULL
, Instance
);
1334 // Stall for 1 milliseconds.
1336 MicroSecondDelay (1000);
1338 gBS
->RestoreTPL (OldTpl
);
1341 // The data buffer should be even alignment
1343 if (((UINTN
)DataBuffer
& 0x1) != 0) {
1344 return EFI_INVALID_PARAMETER
;
1348 // Set relevant IO Port address.
1350 IoPortForBmic
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIC_OFFSET
);
1351 IoPortForBmis
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMIS_OFFSET
);
1352 IoPortForBmid
= (UINT16
) (IdeRegisters
->BusMasterBaseAddr
+ BMID_OFFSET
);
1355 // For Blocking mode, start the command.
1356 // For non-blocking mode, when the command is not started, start it, otherwise
1357 // go to check the status.
1359 if (((Task
!= NULL
) && (!Task
->IsStart
)) || (Task
== NULL
)) {
1361 // Calculate the number of PRD entry.
1362 // Every entry in PRD table can specify a 64K memory region.
1364 PrdTableNum
= (UINTN
)(RShiftU64(DataLength
, 16) + 1);
1367 // Make sure that the memory region of PRD table is not cross 64K boundary
1369 PrdTableSize
= PrdTableNum
* sizeof (EFI_ATA_DMA_PRD
);
1370 if (PrdTableSize
> 0x10000) {
1371 return EFI_INVALID_PARAMETER
;
1375 // Allocate buffer for PRD table initialization.
1376 // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte
1377 // boundary and the table cannot cross a 64K boundary in memory.
1379 PageCount
= EFI_SIZE_TO_PAGES (PrdTableSize
);
1380 RealPageCount
= PageCount
+ EFI_SIZE_TO_PAGES (SIZE_64KB
);
1383 // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.
1385 ASSERT (RealPageCount
> PageCount
);
1387 Status
= PciIo
->AllocateBuffer (
1390 EfiBootServicesData
,
1395 if (EFI_ERROR (Status
)) {
1396 return EFI_OUT_OF_RESOURCES
;
1399 ByteCount
= EFI_PAGES_TO_SIZE (RealPageCount
);
1400 Status
= PciIo
->Map (
1402 EfiPciIoOperationBusMasterCommonBuffer
,
1403 (VOID
*)(UINTN
)BaseAddr
,
1408 if (EFI_ERROR (Status
) || (ByteCount
!= EFI_PAGES_TO_SIZE (RealPageCount
))) {
1410 // If the data length actually mapped is not equal to the requested amount,
1411 // it means the DMA operation may be broken into several discontinuous smaller chunks.
1412 // Can't handle this case.
1414 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1415 return EFI_OUT_OF_RESOURCES
;
1418 ZeroMem ((VOID
*) ((UINTN
) BaseAddr
), ByteCount
);
1421 // Calculate the 64K align address as PRD Table base address.
1423 AlignmentMask
= SIZE_64KB
- 1;
1424 PrdTableBaseAddr
= ((UINTN
) BaseAddr
+ AlignmentMask
) & ~AlignmentMask
;
1425 PrdTableMapAddr
= ((UINTN
) BaseMapAddr
+ AlignmentMask
) & ~AlignmentMask
;
1428 // Map the host address of DataBuffer to DMA master address.
1431 PciIoOperation
= EfiPciIoOperationBusMasterWrite
;
1433 PciIoOperation
= EfiPciIoOperationBusMasterRead
;
1436 ByteCount
= (UINTN
)DataLength
;
1437 Status
= PciIo
->Map (
1445 if (EFI_ERROR (Status
) || (ByteCount
!= DataLength
)) {
1446 PciIo
->Unmap (PciIo
, PrdTableMap
);
1447 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1448 return EFI_OUT_OF_RESOURCES
;
1452 // According to Ata spec, it requires the buffer address and size to be even.
1454 ASSERT ((BufferMapAddress
& 0x1) == 0);
1455 ASSERT ((ByteCount
& 0x1) == 0);
1458 // Fill the PRD table with appropriate bus master address of data buffer and data length.
1460 ByteRemaining
= ByteCount
;
1461 TempPrdBaseAddr
= (EFI_ATA_DMA_PRD
*)(UINTN
)PrdTableBaseAddr
;
1462 while (ByteRemaining
!= 0) {
1463 if (ByteRemaining
<= 0x10000) {
1464 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1465 TempPrdBaseAddr
->ByteCount
= (UINT16
) ByteRemaining
;
1466 TempPrdBaseAddr
->EndOfTable
= 0x8000;
1470 TempPrdBaseAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) BufferMapAddress
);
1471 TempPrdBaseAddr
->ByteCount
= (UINT16
) 0x0;
1473 ByteRemaining
-= 0x10000;
1474 BufferMapAddress
+= 0x10000;
1479 // Start to enable the DMA operation
1481 DeviceHead
= AtaCommandBlock
->AtaDeviceHead
;
1483 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | DeviceHead
));
1486 // Enable interrupt to support UDMA
1489 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1492 // Read BMIS register and clear ERROR and INTR bit
1494 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmis
);
1495 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1496 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1499 // Set the base address to BMID register
1501 IdeWritePortDW (PciIo
, IoPortForBmid
, (UINT32
)PrdTableMapAddr
);
1504 // Set BMIC register to identify the operation direction
1506 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1508 RegisterValue
|= BMIC_NREAD
;
1510 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1512 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1515 Task
->Map
= BufferMap
;
1516 Task
->TableMap
= PrdTableMap
;
1517 Task
->MapBaseAddress
= (EFI_ATA_DMA_PRD
*)(UINTN
)BaseAddr
;
1518 Task
->PageCount
= RealPageCount
;
1519 Task
->IsStart
= TRUE
;
1523 // Issue ATA command
1525 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, AtaCommandBlock
, Timeout
);
1527 if (EFI_ERROR (Status
)) {
1528 Status
= EFI_DEVICE_ERROR
;
1532 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1533 if (EFI_ERROR (Status
)) {
1534 Status
= EFI_DEVICE_ERROR
;
1538 // Set START bit of BMIC register
1540 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1541 RegisterValue
|= BMIC_START
;
1542 IdeWritePortB(PciIo
, IoPortForBmic
, RegisterValue
);
1547 // Check the INTERRUPT and ERROR bit of BMIS
1550 Status
= AtaUdmStatusCheck (PciIo
, Task
, IdeRegisters
);
1552 Status
= AtaUdmStatusWait (PciIo
, IdeRegisters
, Timeout
);
1556 // For blocking mode, clear registers and free buffers.
1557 // For non blocking mode, when the related registers have been set or time
1558 // out, or a error has been happened, it needs to clear the register and free
1561 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1563 // Read BMIS register and clear ERROR and INTR bit
1565 RegisterValue
= IdeReadPortB (PciIo
, IoPortForBmis
);
1566 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1567 IdeWritePortB (PciIo
, IoPortForBmis
, RegisterValue
);
1570 // Read Status Register of IDE device to clear interrupt
1572 RegisterValue
= IdeReadPortB(PciIo
, IdeRegisters
->CmdOrStatus
);
1575 // Clear START bit of BMIC register
1577 RegisterValue
= IdeReadPortB(PciIo
, IoPortForBmic
);
1578 RegisterValue
&= ~((UINT8
) BMIC_START
);
1579 IdeWritePortB (PciIo
, IoPortForBmic
, RegisterValue
);
1582 // Disable interrupt of Select device
1584 DeviceControl
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1585 DeviceControl
|= ATA_CTLREG_IEN_L
;
1586 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, DeviceControl
);
1588 // Stall for 10 milliseconds.
1590 MicroSecondDelay (10000);
1596 // Free all allocated resource
1598 if ((Task
== NULL
) || Status
!= EFI_NOT_READY
) {
1600 PciIo
->Unmap (PciIo
, Task
->TableMap
);
1601 PciIo
->FreeBuffer (PciIo
, Task
->PageCount
, Task
->MapBaseAddress
);
1602 PciIo
->Unmap (PciIo
, Task
->Map
);
1604 PciIo
->Unmap (PciIo
, PrdTableMap
);
1605 PciIo
->FreeBuffer (PciIo
, RealPageCount
, (VOID
*)(UINTN
)BaseAddr
);
1606 PciIo
->Unmap (PciIo
, BufferMap
);
1610 // Dump All Ide registers to ATA_STATUS_BLOCK
1612 DumpAllIdeRegisters (PciIo
, IdeRegisters
, AtaStatusBlock
);
1619 This function reads the pending data in the device.
1621 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1622 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1624 @retval EFI_SUCCESS Successfully read.
1625 @retval EFI_NOT_READY The BSY is set avoiding reading.
1630 AtaPacketReadPendingData (
1631 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1632 IN EFI_IDE_REGISTERS
*IdeRegisters
1636 UINT16 TempWordBuffer
;
1638 AltRegister
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1639 if ((AltRegister
& ATA_STSREG_BSY
) == ATA_STSREG_BSY
) {
1640 return EFI_NOT_READY
;
1643 if ((AltRegister
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1644 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1645 while ((TempWordBuffer
& (ATA_STSREG_BSY
| ATA_STSREG_DRQ
)) == ATA_STSREG_DRQ
) {
1646 IdeReadPortWMultiple (
1652 TempWordBuffer
= IdeReadPortB (PciIo
, IdeRegisters
->AltOrDev
);
1659 This function is called by AtaPacketCommandExecute().
1660 It is used to transfer data between host and device. The data direction is specified
1661 by the fourth parameter.
1663 @param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1664 @param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
1665 @param Buffer Buffer contained data transferred between host and device.
1666 @param ByteCount Data size in byte unit of the buffer.
1667 @param Read Flag used to determine the data transfer direction.
1668 Read equals 1, means data transferred from device to host;
1669 Read equals 0, means data transferred from host to device.
1670 @param Timeout Timeout value for wait DRQ ready before each data stream's transfer
1671 , uses 100ns as a unit.
1673 @retval EFI_SUCCESS data is transferred successfully.
1674 @retval EFI_DEVICE_ERROR the device failed to transfer data.
1678 AtaPacketReadWrite (
1679 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1680 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1681 IN OUT VOID
*Buffer
,
1682 IN OUT UINT32
*ByteCount
,
1687 UINT32 RequiredWordCount
;
1688 UINT32 ActualWordCount
;
1694 RequiredWordCount
= *ByteCount
>> 1;
1697 // No data transfer is premitted.
1699 if (RequiredWordCount
== 0) {
1704 // ActualWordCount means the word count of data really transferred.
1706 ActualWordCount
= 0;
1708 while (ActualWordCount
< RequiredWordCount
) {
1710 // before each data transfer stream, the host should poll DRQ bit ready,
1711 // to see whether indicates device is ready to transfer data.
1713 Status
= DRQReady2 (PciIo
, IdeRegisters
, Timeout
);
1714 if (EFI_ERROR (Status
)) {
1715 if (Status
== EFI_NOT_READY
) {
1717 // Device provided less data than we intended to read, or wanted less
1718 // data than we intended to write, but it may still be successful.
1727 // get current data transfer size from Cylinder Registers.
1729 WordCount
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
) << 8;
1730 WordCount
= WordCount
| IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
1731 WordCount
= WordCount
& 0xffff;
1734 WordCount
= MIN (WordCount
, (RequiredWordCount
- ActualWordCount
));
1737 IdeReadPortWMultiple (
1744 IdeWritePortWMultiple (
1753 // read status register to check whether error happens.
1755 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1756 if (EFI_ERROR (Status
)) {
1757 return EFI_DEVICE_ERROR
;
1760 PtrBuffer
+= WordCount
;
1761 ActualWordCount
+= WordCount
;
1766 // In the case where the drive wants to send more data than we need to read,
1767 // the DRQ bit will be set and cause delays from DRQClear2().
1768 // We need to read data from the drive until it clears DRQ so we can move on.
1770 AtaPacketReadPendingData (PciIo
, IdeRegisters
);
1774 // read status register to check whether error happens.
1776 Status
= CheckStatusRegister (PciIo
, IdeRegisters
);
1777 if (EFI_ERROR (Status
)) {
1778 return EFI_DEVICE_ERROR
;
1782 // After data transfer is completed, normally, DRQ bit should clear.
1784 Status
= DRQClear (PciIo
, IdeRegisters
, Timeout
);
1785 if (EFI_ERROR (Status
)) {
1786 return EFI_DEVICE_ERROR
;
1789 *ByteCount
= ActualWordCount
<< 1;
1794 This function is used to send out ATAPI commands conforms to the Packet Command
1795 with PIO Data In Protocol.
1797 @param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
1798 @param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
1799 store the IDE i/o port registers' base addresses
1800 @param[in] Channel The channel number of device.
1801 @param[in] Device The device number of device.
1802 @param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
1804 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1805 and device sends data successfully.
1806 @retval EFI_DEVICE_ERROR the device failed to send data.
1811 AtaPacketCommandExecute (
1812 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1813 IN EFI_IDE_REGISTERS
*IdeRegisters
,
1816 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET
*Packet
1819 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1822 UINT8 PacketCommand
[12];
1824 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1827 // Fill ATAPI Command Packet according to CDB.
1828 // For Atapi cmd, its length should be less than or equal to 12 bytes.
1830 if (Packet
->CdbLength
> 12) {
1831 return EFI_INVALID_PARAMETER
;
1834 ZeroMem (PacketCommand
, 12);
1835 CopyMem (PacketCommand
, Packet
->Cdb
, Packet
->CdbLength
);
1840 AtaCommandBlock
.AtaFeatures
= 0x00;
1842 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1843 // determine how many data should be transferred.
1845 AtaCommandBlock
.AtaCylinderLow
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
& 0x00ff);
1846 AtaCommandBlock
.AtaCylinderHigh
= (UINT8
) (ATAPI_MAX_BYTE_COUNT
>> 8);
1847 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) (Device
<< 0x4);
1848 AtaCommandBlock
.AtaCommand
= ATA_CMD_PACKET
;
1850 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)(0xe0 | (Device
<< 0x4)));
1852 // Disable interrupt
1854 IdeWritePortB (PciIo
, IdeRegisters
->AltOrDev
, ATA_DEFAULT_CTL
);
1857 // Issue ATA PACKET command firstly
1859 Status
= AtaIssueCommand (PciIo
, IdeRegisters
, &AtaCommandBlock
, Packet
->Timeout
);
1860 if (EFI_ERROR (Status
)) {
1864 Status
= DRQReady (PciIo
, IdeRegisters
, Packet
->Timeout
);
1865 if (EFI_ERROR (Status
)) {
1870 // Send out ATAPI command packet
1872 for (Count
= 0; Count
< 6; Count
++) {
1873 IdeWritePortW (PciIo
, IdeRegisters
->Data
, *((UINT16
*)PacketCommand
+ Count
));
1875 // Stall for 10 microseconds.
1877 MicroSecondDelay (10);
1881 // Read/Write the data of ATAPI Command
1883 if (Packet
->DataDirection
== EFI_EXT_SCSI_DATA_DIRECTION_READ
) {
1884 Status
= AtaPacketReadWrite (
1887 Packet
->InDataBuffer
,
1888 &Packet
->InTransferLength
,
1893 Status
= AtaPacketReadWrite (
1896 Packet
->OutDataBuffer
,
1897 &Packet
->OutTransferLength
,
1908 Set the calculated Best transfer mode to a detected device.
1910 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1911 @param Channel The channel number of device.
1912 @param Device The device number of device.
1913 @param TransferMode A pointer to EFI_ATA_TRANSFER_MODE data structure.
1914 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1916 @retval EFI_SUCCESS Set transfer mode successfully.
1917 @retval EFI_DEVICE_ERROR Set transfer mode failed.
1918 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1923 SetDeviceTransferMode (
1924 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1927 IN EFI_ATA_TRANSFER_MODE
*TransferMode
,
1928 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
1932 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1934 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1936 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_FEATURES
;
1937 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
1938 AtaCommandBlock
.AtaFeatures
= 0x03;
1939 AtaCommandBlock
.AtaSectorCount
= *((UINT8
*)TransferMode
);
1942 // Send SET FEATURE command (sub command 0x03) to set pio mode.
1944 Status
= AtaNonDataCommandIn (
1946 &Instance
->IdeRegisters
[Channel
],
1957 Set drive parameters for devices not support PACKETS command.
1959 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
1960 @param Channel The channel number of device.
1961 @param Device The device number of device.
1962 @param DriveParameters A pointer to EFI_ATA_DRIVE_PARMS data structure.
1963 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1965 @retval EFI_SUCCESS Set drive parameter successfully.
1966 @retval EFI_DEVICE_ERROR Set drive parameter failed.
1967 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
1972 SetDriveParameters (
1973 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
1976 IN EFI_ATA_DRIVE_PARMS
*DriveParameters
,
1977 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
1981 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
1983 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
1985 AtaCommandBlock
.AtaCommand
= ATA_CMD_INIT_DRIVE_PARAM
;
1986 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->Sector
;
1987 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) + DriveParameters
->Heads
);
1990 // Send Init drive parameters
1992 Status
= AtaNonDataCommandIn (
1994 &Instance
->IdeRegisters
[Channel
],
2002 // Send Set Multiple parameters
2004 AtaCommandBlock
.AtaCommand
= ATA_CMD_SET_MULTIPLE_MODE
;
2005 AtaCommandBlock
.AtaSectorCount
= DriveParameters
->MultipleSector
;
2006 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2008 Status
= AtaNonDataCommandIn (
2010 &Instance
->IdeRegisters
[Channel
],
2021 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
2023 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2024 @param Channel The channel number of device.
2025 @param Device The device number of device.
2026 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2028 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
2029 @retval Others Fail to get return status data.
2034 IdeAtaSmartReturnStatusCheck (
2035 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2038 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2042 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2046 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2048 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2049 AtaCommandBlock
.AtaFeatures
= ATA_SMART_RETURN_STATUS
;
2050 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2051 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2052 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2055 // Send S.M.A.R.T Read Return Status command to device
2057 Status
= AtaNonDataCommandIn (
2059 &Instance
->IdeRegisters
[Channel
],
2066 if (EFI_ERROR (Status
)) {
2067 REPORT_STATUS_CODE (
2068 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2069 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
2071 return EFI_DEVICE_ERROR
;
2074 REPORT_STATUS_CODE (
2076 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
2079 LBAMid
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderLsb
);
2080 LBAHigh
= IdeReadPortB (Instance
->PciIo
, Instance
->IdeRegisters
[Channel
].CylinderMsb
);
2082 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
2084 // The threshold exceeded condition is not detected by the device
2086 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
2087 REPORT_STATUS_CODE (
2089 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
2091 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
2093 // The threshold exceeded condition is detected by the device
2095 DEBUG ((EFI_D_INFO
, "The S.M.A.R.T threshold exceeded condition is detected\n"));
2096 REPORT_STATUS_CODE (
2098 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
2106 Enable SMART command of the disk if supported.
2108 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2109 @param Channel The channel number of device.
2110 @param Device The device number of device.
2111 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2112 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2117 IdeAtaSmartSupport (
2118 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2121 IN EFI_IDENTIFY_DATA
*IdentifyData
,
2122 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2126 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2129 // Detect if the device supports S.M.A.R.T.
2131 if ((IdentifyData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
2133 // S.M.A.R.T is not supported by the device
2135 DEBUG ((EFI_D_INFO
, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",
2136 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2137 REPORT_STATUS_CODE (
2138 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
2139 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
2143 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
2145 if ((IdentifyData
->AtaData
.command_set_feature_enb_85
& 0x0001) != 0x0001) {
2147 REPORT_STATUS_CODE (
2149 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLE
)
2152 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2154 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2155 AtaCommandBlock
.AtaFeatures
= ATA_SMART_ENABLE_OPERATION
;
2156 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2157 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2158 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2161 // Send S.M.A.R.T Enable command to device
2163 Status
= AtaNonDataCommandIn (
2165 &Instance
->IdeRegisters
[Channel
],
2172 if (!EFI_ERROR (Status
)) {
2174 // Send S.M.A.R.T AutoSave command to device
2176 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2178 AtaCommandBlock
.AtaCommand
= ATA_CMD_SMART
;
2179 AtaCommandBlock
.AtaFeatures
= 0xD2;
2180 AtaCommandBlock
.AtaSectorCount
= 0xF1;
2181 AtaCommandBlock
.AtaCylinderLow
= ATA_CONSTANT_4F
;
2182 AtaCommandBlock
.AtaCylinderHigh
= ATA_CONSTANT_C2
;
2183 AtaCommandBlock
.AtaDeviceHead
= (UINT8
) ((Device
<< 0x4) | 0xe0);
2185 Status
= AtaNonDataCommandIn (
2187 &Instance
->IdeRegisters
[Channel
],
2193 if (!EFI_ERROR (Status
)) {
2194 Status
= IdeAtaSmartReturnStatusCheck (
2204 DEBUG ((EFI_D_INFO
, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",
2205 (Channel
== 1) ? "secondary" : "primary", (Device
== 1) ? "slave" : "master"));
2214 Sends out an ATA Identify Command to the specified device.
2216 This function is called by DiscoverIdeDevice() during its device
2217 identification. It sends out the ATA Identify Command to the
2218 specified device. Only ATA device responses to this command. If
2219 the command succeeds, it returns the Identify data structure which
2220 contains information about the device. This function extracts the
2221 information it needs to fill the IDE_BLK_IO_DEV data structure,
2222 including device type, media block size, media capacity, and etc.
2224 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2225 @param Channel The channel number of device.
2226 @param Device The device number of device.
2227 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2228 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2230 @retval EFI_SUCCESS Identify ATA device successfully.
2231 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
2232 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2238 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2241 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2242 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2246 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2248 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2250 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DRIVE
;
2251 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2253 Status
= AtaPioDataInOut (
2255 &Instance
->IdeRegisters
[Channel
],
2257 sizeof (EFI_IDENTIFY_DATA
),
2269 This function is called by DiscoverIdeDevice() during its device
2271 Its main purpose is to get enough information for the device media
2272 to fill in the Media data structure of the Block I/O Protocol interface.
2274 There are 5 steps to reach such objective:
2275 1. Sends out the ATAPI Identify Command to the specified device.
2276 Only ATAPI device responses to this command. If the command succeeds,
2277 it returns the Identify data structure which filled with information
2278 about the device. Since the ATAPI device contains removable media,
2279 the only meaningful information is the device module name.
2280 2. Sends out ATAPI Inquiry Packet Command to the specified device.
2281 This command will return inquiry data of the device, which contains
2282 the device type information.
2283 3. Allocate sense data space for future use. We don't detect the media
2284 presence here to improvement boot performance, especially when CD
2285 media is present. The media detection will be performed just before
2286 each BLK_IO read/write
2288 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2289 @param Channel The channel number of device.
2290 @param Device The device number of device.
2291 @param Buffer A pointer to data buffer which is used to contain IDENTIFY data.
2292 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
2294 @retval EFI_SUCCESS Identify ATAPI device successfully.
2295 @retval EFI_DEVICE_ERROR ATA Identify Packet Device Command failed or device type
2296 is not supported by this IDE driver.
2297 @retval EFI_OUT_OF_RESOURCES Allocate memory failed.
2303 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2306 IN OUT EFI_IDENTIFY_DATA
*Buffer
,
2307 IN OUT EFI_ATA_STATUS_BLOCK
*AtaStatusBlock
2311 EFI_ATA_COMMAND_BLOCK AtaCommandBlock
;
2313 ZeroMem (&AtaCommandBlock
, sizeof (EFI_ATA_COMMAND_BLOCK
));
2315 AtaCommandBlock
.AtaCommand
= ATA_CMD_IDENTIFY_DEVICE
;
2316 AtaCommandBlock
.AtaDeviceHead
= (UINT8
)(Device
<< 0x4);
2319 // Send ATAPI Identify Command to get IDENTIFY data.
2321 Status
= AtaPioDataInOut (
2323 &Instance
->IdeRegisters
[Channel
],
2325 sizeof (EFI_IDENTIFY_DATA
),
2338 This function is used for detect whether the IDE device exists in the
2339 specified Channel as the specified Device Number.
2341 There is two IDE channels: one is Primary Channel, the other is
2342 Secondary Channel.(Channel is the logical name for the physical "Cable".)
2343 Different channel has different register group.
2345 On each IDE channel, at most two IDE devices attach,
2346 one is called Device 0 (Master device), the other is called Device 1
2347 (Slave device). The devices on the same channel co-use the same register
2348 group, so before sending out a command for a specified device via command
2349 register, it is a must to select the current device to accept the command
2350 by set the device number in the Head/Device Register.
2352 @param Instance A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
2353 @param IdeChannel The channel number of device.
2355 @retval EFI_SUCCESS successfully detects device.
2356 @retval other any failure during detection process will return this value.
2361 DetectAndConfigIdeDevice (
2362 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
,
2367 UINT8 SectorCountReg
;
2371 EFI_ATA_DEVICE_TYPE DeviceType
;
2373 EFI_IDE_REGISTERS
*IdeRegisters
;
2374 EFI_IDENTIFY_DATA Buffer
;
2376 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2377 EFI_PCI_IO_PROTOCOL
*PciIo
;
2379 EFI_ATA_COLLECTIVE_MODE
*SupportedModes
;
2380 EFI_ATA_TRANSFER_MODE TransferMode
;
2381 EFI_ATA_DRIVE_PARMS DriveParameters
;
2383 IdeRegisters
= &Instance
->IdeRegisters
[IdeChannel
];
2384 IdeInit
= Instance
->IdeControllerInit
;
2385 PciIo
= Instance
->PciIo
;
2387 for (IdeDevice
= 0; IdeDevice
< EfiIdeMaxDevice
; IdeDevice
++) {
2389 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2391 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2394 // Send ATA Device Execut Diagnostic command.
2395 // This command should work no matter DRDY is ready or not
2397 IdeWritePortB (PciIo
, IdeRegisters
->CmdOrStatus
, ATA_CMD_EXEC_DRIVE_DIAG
);
2399 Status
= WaitForBSYClear (PciIo
, IdeRegisters
, 350000000);
2400 if (EFI_ERROR (Status
)) {
2401 DEBUG((EFI_D_ERROR
, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status
));
2406 // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.
2408 IdeWritePortB (PciIo
, IdeRegisters
->Head
, (UINT8
)((IdeDevice
<< 4) | 0xe0));
2410 // Stall for 1 milliseconds.
2412 MicroSecondDelay (1000);
2414 SectorCountReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorCount
);
2415 LBALowReg
= IdeReadPortB (PciIo
, IdeRegisters
->SectorNumber
);
2416 LBAMidReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderLsb
);
2417 LBAHighReg
= IdeReadPortB (PciIo
, IdeRegisters
->CylinderMsb
);
2420 // Refer to ATA/ATAPI 4 Spec, section 9.1
2422 if ((SectorCountReg
== 0x1) && (LBALowReg
== 0x1) && (LBAMidReg
== 0x0) && (LBAHighReg
== 0x0)) {
2423 DeviceType
= EfiIdeHarddisk
;
2424 } else if ((LBAMidReg
== 0x14) && (LBAHighReg
== 0xeb)) {
2425 DeviceType
= EfiIdeCdrom
;
2431 // Send IDENTIFY cmd to the device to test if it is really attached.
2433 if (DeviceType
== EfiIdeHarddisk
) {
2434 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2436 // if identifying ata device is failure, then try to send identify packet cmd.
2438 if (EFI_ERROR (Status
)) {
2439 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_EC_NOT_DETECTED
));
2441 DeviceType
= EfiIdeCdrom
;
2442 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2445 Status
= AtaIdentifyPacket (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2447 // if identifying atapi device is failure, then try to send identify cmd.
2449 if (EFI_ERROR (Status
)) {
2450 DeviceType
= EfiIdeHarddisk
;
2451 Status
= AtaIdentify (Instance
, IdeChannel
, IdeDevice
, &Buffer
, NULL
);
2455 if (EFI_ERROR (Status
)) {
2457 // No device is found at this port
2462 DEBUG ((EFI_D_INFO
, "[%a] channel [%a] [%a] device\n",
2463 (IdeChannel
== 1) ? "secondary" : "primary ", (IdeDevice
== 1) ? "slave " : "master",
2464 DeviceType
== EfiIdeCdrom
? "cdrom " : "harddisk"));
2466 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2468 if ((DeviceType
== EfiIdeHarddisk
) && PcdGetBool (PcdAtaSmartEnable
)) {
2469 IdeAtaSmartSupport (
2479 // Submit identify data to IDE controller init driver
2481 IdeInit
->SubmitData (IdeInit
, IdeChannel
, IdeDevice
, &Buffer
);
2484 // Now start to config ide device parameter and transfer mode.
2486 Status
= IdeInit
->CalculateMode (
2492 if (EFI_ERROR (Status
)) {
2493 DEBUG ((EFI_D_ERROR
, "Calculate Mode Fail, Status = %r\n", Status
));
2498 // Set best supported PIO mode on this IDE device
2500 if (SupportedModes
->PioMode
.Mode
<= EfiAtaPioMode2
) {
2501 TransferMode
.ModeCategory
= EFI_ATA_MODE_DEFAULT_PIO
;
2503 TransferMode
.ModeCategory
= EFI_ATA_MODE_FLOW_PIO
;
2506 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->PioMode
.Mode
);
2508 if (SupportedModes
->ExtModeCount
== 0){
2509 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2511 if (EFI_ERROR (Status
)) {
2512 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2518 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2519 // be set together. Only one DMA mode can be set to a device. If setting
2520 // DMA mode operation fails, we can continue moving on because we only use
2521 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2523 if (SupportedModes
->UdmaMode
.Valid
) {
2524 TransferMode
.ModeCategory
= EFI_ATA_MODE_UDMA
;
2525 TransferMode
.ModeNumber
= (UINT8
) (SupportedModes
->UdmaMode
.Mode
);
2526 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2528 if (EFI_ERROR (Status
)) {
2529 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2532 } else if (SupportedModes
->MultiWordDmaMode
.Valid
) {
2533 TransferMode
.ModeCategory
= EFI_ATA_MODE_MDMA
;
2534 TransferMode
.ModeNumber
= (UINT8
) SupportedModes
->MultiWordDmaMode
.Mode
;
2535 Status
= SetDeviceTransferMode (Instance
, IdeChannel
, IdeDevice
, &TransferMode
, NULL
);
2537 if (EFI_ERROR (Status
)) {
2538 DEBUG ((EFI_D_ERROR
, "Set transfer Mode Fail, Status = %r\n", Status
));
2544 // Set Parameters for the device:
2546 // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
2548 if (DeviceType
== EfiIdeHarddisk
) {
2550 // Init driver parameters
2552 DriveParameters
.Sector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->sectors_per_track
;
2553 DriveParameters
.Heads
= (UINT8
) (((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->heads
- 1);
2554 DriveParameters
.MultipleSector
= (UINT8
) ((ATA5_IDENTIFY_DATA
*)(&Buffer
.AtaData
))->multi_sector_cmd_max_sct_cnt
;
2556 Status
= SetDriveParameters (Instance
, IdeChannel
, IdeDevice
, &DriveParameters
, NULL
);
2560 // Set IDE controller Timing Blocks in the PCI Configuration Space
2562 IdeInit
->SetTiming (IdeInit
, IdeChannel
, IdeDevice
, SupportedModes
);
2565 // IDE controller and IDE device timing is configured successfully.
2566 // Now insert the device into device list.
2568 Status
= CreateNewDeviceInfo (Instance
, IdeChannel
, IdeDevice
, DeviceType
, &Buffer
);
2569 if (EFI_ERROR (Status
)) {
2573 if (DeviceType
== EfiIdeHarddisk
) {
2574 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, (EFI_PERIPHERAL_FIXED_MEDIA
| EFI_P_PC_ENABLE
));
2582 Initialize ATA host controller at IDE mode.
2584 The function is designed to initialize ATA host controller.
2586 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2591 IdeModeInitialization (
2592 IN ATA_ATAPI_PASS_THRU_INSTANCE
*Instance
2596 EFI_IDE_CONTROLLER_INIT_PROTOCOL
*IdeInit
;
2597 EFI_PCI_IO_PROTOCOL
*PciIo
;
2600 BOOLEAN ChannelEnabled
;
2603 IdeInit
= Instance
->IdeControllerInit
;
2604 PciIo
= Instance
->PciIo
;
2605 Channel
= IdeInit
->ChannelCount
;
2608 // Obtain IDE IO port registers' base addresses
2610 Status
= GetIdeRegisterIoAddr (PciIo
, Instance
->IdeRegisters
);
2611 if (EFI_ERROR (Status
)) {
2615 for (IdeChannel
= 0; IdeChannel
< Channel
; IdeChannel
++) {
2616 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelEnumeration
, IdeChannel
);
2619 // now obtain channel information fron IdeControllerInit protocol.
2621 Status
= IdeInit
->GetChannelInfo (
2627 if (EFI_ERROR (Status
)) {
2628 DEBUG ((EFI_D_ERROR
, "[GetChannel, Status=%x]", Status
));
2632 if (!ChannelEnabled
) {
2636 ASSERT (MaxDevices
<= 2);
2638 // Now inform the IDE Controller Init Module.
2640 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBeforeChannelReset
, IdeChannel
);
2643 // No reset channel function implemented.
2645 IdeInit
->NotifyPhase (IdeInit
, EfiIdeAfterChannelReset
, IdeChannel
);
2648 // Now inform the IDE Controller Init Module.
2650 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusBeforeDevicePresenceDetection
, IdeChannel
);
2653 // Detect all attached ATA devices and set the transfer mode for each device.
2655 DetectAndConfigIdeDevice (Instance
, IdeChannel
);
2659 // All configurations done! Notify IdeController to do post initialization
2660 // work such as saving IDE controller PCI settings for S3 resume
2662 IdeInit
->NotifyPhase (IdeInit
, EfiIdeBusPhaseMaximum
, 0);