2 This file contains all helper functions on the ATA command
4 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
5 All rights reserved. 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.
13 @par Revision Reference:
14 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
15 update - ATAIdentity() func
16 update - AtaBlockIoReadBlocks() func
17 update - AtaBlockIoWriteBlocks() func
18 add - AtaAtapi6Identify() func
19 add - AtaReadSectorsExt() func
20 add - AtaWriteSectorsExt() func
21 add - AtaPioDataInExt() func
22 add - AtaPioDataOutExt() func
28 This function is called by ATAIdentify() to identity whether this disk
29 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
31 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
32 all the information of the IDE device.
34 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one and
35 48-bit addressing must be used
36 @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but the
37 capacity is below 120G, 48bit addressing is not needed
38 @retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
39 @retval EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.
41 @note This function must be called after DEVICE_IDENTITY command has been
47 IN IDE_BLK_IO_DEV
*IdeDev
53 EFI_IDENTIFY_DATA
*Atapi6IdentifyStruct
;
55 if (IdeDev
->IdData
== NULL
) {
56 return EFI_INVALID_PARAMETER
;
59 Atapi6IdentifyStruct
= IdeDev
->IdData
;
61 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& (BIT15
| BIT14
)) != 0x4000) {
63 // Per ATA-6 spec, word83: bit15 is zero and bit14 is one
65 return EFI_DEVICE_ERROR
;
68 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& BIT10
) == 0) {
70 // The device dosn't support 48 bit addressing
72 return EFI_UNSUPPORTED
;
76 // 48 bit address feature set is supported, get maximum capacity
78 Capacity
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[0];
79 for (Index
= 1; Index
< 4; Index
++) {
81 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
83 TmpLba
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[Index
];
84 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
87 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
89 // Capacity exceeds 120GB. 48-bit addressing is really needed
91 IdeDev
->Type
= Ide48bitAddressingHardDisk
;
94 // Fill block media information:Media->LogicalPartition ,
95 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
97 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
98 IdeDev
->BlkIo
.Media
->MediaId
= 1;
99 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
100 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
101 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
102 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
103 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
108 return EFI_UNSUPPORTED
;
111 Enable SMART of the disk if supported
113 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
114 all the information of the IDE device.
118 IN IDE_BLK_IO_DEV
*IdeDev
122 BOOLEAN SMARTSupported
;
124 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
130 // Detect if the device supports S.M.A.R.T.
132 if ((IdeDev
->IdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
134 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
138 if ((IdeDev
->IdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
140 // S.M.A.R.T is not supported by the device
142 SMARTSupported
= FALSE
;
144 SMARTSupported
= TRUE
;
148 if (!SMARTSupported
) {
150 // Report nonsupport status code
153 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
154 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
158 // Enable this feature
162 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
165 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
166 Status
= AtaNonDataCommandIn (
170 ATA_SMART_ENABLE_OPERATION
,
177 // Detect if this feature is enabled
179 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
180 if (TmpAtaIdentifyPointer
== NULL
) {
184 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
185 Status
= AtaPioDataIn (
187 (VOID
*) TmpAtaIdentifyPointer
,
188 sizeof (EFI_IDENTIFY_DATA
),
189 ATA_CMD_IDENTIFY_DRIVE
,
196 if (EFI_ERROR (Status
)) {
197 gBS
->FreePool (TmpAtaIdentifyPointer
);
202 // Check if the feature is enabled
204 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
208 AtaNonDataCommandIn (
212 ATA_SMART_RETURN_STATUS
,
218 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
219 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
221 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
223 // The threshold exceeded condition is not detected by the device
227 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
230 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
232 // The threshold exceeded condition is detected by the device
236 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
242 // Report disabled status code
245 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
246 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
250 gBS
->FreePool (TmpAtaIdentifyPointer
);
256 Sends out an ATA Identify Command to the specified device.
258 This function is called by DiscoverIdeDevice() during its device
259 identification. It sends out the ATA Identify Command to the
260 specified device. Only ATA device responses to this command. If
261 the command succeeds, it returns the Identify data structure which
262 contains information about the device. This function extracts the
263 information it needs to fill the IDE_BLK_IO_DEV data structure,
264 including device type, media block size, media capacity, and etc.
266 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
267 all the information of the IDE device.
269 @retval EFI_SUCCESS Identify ATA device successfully.
270 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
271 @note parameter IdeDev will be updated in this function.
276 IN IDE_BLK_IO_DEV
*IdeDev
280 EFI_IDENTIFY_DATA
*AtaIdentifyPointer
;
286 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
287 // the ATA Identify command
289 AtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
290 if (AtaIdentifyPointer
== NULL
) {
291 return EFI_OUT_OF_RESOURCES
;
295 // use ATA PIO Data In protocol to send ATA Identify command
296 // and receive data from device
298 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
303 Status
= AtaPioDataIn (
305 (VOID
*) AtaIdentifyPointer
,
306 sizeof (EFI_IDENTIFY_DATA
),
307 ATA_CMD_IDENTIFY_DRIVE
,
315 // If ATA Identify command succeeds, then according to the received
317 // identify the device type ( ATA or not ).
318 // If ATA device, fill the information in IdeDev.
319 // If not ATA device, return IDE_DEVICE_ERROR
321 if (!EFI_ERROR (Status
)) {
323 IdeDev
->IdData
= AtaIdentifyPointer
;
326 // Print ATA Module Name
328 PrintAtaModuleName (IdeDev
);
331 // bit 15 of pAtaIdentify->config is used to identify whether device is
332 // ATA device or ATAPI device.
333 // if 0, means ATA device; if 1, means ATAPI device.
335 if ((AtaIdentifyPointer
->AtaData
.config
& 0x8000) == 0x00) {
337 // Detect if support S.M.A.R.T. If yes, enable it as default
339 AtaSMARTSupport (IdeDev
);
342 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
344 Status
= AtaAtapi6Identify (IdeDev
);
345 if (!EFI_ERROR (Status
)) {
347 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
350 } else if (Status
== EFI_DEVICE_ERROR
) {
352 // Some disk with big capacity (>200GB) is slow when being identified
353 // and will return all zero for word83.
354 // We try twice at first. If it fails, we do a SoftRest and try again.
359 // Do a SoftRest before the third attempt.
361 AtaSoftReset (IdeDev
);
366 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
368 IdeDev
->Type
= IdeHardDisk
;
371 // Block Media Information:
372 // Media->LogicalPartition , Media->WriteCaching will be filled
373 // in the DiscoverIdeDevcie() function.
375 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
376 IdeDev
->BlkIo
.Media
->MediaId
= 1;
377 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
378 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
379 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
380 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
383 // Calculate device capacity
385 Capacity
= ((UINT32
)AtaIdentifyPointer
->AtaData
.user_addressable_sectors_hi
<< 16) |
386 AtaIdentifyPointer
->AtaData
.user_addressable_sectors_lo
;
387 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
396 gBS
->FreePool (AtaIdentifyPointer
);
398 // Make sure the pIdData will not be freed again.
400 IdeDev
->IdData
= NULL
;
402 return EFI_DEVICE_ERROR
;
406 This function is a helper function used to change the char order in a string. It
407 is designed specially for the PrintAtaModuleName() function. After the IDE device
408 is detected, the IDE driver gets the device module name by sending ATA command
409 called ATA Identify Command or ATAPI Identify Command to the specified IDE device.
410 The module name returned is a string of ASCII characters: the first character is bit8--bit15
411 of the first word, the second character is BIT0--bit7 of the first word and so on. Thus
412 the string can not be print directly before it is preprocessed by this func to change
413 the order of characters in each word in the string.
415 @param Destination Indicates the destination string.
416 @param Source Indicates the source string.
417 @param Size the length of the string
421 IN CHAR8
*Destination
,
429 for (Index
= 0; Index
< Size
; Index
+= 2) {
431 Temp
= Source
[Index
+ 1];
432 Destination
[Index
+ 1] = Source
[Index
];
433 Destination
[Index
] = Temp
;
437 This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.
439 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
440 all the information of the IDE device.
444 IN IDE_BLK_IO_DEV
*IdeDev
447 if (IdeDev
->IdData
== NULL
) {
451 SwapStringChars (IdeDev
->ModelName
, IdeDev
->IdData
->AtaData
.ModelName
, 40);
452 IdeDev
->ModelName
[40] = 0x00;
456 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
458 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
459 all the information of the IDE device.
460 @param Buffer buffer contained data transferred from device to host.
461 @param ByteCount data size in byte unit of the buffer.
462 @param AtaCommand value of the Command Register
463 @param Head value of the Head/Device Register
464 @param SectorCount value of the Sector Count Register
465 @param SectorNumber value of the Sector Number Register
466 @param CylinderLsb value of the low byte of the Cylinder Register
467 @param CylinderMsb value of the high byte of the Cylinder Register
469 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
470 @retval EFI_DEVICE_ERROR command sent failed.
475 IN IDE_BLK_IO_DEV
*IdeDev
,
480 IN UINT8 SectorCount
,
481 IN UINT8 SectorNumber
,
482 IN UINT8 CylinderLsb
,
491 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
492 if (EFI_ERROR (Status
)) {
493 return EFI_DEVICE_ERROR
;
497 // e0:1110,0000-- bit7 and bit5 are reserved bits.
498 // bit6 set means LBA mode
502 IdeDev
->IoPort
->Head
,
503 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
507 // All ATAPI device's ATA commands can be issued regardless of the
510 if (IdeDev
->Type
== IdeHardDisk
) {
512 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
513 if (EFI_ERROR (Status
)) {
514 return EFI_DEVICE_ERROR
;
518 // set all the command parameters
519 // Before write to all the following registers, BSY and DRQ must be 0.
521 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
522 if (EFI_ERROR (Status
)) {
523 return EFI_DEVICE_ERROR
;
526 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
527 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
530 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
531 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
532 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
533 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
536 // send command via Command Register
538 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
540 Buffer16
= (UINT16
*) Buffer
;
543 // According to PIO data in protocol, host can perform a series of reads to
544 // the data register after each time device set DRQ ready;
545 // The data size of "a series of read" is command specific.
546 // For most ATA command, data size received from device will not exceed
547 // 1 sector, hence the data size for "a series of read" can be the whole data
548 // size of one command request.
549 // For ATA command such as Read Sector command, the data size of one ATA
550 // command request is often larger than 1 sector, according to the
551 // Read Sector command, the data size of "a series of read" is exactly 1
553 // Here for simplification reason, we specify the data size for
554 // "a series of read" to 1 sector (256 words) if data size of one ATA command
555 // request is larger than 256 words.
560 // used to record bytes of currently transfered data
564 while (WordCount
< ByteCount
/ 2) {
566 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
568 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
569 if (EFI_ERROR (Status
)) {
570 return EFI_DEVICE_ERROR
;
573 Status
= CheckErrorStatus (IdeDev
);
574 if (EFI_ERROR (Status
)) {
575 return EFI_DEVICE_ERROR
;
579 // Get the byte count for one series of read
581 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
582 Increment
= ByteCount
/ 2 - WordCount
;
585 IDEReadPortWMultiple (
587 IdeDev
->IoPort
->Data
,
592 WordCount
+= Increment
;
593 Buffer16
+= Increment
;
597 DRQClear (IdeDev
, ATATIMEOUT
);
599 return CheckErrorStatus (IdeDev
);
603 This function is used to send out ATA commands conforms to the
604 PIO Data Out Protocol.
606 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
607 to record all the information of the IDE device.
608 @param *Buffer buffer contained data transferred from host to device.
609 @param ByteCount data size in byte unit of the buffer.
610 @param AtaCommand value of the Command Register
611 @param Head value of the Head/Device Register
612 @param SectorCount value of the Sector Count Register
613 @param SectorNumber value of the Sector Number Register
614 @param CylinderLsb value of the low byte of the Cylinder Register
615 @param CylinderMsb value of the high byte of the Cylinder Register
617 @retval EFI_SUCCESS send out the ATA command and device received required
619 @retval EFI_DEVICE_ERROR command sent failed.
624 IN IDE_BLK_IO_DEV
*IdeDev
,
629 IN UINT8 SectorCount
,
630 IN UINT8 SectorNumber
,
631 IN UINT8 CylinderLsb
,
640 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
641 if (EFI_ERROR (Status
)) {
642 return EFI_DEVICE_ERROR
;
646 // select device via Head/Device register.
647 // Before write Head/Device register, BSY and DRQ must be 0.
649 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
650 if (EFI_ERROR (Status
)) {
651 return EFI_DEVICE_ERROR
;
655 // e0:1110,0000-- bit7 and bit5 are reserved bits.
656 // bit6 set means LBA mode
660 IdeDev
->IoPort
->Head
,
661 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
664 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
665 if (EFI_ERROR (Status
)) {
666 return EFI_DEVICE_ERROR
;
670 // set all the command parameters
671 // Before write to all the following registers, BSY and DRQ must be 0.
673 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
674 if (EFI_ERROR (Status
)) {
675 return EFI_DEVICE_ERROR
;
678 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
679 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
680 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
681 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
684 // send command via Command Register
686 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
688 Buffer16
= (UINT16
*) Buffer
;
691 // According to PIO data out protocol, host can perform a series of
692 // writes to the data register after each time device set DRQ ready;
693 // The data size of "a series of read" is command specific.
694 // For most ATA command, data size written to device will not exceed 1 sector,
695 // hence the data size for "a series of write" can be the data size of one
697 // For ATA command such as Write Sector command, the data size of one
698 // ATA command request is often larger than 1 sector, according to the
699 // Write Sector command, the data size of "a series of read" is exactly
701 // Here for simplification reason, we specify the data size for
702 // "a series of write" to 1 sector (256 words) if data size of one ATA command
703 // request is larger than 256 words.
708 while (WordCount
< ByteCount
/ 2) {
711 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
712 // data transfer can be performed only when DRQ is ready.
714 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
715 if (EFI_ERROR (Status
)) {
716 return EFI_DEVICE_ERROR
;
719 Status
= CheckErrorStatus (IdeDev
);
720 if (EFI_ERROR (Status
)) {
721 return EFI_DEVICE_ERROR
;
725 // Check the remaining byte count is less than 512 bytes
727 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
728 Increment
= ByteCount
/ 2 - WordCount
;
731 // perform a series of write without check DRQ ready
734 IDEWritePortWMultiple (
736 IdeDev
->IoPort
->Data
,
740 WordCount
+= Increment
;
741 Buffer16
+= Increment
;
745 DRQClear (IdeDev
, ATATIMEOUT
);
747 return CheckErrorStatus (IdeDev
);
751 This function is used to analyze the Status Register and print out
752 some debug information and if there is ERR bit set in the Status
753 Register, the Error Register's value is also be parsed and print out.
755 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to
756 record all the information of the IDE device.
758 @retval EFI_SUCCESS No err information in the Status Register.
759 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
764 IN IDE_BLK_IO_DEV
*IdeDev
767 UINT8 StatusRegister
;
770 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
774 if ((StatusRegister
& ATA_STSREG_DWF
) != 0) {
777 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
782 if ((StatusRegister
& ATA_STSREG_CORR
) != 0) {
785 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
790 if ((StatusRegister
& ATA_STSREG_ERR
) != 0) {
791 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
793 if ((ErrorRegister
& ATA_ERRREG_BBK
) != 0) {
796 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
801 if ((ErrorRegister
& ATA_ERRREG_UNC
) != 0) {
804 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
809 if ((ErrorRegister
& ATA_ERRREG_MC
) != 0) {
812 "CheckErrorStatus()-- %02x : Error : Media Change\n",
817 if ((ErrorRegister
& ATA_ERRREG_ABRT
) != 0) {
820 "CheckErrorStatus()-- %02x : Error : Abort\n",
825 if ((ErrorRegister
& ATA_ERRREG_TK0NF
) != 0) {
828 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
833 if ((ErrorRegister
& ATA_ERRREG_AMNF
) != 0) {
836 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
844 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
848 return EFI_DEVICE_ERROR
;
853 This function is called by the AtaBlkIoReadBlocks() to perform reading from
856 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
857 all the information of the IDE device.
858 @param DataBuffer A pointer to the destination buffer for the data.
859 @param Lba The starting logical block address to read from on the device media.
860 @param NumberOfBlocks The number of transfer data blocks.
862 @return status is fully dependent on the return status of AtaPioDataIn() function.
867 IN IDE_BLK_IO_DEV
*IdeDev
,
870 IN UINTN NumberOfBlocks
874 UINTN BlocksRemaining
;
889 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
891 AtaCommand
= ATA_CMD_READ_SECTORS
;
894 BlocksRemaining
= NumberOfBlocks
;
896 Lba32
= (UINT32
) Lba
;
898 Status
= EFI_SUCCESS
;
900 while (BlocksRemaining
> 0) {
903 // in ATA-3 spec, LBA is in 28 bit width
905 Lba0
= (UINT8
) Lba32
;
906 Lba1
= (UINT8
) (Lba32
>> 8);
907 Lba2
= (UINT8
) (Lba32
>> 16);
909 // low 4 bit of Lba3 stands for LBA bit24~bit27.
911 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
913 if (BlocksRemaining
>= 0x100) {
916 // SectorCount8 is sent to Sector Count register, 0x00 means 256
917 // sectors to be read
921 // SectorCount is used to record the number of sectors to be read
926 SectorCount8
= (UINT8
) BlocksRemaining
;
927 SectorCount
= (UINT16
) BlocksRemaining
;
931 // ByteCount is the number of bytes that will be read
933 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
936 // call AtaPioDataIn() to send Read Sector Command and receive data read
938 Status
= AtaPioDataIn (
949 if (EFI_ERROR (Status
)) {
953 Lba32
+= SectorCount
;
954 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
955 BlocksRemaining
-= SectorCount
;
962 This function is called by the AtaBlkIoWriteBlocks() to perform writing onto
965 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
966 all the information of the IDE device.
967 @param BufferData A pointer to the source buffer for the data.
968 @param Lba The starting logical block address to write onto the device media.
969 @param NumberOfBlocks The number of transfer data blocks.
971 @return status is fully dependent on the return status of AtaPioDataIn() function.
976 IN IDE_BLK_IO_DEV
*IdeDev
,
979 IN UINTN NumberOfBlocks
983 UINTN BlocksRemaining
;
998 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
1000 AtaCommand
= ATA_CMD_WRITE_SECTORS
;
1002 BlocksRemaining
= NumberOfBlocks
;
1004 Lba32
= (UINT32
) Lba
;
1006 Status
= EFI_SUCCESS
;
1008 while (BlocksRemaining
> 0) {
1010 Lba0
= (UINT8
) Lba32
;
1011 Lba1
= (UINT8
) (Lba32
>> 8);
1012 Lba2
= (UINT8
) (Lba32
>> 16);
1013 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
1015 if (BlocksRemaining
>= 0x100) {
1018 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
1021 SectorCount8
= 0x00;
1023 // SectorCount is used to record the number of sectors to be written
1028 SectorCount8
= (UINT8
) BlocksRemaining
;
1029 SectorCount
= (UINT16
) BlocksRemaining
;
1032 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1034 Status
= AtaPioDataOut (
1045 if (EFI_ERROR (Status
)) {
1049 Lba32
+= SectorCount
;
1050 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1051 BlocksRemaining
-= SectorCount
;
1057 This function is used to implement the Soft Reset on the specified device. But,
1058 the ATA Soft Reset mechanism is so strong a reset method that it will force
1059 resetting on both devices connected to the same cable.
1061 It is called by IdeBlkIoReset(), a interface function of Block
1064 This function can also be used by the ATAPI device to perform reset when
1065 ATAPI Reset command is failed.
1067 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1068 all the information of the IDE device.
1069 @retval EFI_SUCCESS Soft reset completes successfully.
1070 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1072 @note The registers initial values after ATA soft reset are different
1073 to the ATA device and ATAPI device.
1077 IN IDE_BLK_IO_DEV
*IdeDev
1081 UINT8 DeviceControl
;
1085 // set SRST bit to initiate soft reset
1087 DeviceControl
|= ATA_CTLREG_SRST
;
1090 // disable Interrupt
1092 DeviceControl
|= BIT1
;
1094 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1097 // SRST should assert for at least 5 us, we use 10 us for
1098 // better compatibility
1103 // Enable interrupt to support UDMA, and clear SRST bit
1106 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1109 // Wait for at least 2 ms to check BSY status, we use 10 ms
1110 // for better compatibility
1114 // slave device needs at most 31s to clear BSY
1116 if (WaitForBSYClear (IdeDev
, 31000) == EFI_TIMEOUT
) {
1117 return EFI_DEVICE_ERROR
;
1123 This function is used to send out ATA commands conforms to the PIO Data In
1124 Protocol, supporting ATA/ATAPI-6 standard
1126 Comparing with ATA-3 data in protocol, we have two differents here:
1127 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1128 wait will frequently fail... cause writing function return error)
1130 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1131 slow down writing performance by 100 times!)
1133 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1134 to record all the information of the IDE device.
1135 @param Buffer buffer contained data transferred from device to host.
1136 @param ByteCount data size in byte unit of the buffer.
1137 @param AtaCommand value of the Command Register
1138 @param StartLba the start LBA of this transaction
1139 @param SectorCount the count of sectors to be transfered
1141 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1142 @retval EFI_DEVICE_ERROR command sent failed.
1147 IN IDE_BLK_IO_DEV
*IdeDev
,
1148 IN OUT VOID
*Buffer
,
1149 IN UINT32 ByteCount
,
1150 IN UINT8 AtaCommand
,
1151 IN EFI_LBA StartLba
,
1152 IN UINT16 SectorCount
1165 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1166 if (EFI_ERROR (Status
)) {
1167 return EFI_DEVICE_ERROR
;
1171 // Select device, set bit6 as 1 to indicate LBA mode is used
1173 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1177 IdeDev
->IoPort
->Head
,
1182 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1184 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1185 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1187 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1188 if (EFI_ERROR (Status
)) {
1189 return EFI_DEVICE_ERROR
;
1194 // Fill feature register if needed
1196 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
1197 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1201 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1203 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1204 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1206 SectorCount8
= (UINT8
) SectorCount
;
1207 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1210 // Fill the start LBA registers, which are also two-byte FIFO
1212 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1213 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1214 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1215 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1216 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1217 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1219 LbaLow
= (UINT8
) StartLba
;
1220 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1221 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1222 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1223 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1224 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1227 // Send command via Command Register, invoking the processing of this command
1229 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1231 Buffer16
= (UINT16
*) Buffer
;
1234 // According to PIO data in protocol, host can perform a series of reads to
1235 // the data register after each time device set DRQ ready;
1244 // used to record bytes of currently transfered data
1248 while (WordCount
< ByteCount
/ 2) {
1250 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1252 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1253 if (EFI_ERROR (Status
)) {
1254 return EFI_DEVICE_ERROR
;
1257 Status
= CheckErrorStatus (IdeDev
);
1258 if (EFI_ERROR (Status
)) {
1259 return EFI_DEVICE_ERROR
;
1263 // Get the byte count for one series of read
1265 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1266 Increment
= ByteCount
/ 2 - WordCount
;
1269 IDEReadPortWMultiple (
1271 IdeDev
->IoPort
->Data
,
1276 WordCount
+= Increment
;
1277 Buffer16
+= Increment
;
1281 return CheckErrorStatus (IdeDev
);
1284 Send ATA Ext command into device with NON_DATA protocol
1286 @param IdeDev Standard IDE device private data structure
1287 @param AtaCommand The ATA command to be sent
1288 @param Device The value in Device register
1289 @param Feature The value in Feature register
1290 @param SectorCount The value in SectorCount register
1291 @param LbaAddress The LBA address in 48-bit mode
1293 @retval EFI_SUCCESS Reading succeed
1294 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1298 AtaCommandIssueExt (
1299 IN IDE_BLK_IO_DEV
*IdeDev
,
1300 IN UINT8 AtaCommand
,
1303 IN UINT16 SectorCount
,
1304 IN EFI_LBA LbaAddress
1314 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1315 if (EFI_ERROR (Status
)) {
1316 return EFI_DEVICE_ERROR
;
1320 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1324 IdeDev
->IoPort
->Head
,
1325 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1329 // ATA commands for ATA device must be issued when DRDY is set
1331 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1332 if (EFI_ERROR (Status
)) {
1333 return EFI_DEVICE_ERROR
;
1337 // Pass parameter into device register block
1339 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1342 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1344 Feature8
= (UINT8
) (Feature
>> 8);
1345 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1347 Feature8
= (UINT8
) Feature
;
1348 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1351 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1353 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1354 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1356 SectorCount8
= (UINT8
) SectorCount
;
1357 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1360 // Fill the start LBA registers, which are also two-byte FIFO
1362 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1363 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1364 LbaLow
= (UINT8
) LbaAddress
;
1365 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1367 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1368 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1369 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1370 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1372 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1373 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1374 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1375 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1378 // Work around for Segate 160G disk writing
1383 // Send command via Command Register
1385 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1388 // Stall at least 400ns
1395 Send ATA Ext command into device with NON_DATA protocol
1397 @param IdeDev Standard IDE device private data structure
1398 @param AtaCommand The ATA command to be sent
1399 @param Device The value in Device register
1400 @param Feature The value in Feature register
1401 @param SectorCount The value in SectorCount register
1402 @param LbaAddress The LBA address in 48-bit mode
1404 @retval EFI_SUCCESS Reading succeed
1405 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1410 IN IDE_BLK_IO_DEV
*IdeDev
,
1411 IN UINT8 AtaCommand
,
1414 IN UINT16 SectorCount
,
1415 IN EFI_LBA LbaAddress
1426 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1427 if (EFI_ERROR (Status
)) {
1428 return EFI_DEVICE_ERROR
;
1432 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1436 IdeDev
->IoPort
->Head
,
1437 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1441 // ATA commands for ATA device must be issued when DRDY is set
1443 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1444 if (EFI_ERROR (Status
)) {
1445 return EFI_DEVICE_ERROR
;
1448 Lba0
= (UINT8
) LbaAddress
;
1449 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1450 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1451 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1452 Device
= (UINT8
) (Device
| Lba3
);
1455 // Pass parameter into device register block
1457 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1460 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1462 Feature8
= (UINT8
) Feature
;
1463 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1466 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1468 SectorCount8
= (UINT8
) SectorCount
;
1469 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1472 // Fill the start LBA registers, which are also two-byte FIFO
1475 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
1476 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
1477 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
1480 // Send command via Command Register
1482 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1485 // Stall at least 400ns
1492 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1494 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1495 to record all the information of the IDE device.
1496 @param DataBuffer A pointer to the source buffer for the data.
1497 @param StartLba The starting logical block address to write to
1498 on the device media.
1499 @param NumberOfBlocks The number of transfer data blocks.
1500 @param UdmaOp The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
1501 AtaUdmaWriteOp, AtaUdmaWriteExOp
1503 @retval EFI_SUCCESS the operation is successful.
1504 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1505 @retval EFI_UNSUPPORTED Unknown channel or operations command
1506 @retval EFI_DEVICE_ERROR Ata command execute failed
1511 IN IDE_BLK_IO_DEV
*IdeDev
,
1512 IN VOID
*DataBuffer
,
1513 IN EFI_LBA StartLba
,
1514 IN UINTN NumberOfBlocks
,
1515 IN ATA_UDMA_OPERATION UdmaOp
1518 IDE_DMA_PRD
*PrdAddr
;
1519 IDE_DMA_PRD
*UsedPrdAddr
;
1520 IDE_DMA_PRD
*TempPrdAddr
;
1521 UINT8 RegisterValue
;
1523 UINT64 IoPortForBmic
;
1524 UINT64 IoPortForBmis
;
1525 UINT64 IoPortForBmid
;
1529 UINTN ByteAvailable
;
1531 UINTN RemainBlockNum
;
1532 UINT8 DeviceControl
;
1537 EFI_PHYSICAL_ADDRESS DeviceAddress
;
1538 UINTN MaxDmaCommandSectors
;
1539 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp
;
1544 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
1545 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
1546 AtaCommand
= ATA_CMD_READ_DMA
;
1548 case AtaUdmaReadExtOp
:
1549 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
1550 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
1551 AtaCommand
= ATA_CMD_READ_DMA_EXT
;
1553 case AtaUdmaWriteOp
:
1554 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
1555 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
1556 AtaCommand
= ATA_CMD_WRITE_DMA
;
1558 case AtaUdmaWriteExtOp
:
1559 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
1560 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
1561 AtaCommand
= ATA_CMD_WRITE_DMA_EXT
;
1564 return EFI_UNSUPPORTED
;
1571 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1572 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1575 // Enable interrupt to support UDMA
1578 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1580 if (IdePrimary
== IdeDev
->Channel
) {
1581 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
1582 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
1583 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
1585 if (IdeSecondary
== IdeDev
->Channel
) {
1586 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
1587 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
1588 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
1590 return EFI_UNSUPPORTED
;
1595 // Read BMIS register and clear ERROR and INTR bit
1597 IdeDev
->PciIo
->Io
.Read (
1600 EFI_PCI_IO_PASS_THROUGH_BAR
,
1606 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1608 IdeDev
->PciIo
->Io
.Write (
1611 EFI_PCI_IO_PASS_THROUGH_BAR
,
1617 Status
= EFI_SUCCESS
;
1619 RemainBlockNum
= NumberOfBlocks
;
1620 while (RemainBlockNum
> 0) {
1622 if (RemainBlockNum
>= MaxDmaCommandSectors
) {
1624 // SectorCount is used to record the number of sectors to be read
1625 // Max 65536 sectors can be transfered at a time.
1627 NumberOfBlocks
= MaxDmaCommandSectors
;
1628 RemainBlockNum
-= MaxDmaCommandSectors
;
1630 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
1635 // Calculate the number of PRD table to make sure the memory region
1636 // not cross 64K boundary
1638 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
1639 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
1644 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
1645 Status
= IdeDev
->PciIo
->AllocateBuffer (
1648 EfiBootServicesData
,
1653 if (EFI_ERROR (Status
)) {
1654 return EFI_OUT_OF_RESOURCES
;
1656 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
1658 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
1660 // To make sure PRD is allocated in one 64K page
1662 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
1663 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
1665 if ((UINTN
) PrdAddr
& 0x03) {
1666 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
1668 UsedPrdAddr
= PrdAddr
;
1673 // Build the PRD table
1675 Status
= IdeDev
->PciIo
->Map (
1683 if (EFI_ERROR (Status
)) {
1684 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1685 return EFI_OUT_OF_RESOURCES
;
1687 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
1688 TempPrdAddr
= UsedPrdAddr
;
1691 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
1693 if (ByteCount
<= ByteAvailable
) {
1694 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
1695 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
1696 TempPrdAddr
->EndOfTable
= 0x8000;
1700 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
1701 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
1703 ByteCount
-= ByteAvailable
;
1704 PrdBuffer
+= ByteAvailable
;
1709 // Set the base address to BMID register
1711 IdeDev
->PciIo
->Io
.Write (
1713 EfiPciIoWidthUint32
,
1714 EFI_PCI_IO_PASS_THROUGH_BAR
,
1721 // Set BMIC register to identify the operation direction
1723 IdeDev
->PciIo
->Io
.Read (
1726 EFI_PCI_IO_PASS_THROUGH_BAR
,
1732 if (UdmaOp
== AtaUdmaReadExtOp
|| UdmaOp
== AtaUdmaReadOp
) {
1733 RegisterValue
|= BMIC_NREAD
;
1735 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1738 IdeDev
->PciIo
->Io
.Write (
1741 EFI_PCI_IO_PASS_THROUGH_BAR
,
1747 if (UdmaOp
== AtaUdmaWriteExtOp
|| UdmaOp
== AtaUdmaReadExtOp
) {
1748 Status
= AtaCommandIssueExt (
1753 (UINT16
) NumberOfBlocks
,
1757 Status
= AtaCommandIssue (
1762 (UINT16
) NumberOfBlocks
,
1767 if (EFI_ERROR (Status
)) {
1768 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1769 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
1770 return EFI_DEVICE_ERROR
;
1774 // Set START bit of BMIC register
1776 IdeDev
->PciIo
->Io
.Read (
1779 EFI_PCI_IO_PASS_THROUGH_BAR
,
1785 RegisterValue
|= BMIC_START
;
1787 IdeDev
->PciIo
->Io
.Write (
1790 EFI_PCI_IO_PASS_THROUGH_BAR
,
1797 // Check the INTERRUPT and ERROR bit of BMIS
1798 // Max transfer number of sectors for one command is 65536(32Mbyte),
1799 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1800 // So set the variable Count to 2000, for about 2 second timeout time.
1802 Status
= EFI_SUCCESS
;
1806 IdeDev
->PciIo
->Io
.Read (
1809 EFI_PCI_IO_PASS_THROUGH_BAR
,
1814 if (((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) != 0) || (Count
== 0)) {
1815 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Count
== 0)) {
1816 Status
= EFI_DEVICE_ERROR
;
1826 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1827 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
1829 // Read BMIS register and clear ERROR and INTR bit
1831 IdeDev
->PciIo
->Io
.Read (
1834 EFI_PCI_IO_PASS_THROUGH_BAR
,
1840 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1842 IdeDev
->PciIo
->Io
.Write (
1845 EFI_PCI_IO_PASS_THROUGH_BAR
,
1851 // Read Status Register of IDE device to clear interrupt
1853 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
1855 // Clear START bit of BMIC register
1857 IdeDev
->PciIo
->Io
.Read (
1860 EFI_PCI_IO_PASS_THROUGH_BAR
,
1866 RegisterValue
&= ~((UINT8
) BMIC_START
);
1868 IdeDev
->PciIo
->Io
.Write (
1871 EFI_PCI_IO_PASS_THROUGH_BAR
,
1877 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1878 return EFI_DEVICE_ERROR
;
1881 if (EFI_ERROR (Status
)) {
1884 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
1885 StartLba
+= NumberOfBlocks
;
1889 // Disable interrupt of Select device
1891 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
1892 DeviceControl
|= ATA_CTLREG_IEN_L
;
1893 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1900 This function is called by the AtaBlkIoReadBlocks() to perform reading from
1901 media in block unit. The function has been enhanced to support >120GB access
1902 and transfer at most 65536 blocks per command
1904 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1905 all the information of the IDE device.
1906 @param DataBuffer A pointer to the destination buffer for the data.
1907 @param StartLba The starting logical block address to read from on the device media.
1908 @param NumberOfBlocks The number of transfer data blocks.
1910 @return status depends on the function DoAtaUdma() returns.
1914 IN IDE_BLK_IO_DEV
*IdeDev
,
1915 IN VOID
*DataBuffer
,
1916 IN EFI_LBA StartLba
,
1917 IN UINTN NumberOfBlocks
1920 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadExtOp
);
1923 This function is called by the AtaBlkIoReadBlocks() to perform
1924 reading from media in block unit. The function has been enhanced to
1925 support >120GB access and transfer at most 65536 blocks per command
1927 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1928 all the information of the IDE device.
1929 @param DataBuffer A pointer to the destination buffer for the data.
1930 @param StartLba The starting logical block address to read from
1931 on the device media.
1932 @param NumberOfBlocks The number of transfer data blocks.
1934 @return status depends on the function DoAtaUdma() returns.
1938 IN IDE_BLK_IO_DEV
*IdeDev
,
1939 IN VOID
*DataBuffer
,
1940 IN EFI_LBA StartLba
,
1941 IN UINTN NumberOfBlocks
1944 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadOp
);
1948 This function is called by the AtaBlkIoReadBlocks() to perform
1949 reading from media in block unit. The function has been enhanced to
1950 support >120GB access and transfer at most 65536 blocks per command
1952 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1953 all the information of the IDE device.
1954 @param DataBuffer A pointer to the destination buffer for the data.
1955 @param StartLba The starting logical block address to read from on the device media.
1956 @param NumberOfBlocks The number of transfer data blocks.
1958 @return status is fully dependent on the return status of AtaPioDataInExt() function.
1962 IN IDE_BLK_IO_DEV
*IdeDev
,
1963 IN VOID
*DataBuffer
,
1964 IN EFI_LBA StartLba
,
1965 IN UINTN NumberOfBlocks
1969 UINTN BlocksRemaining
;
1977 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1979 AtaCommand
= ATA_CMD_READ_SECTORS_EXT
;
1980 Buffer
= DataBuffer
;
1981 BlocksRemaining
= NumberOfBlocks
;
1983 Status
= EFI_SUCCESS
;
1985 while (BlocksRemaining
> 0) {
1987 if (BlocksRemaining
>= 0x10000) {
1989 // SectorCount is used to record the number of sectors to be read
1990 // Max 65536 sectors can be transfered at a time.
1992 SectorCount
= 0xffff;
1994 SectorCount
= (UINT16
) BlocksRemaining
;
1998 // ByteCount is the number of bytes that will be read
2000 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
2003 // call AtaPioDataInExt() to send Read Sector Command and receive data read
2005 Status
= AtaPioDataInExt (
2013 if (EFI_ERROR (Status
)) {
2017 Lba64
+= SectorCount
;
2018 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
2019 BlocksRemaining
-= SectorCount
;
2025 This function is the ATA implementation for ReadBlocks in the
2026 Block I/O Protocol interface.
2028 @param IdeBlkIoDevice Indicates the calling context.
2029 @param MediaId The media id that the read request is for.
2030 @param LBA The starting logical block address to read from on the device.
2031 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2032 of the intrinsic block size of the device.
2034 @param Buffer A pointer to the destination buffer for the data. The caller
2035 is responsible for either having implicit or explicit ownership
2036 of the memory that data is read into.
2038 @retval EFI_SUCCESS Read Blocks successfully.
2039 @retval EFI_DEVICE_ERROR Read Blocks failed.
2040 @retval EFI_NO_MEDIA There is no media in the device.
2041 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2042 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2043 intrinsic block size of the device.
2044 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
2045 or the data buffer is not valid.
2047 @note If Read Block error because of device error, this function will call
2048 AtaSoftReset() function to reset device.
2052 AtaBlkIoReadBlocks (
2053 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
2056 IN UINTN BufferSize
,
2060 EFI_BLOCK_IO_MEDIA
*Media
;
2062 UINTN NumberOfBlocks
;
2065 if (Buffer
== NULL
) {
2066 return EFI_INVALID_PARAMETER
;
2069 if (BufferSize
== 0) {
2073 Status
= EFI_SUCCESS
;
2076 // Get the intrinsic block size
2078 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
2079 BlockSize
= Media
->BlockSize
;
2081 NumberOfBlocks
= BufferSize
/ BlockSize
;
2083 if (MediaId
!= Media
->MediaId
) {
2084 return EFI_MEDIA_CHANGED
;
2087 if (BufferSize
% BlockSize
!= 0) {
2088 return EFI_BAD_BUFFER_SIZE
;
2091 if (!(Media
->MediaPresent
)) {
2092 return EFI_NO_MEDIA
;
2095 if (LBA
> Media
->LastBlock
) {
2096 return EFI_INVALID_PARAMETER
;
2099 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
2100 return EFI_INVALID_PARAMETER
;
2103 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
2104 return EFI_INVALID_PARAMETER
;
2107 Status
= EFI_SUCCESS
;
2108 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
2110 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
2112 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2113 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2115 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2119 // For ATA-3 compatible device, use ATA-3 read block mechanism
2121 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2122 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2124 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2128 if (EFI_ERROR (Status
)) {
2129 AtaSoftReset (IdeBlkIoDevice
);
2130 return EFI_DEVICE_ERROR
;
2137 This function is used to send out ATA commands conforms to the
2138 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
2140 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
2141 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
2142 wait will frequently fail... cause writing function return error)
2144 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
2145 slow down writing performance by 100 times!)
2147 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2148 to record all the information of the IDE device.
2149 @param Buffer buffer contained data transferred from host to device.
2150 @param ByteCount data size in byte unit of the buffer.
2151 @param AtaCommand value of the Command Register
2152 @param StartLba the start LBA of this transaction
2153 @param SectorCount the count of sectors to be transfered
2155 @retval EFI_SUCCESS send out the ATA command and device receive required
2157 @retval EFI_DEVICE_ERROR command sent failed.
2162 IN IDE_BLK_IO_DEV
*IdeDev
,
2164 IN UINT32 ByteCount
,
2165 IN UINT8 AtaCommand
,
2166 IN EFI_LBA StartLba
,
2167 IN UINT16 SectorCount
2180 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2181 if (EFI_ERROR (Status
)) {
2182 return EFI_DEVICE_ERROR
;
2186 // Select device. Set bit6 as 1 to indicate LBA mode is used
2188 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
2192 IdeDev
->IoPort
->Head
,
2197 // Wait for DRDY singnal asserting.
2199 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2200 if (EFI_ERROR (Status
)) {
2201 return EFI_DEVICE_ERROR
;
2205 // Fill feature register if needed
2207 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
2208 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
2212 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2214 SectorCount8
= (UINT8
) (SectorCount
>> 8);
2215 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2217 SectorCount8
= (UINT8
) SectorCount
;
2218 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2221 // Fill the start LBA registers, which are also two-byte FIFO
2223 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
2224 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
2225 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
2226 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2227 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2228 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2230 LbaLow
= (UINT8
) StartLba
;
2231 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
2232 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
2233 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2234 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2235 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2238 // Send command via Command Register, invoking the processing of this command
2240 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2242 Buffer16
= (UINT16
*) Buffer
;
2245 // According to PIO Data Out protocol, host can perform a series of writes to
2246 // the data register after each time device set DRQ ready;
2251 // used to record bytes of currently transfered data
2255 while (WordCount
< ByteCount
/ 2) {
2257 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
2259 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
2260 if (EFI_ERROR (Status
)) {
2261 return EFI_DEVICE_ERROR
;
2264 Status
= CheckErrorStatus (IdeDev
);
2265 if (EFI_ERROR (Status
)) {
2266 return EFI_DEVICE_ERROR
;
2270 // Write data into device by one series of writing to data register
2272 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
2273 Increment
= ByteCount
/ 2 - WordCount
;
2276 IDEWritePortWMultiple (
2278 IdeDev
->IoPort
->Data
,
2283 WordCount
+= Increment
;
2284 Buffer16
+= Increment
;
2287 return CheckErrorStatus (IdeDev
);
2290 This function is called by the AtaBlkIoWriteBlocks() to perform
2291 writing to media in block unit. The function has been enhanced to
2292 support >120GB access and transfer at most 65536 blocks per command
2294 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2295 to record all the information of the IDE device.
2296 @param DataBuffer A pointer to the source buffer for the data.
2297 @param StartLba The starting logical block address to write to
2298 on the device media.
2299 @param NumberOfBlocks The number of transfer data blocks.
2301 @return status depends on the function DoAtaUdma() returns.
2305 IN IDE_BLK_IO_DEV
*IdeDev
,
2306 IN VOID
*DataBuffer
,
2307 IN EFI_LBA StartLba
,
2308 IN UINTN NumberOfBlocks
2311 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteExtOp
);
2315 This function is called by the AtaBlkIoWriteBlocks() to perform
2316 writing to media in block unit.
2318 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2319 to record all the information of the IDE device.
2320 @param DataBuffer A pointer to the source buffer for the data.
2321 @param StartLba The starting logical block address to write to
2322 on the device media.
2323 @param NumberOfBlocks The number of transfer data blocks.
2325 @return status depends on the function DoAtaUdma() returns.
2329 IN IDE_BLK_IO_DEV
*IdeDev
,
2330 IN VOID
*DataBuffer
,
2331 IN EFI_LBA StartLba
,
2332 IN UINTN NumberOfBlocks
2335 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteOp
);
2338 This function is called by the AtaBlkIoWriteBlocks() to perform
2339 writing onto media in block unit. The function has been enhanced to
2340 support >120GB access and transfer at most 65536 blocks per command
2342 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used
2343 to record all the information of the IDE device.
2344 @param DataBuffer A pointer to the source buffer for the data.
2345 @param StartLba The starting logical block address to write onto the device
2347 @param NumberOfBlocks The number of transfer data blocks.
2349 @return status is fully dependent on the return status of AtaPioDataOutExt() function.
2352 AtaWriteSectorsExt (
2353 IN IDE_BLK_IO_DEV
*IdeDev
,
2354 IN VOID
*DataBuffer
,
2355 IN EFI_LBA StartLba
,
2356 IN UINTN NumberOfBlocks
2361 UINTN BlocksRemaining
;
2368 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
2370 AtaCommand
= ATA_CMD_WRITE_SECTORS_EXT
;
2372 Buffer
= DataBuffer
;
2373 BlocksRemaining
= NumberOfBlocks
;
2375 Status
= EFI_SUCCESS
;
2377 while (BlocksRemaining
> 0) {
2379 if (BlocksRemaining
>= 0x10000) {
2381 // SectorCount is used to record the number of sectors to be written.
2382 // Max 65536 sectors can be transfered at a time.
2384 SectorCount
= 0xffff;
2386 SectorCount
= (UINT16
) BlocksRemaining
;
2390 // ByteCount is the number of bytes that will be written
2392 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
2395 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
2397 Status
= AtaPioDataOutExt (
2405 if (EFI_ERROR (Status
)) {
2409 Lba64
+= SectorCount
;
2410 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
2411 BlocksRemaining
-= SectorCount
;
2417 This function is the ATA implementation for WriteBlocks in the
2418 Block I/O Protocol interface.
2420 @param IdeBlkIoDevice Indicates the calling context.
2421 @param MediaId The media id that the write request is for.
2422 @param LBA The starting logical block address to write onto the device.
2423 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2424 of the intrinsic block size of the device.
2425 @param Buffer A pointer to the source buffer for the data.The caller
2426 is responsible for either having implicit or explicit
2427 ownership of the memory that data is written from.
2429 @retval EFI_SUCCESS Write Blocks successfully.
2430 @retval EFI_DEVICE_ERROR Write Blocks failed.
2431 @retval EFI_NO_MEDIA There is no media in the device.
2432 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2434 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2435 intrinsic block size of the device.
2436 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
2437 or the data buffer is not valid.
2439 @note If Write Block error because of device error, this function will call
2440 AtaSoftReset() function to reset device.
2443 AtaBlkIoWriteBlocks (
2444 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
2447 IN UINTN BufferSize
,
2452 EFI_BLOCK_IO_MEDIA
*Media
;
2454 UINTN NumberOfBlocks
;
2457 if (Buffer
== NULL
) {
2458 return EFI_INVALID_PARAMETER
;
2461 if (BufferSize
== 0) {
2465 Status
= EFI_SUCCESS
;
2468 // Get the intrinsic block size
2470 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
2471 BlockSize
= Media
->BlockSize
;
2472 NumberOfBlocks
= BufferSize
/ BlockSize
;
2474 if (MediaId
!= Media
->MediaId
) {
2475 return EFI_MEDIA_CHANGED
;
2478 if (BufferSize
% BlockSize
!= 0) {
2479 return EFI_BAD_BUFFER_SIZE
;
2482 if (LBA
> Media
->LastBlock
) {
2483 return EFI_INVALID_PARAMETER
;
2486 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
2487 return EFI_INVALID_PARAMETER
;
2490 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
2491 return EFI_INVALID_PARAMETER
;
2494 Status
= EFI_SUCCESS
;
2495 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
2497 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
2499 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2500 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2502 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2506 // For ATA-3 compatible device, use ATA-3 write block mechanism
2508 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2509 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2511 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
2515 if (EFI_ERROR (Status
)) {
2516 AtaSoftReset (IdeBlkIoDevice
);
2517 return EFI_DEVICE_ERROR
;
2523 Enable Long Physical Sector Feature for ATA device.
2525 @param IdeDev The IDE device data
2527 @retval EFI_SUCCESS The ATA device supports Long Physical Sector feature
2528 and corresponding fields in BlockIo structure is updated.
2529 @retval EFI_UNSUPPORTED The device is not ATA device or Long Physical Sector
2530 feature is not supported.
2533 AtaEnableLongPhysicalSector (
2534 IN IDE_BLK_IO_DEV
*IdeDev
2537 EFI_ATA_IDENTIFY_DATA
*AtaIdentifyData
;
2538 UINT16 PhyLogicSectorSupport
;
2540 ASSERT (IdeDev
->IdData
!= NULL
);
2542 // Only valid for ATA device
2544 AtaIdentifyData
= (EFI_ATA_IDENTIFY_DATA
*) &IdeDev
->IdData
->AtaData
;
2545 if ((AtaIdentifyData
->config
& 0x8000) != 0) {
2546 return EFI_UNSUPPORTED
;
2548 PhyLogicSectorSupport
= AtaIdentifyData
->phy_logic_sector_support
;
2550 // Check whether Long Physical Sector Feature is supported
2552 if ((PhyLogicSectorSupport
& 0xc000) == 0x4000) {
2553 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
= 1;
2554 IdeDev
->BlkIo
.Media
->LowestAlignedLba
= 0;
2556 // Check whether one physical block contains multiple physical blocks
2558 if ((PhyLogicSectorSupport
& 0x2000) != 0) {
2559 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
=
2560 (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
2562 // Check lowest alignment of logical blocks within physical block
2564 if ((AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0xc000) == 0x4000) {
2565 IdeDev
->BlkIo
.Media
->LowestAlignedLba
=
2566 (EFI_LBA
) (AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff);
2570 // Check logical block size
2572 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
2573 if ((PhyLogicSectorSupport
& 0x1000) != 0) {
2574 IdeDev
->BlkIo
.Media
->BlockSize
= (UINT32
) (
2575 ((AtaIdentifyData
->logic_sector_size_hi
<< 16) |
2576 AtaIdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
)
2581 return EFI_UNSUPPORTED
;
2585 Send ATA command into device with NON_DATA protocol
2587 @param IdeDev Standard IDE device private data structure
2588 @param AtaCommand The ATA command to be sent
2589 @param Device The value in Device register
2590 @param Feature The value in Feature register
2591 @param SectorCount The value in SectorCount register
2592 @param LbaLow The value in LBA_LOW register
2593 @param LbaMiddle The value in LBA_MIDDLE register
2594 @param LbaHigh The value in LBA_HIGH register
2596 @retval EFI_SUCCESS Reading succeed
2597 @retval EFI_ABORTED Command failed
2598 @retval EFI_DEVICE_ERROR Device status error.
2602 AtaNonDataCommandIn (
2603 IN IDE_BLK_IO_DEV
*IdeDev
,
2604 IN UINT8 AtaCommand
,
2607 IN UINT8 SectorCount
,
2614 UINT8 StatusRegister
;
2616 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2617 if (EFI_ERROR (Status
)) {
2618 return EFI_DEVICE_ERROR
;
2622 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2626 IdeDev
->IoPort
->Head
,
2627 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2631 // ATA commands for ATA device must be issued when DRDY is set
2633 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2634 if (EFI_ERROR (Status
)) {
2635 return EFI_DEVICE_ERROR
;
2639 // Pass parameter into device register block
2641 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2642 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature
);
2643 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
2644 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2645 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMiddle
);
2646 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2649 // Send command via Command Register
2651 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2654 // Wait for command completion
2655 // For ATAPI_SMART_CMD, we may need more timeout to let device
2656 // adjust internal states.
2658 if (AtaCommand
== ATA_CMD_SMART
) {
2659 Status
= WaitForBSYClear (IdeDev
, ATASMARTTIMEOUT
);
2661 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2663 if (EFI_ERROR (Status
)) {
2664 return EFI_DEVICE_ERROR
;
2667 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
2668 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
2670 // Failed to execute command, abort operation
2679 Send ATA Ext command into device with NON_DATA protocol
2681 @param IdeDev Standard IDE device private data structure
2682 @param AtaCommand The ATA command to be sent
2683 @param Device The value in Device register
2684 @param Feature The value in Feature register
2685 @param SectorCount The value in SectorCount register
2686 @param LbaAddress The LBA address in 48-bit mode
2688 @retval EFI_SUCCESS Reading succeed
2689 @retval EFI_ABORTED Command failed
2690 @retval EFI_DEVICE_ERROR Device status error.
2694 AtaNonDataCommandInExt (
2695 IN IDE_BLK_IO_DEV
*IdeDev
,
2696 IN UINT8 AtaCommand
,
2699 IN UINT16 SectorCount
,
2700 IN EFI_LBA LbaAddress
2704 UINT8 StatusRegister
;
2711 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2712 if (EFI_ERROR (Status
)) {
2713 return EFI_DEVICE_ERROR
;
2717 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2721 IdeDev
->IoPort
->Head
,
2722 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2726 // ATA commands for ATA device must be issued when DRDY is set
2728 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2729 if (EFI_ERROR (Status
)) {
2730 return EFI_DEVICE_ERROR
;
2734 // Pass parameter into device register block
2736 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2739 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2741 Feature8
= (UINT8
) (Feature
>> 8);
2742 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2744 Feature8
= (UINT8
) Feature
;
2745 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2748 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2750 SectorCount8
= (UINT8
) (SectorCount
>> 8);
2751 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2753 SectorCount8
= (UINT8
) SectorCount
;
2754 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2757 // Fill the start LBA registers, which are also two-byte FIFO
2759 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2760 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
2761 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
2762 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2763 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2764 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2766 LbaLow
= (UINT8
) LbaAddress
;
2767 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2768 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2769 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2770 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2771 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2774 // Send command via Command Register
2776 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2779 // Wait for command completion
2781 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2782 if (EFI_ERROR (Status
)) {
2783 return EFI_DEVICE_ERROR
;
2786 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
2787 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
2789 // Failed to execute command, abort operation