2 This file contains all helper functions on the ATA command
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
7 @par Revision Reference:
8 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
9 update - ATAIdentity() func
10 update - AtaBlockIoReadBlocks() func
11 update - AtaBlockIoWriteBlocks() func
12 add - AtaAtapi6Identify() func
13 add - AtaReadSectorsExt() func
14 add - AtaWriteSectorsExt() func
15 add - AtaPioDataInExt() func
16 add - AtaPioDataOutExt() func
22 This function is called by ATAIdentify() to identity whether this disk
23 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
25 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
26 all the information of the IDE device.
28 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one and
29 48-bit addressing must be used
30 @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but the
31 capacity is below 120G, 48bit addressing is not needed
32 @retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
33 @retval EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.
35 @note This function must be called after DEVICE_IDENTITY command has been
41 IN IDE_BLK_IO_DEV
*IdeDev
47 EFI_IDENTIFY_DATA
*Atapi6IdentifyStruct
;
49 if (IdeDev
->IdData
== NULL
) {
50 return EFI_INVALID_PARAMETER
;
53 Atapi6IdentifyStruct
= IdeDev
->IdData
;
55 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& (BIT15
| BIT14
)) != 0x4000) {
57 // Per ATA-6 spec, word83: bit15 is zero and bit14 is one
59 return EFI_DEVICE_ERROR
;
62 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& BIT10
) == 0) {
64 // The device dosn't support 48 bit addressing
66 return EFI_UNSUPPORTED
;
70 // 48 bit address feature set is supported, get maximum capacity
72 Capacity
= Atapi6IdentifyStruct
->AtaData
.maximum_lba_for_48bit_addressing
[0];
73 for (Index
= 1; Index
< 4; Index
++) {
75 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
77 TmpLba
= Atapi6IdentifyStruct
->AtaData
.maximum_lba_for_48bit_addressing
[Index
];
78 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
81 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
83 // Capacity exceeds 120GB. 48-bit addressing is really needed
85 IdeDev
->Type
= Ide48bitAddressingHardDisk
;
88 // Fill block media information:Media->LogicalPartition ,
89 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
91 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
92 IdeDev
->BlkIo
.Media
->MediaId
= 1;
93 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
94 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
95 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
96 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
97 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
102 return EFI_UNSUPPORTED
;
105 Enable SMART of the disk if supported
107 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
108 all the information of the IDE device.
112 IN IDE_BLK_IO_DEV
*IdeDev
116 BOOLEAN SMARTSupported
;
118 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
124 // Detect if the device supports S.M.A.R.T.
126 if ((IdeDev
->IdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
128 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
132 if ((IdeDev
->IdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
134 // S.M.A.R.T is not supported by the device
136 SMARTSupported
= FALSE
;
138 SMARTSupported
= TRUE
;
142 if (!SMARTSupported
) {
144 // Report nonsupport status code
147 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
148 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
152 // Enable this feature
156 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
159 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
160 Status
= AtaNonDataCommandIn (
164 ATA_SMART_ENABLE_OPERATION
,
171 // Detect if this feature is enabled
173 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
174 if (TmpAtaIdentifyPointer
== NULL
) {
178 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
179 Status
= AtaPioDataIn (
181 (VOID
*) TmpAtaIdentifyPointer
,
182 sizeof (EFI_IDENTIFY_DATA
),
183 ATA_CMD_IDENTIFY_DRIVE
,
190 if (EFI_ERROR (Status
)) {
191 gBS
->FreePool (TmpAtaIdentifyPointer
);
196 // Check if the feature is enabled
198 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
202 AtaNonDataCommandIn (
206 ATA_SMART_RETURN_STATUS
,
212 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
213 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
215 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
217 // The threshold exceeded condition is not detected by the device
221 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
224 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
226 // The threshold exceeded condition is detected by the device
230 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
236 // Report disabled status code
239 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
240 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
244 gBS
->FreePool (TmpAtaIdentifyPointer
);
250 Sends out an ATA Identify Command to the specified device.
252 This function is called by DiscoverIdeDevice() during its device
253 identification. It sends out the ATA Identify Command to the
254 specified device. Only ATA device responses to this command. If
255 the command succeeds, it returns the Identify data structure which
256 contains information about the device. This function extracts the
257 information it needs to fill the IDE_BLK_IO_DEV data structure,
258 including device type, media block size, media capacity, and etc.
260 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
261 all the information of the IDE device.
263 @retval EFI_SUCCESS Identify ATA device successfully.
264 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or device is not ATA device.
265 @note parameter IdeDev will be updated in this function.
270 IN IDE_BLK_IO_DEV
*IdeDev
274 EFI_IDENTIFY_DATA
*AtaIdentifyPointer
;
280 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
281 // the ATA Identify command
283 AtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
284 if (AtaIdentifyPointer
== NULL
) {
285 return EFI_OUT_OF_RESOURCES
;
289 // use ATA PIO Data In protocol to send ATA Identify command
290 // and receive data from device
292 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
297 Status
= AtaPioDataIn (
299 (VOID
*) AtaIdentifyPointer
,
300 sizeof (EFI_IDENTIFY_DATA
),
301 ATA_CMD_IDENTIFY_DRIVE
,
309 // If ATA Identify command succeeds, then according to the received
311 // identify the device type ( ATA or not ).
312 // If ATA device, fill the information in IdeDev.
313 // If not ATA device, return IDE_DEVICE_ERROR
315 if (!EFI_ERROR (Status
)) {
317 IdeDev
->IdData
= AtaIdentifyPointer
;
320 // Print ATA Module Name
322 PrintAtaModuleName (IdeDev
);
325 // bit 15 of pAtaIdentify->config is used to identify whether device is
326 // ATA device or ATAPI device.
327 // if 0, means ATA device; if 1, means ATAPI device.
329 if ((AtaIdentifyPointer
->AtaData
.config
& 0x8000) == 0x00) {
331 // Detect if support S.M.A.R.T. If yes, enable it as default
333 AtaSMARTSupport (IdeDev
);
336 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
338 Status
= AtaAtapi6Identify (IdeDev
);
339 if (!EFI_ERROR (Status
)) {
341 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
344 } else if (Status
== EFI_DEVICE_ERROR
) {
346 // Some disk with big capacity (>200GB) is slow when being identified
347 // and will return all zero for word83.
348 // We try twice at first. If it fails, we do a SoftRest and try again.
353 // Do a SoftRest before the third attempt.
355 AtaSoftReset (IdeDev
);
360 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
362 IdeDev
->Type
= IdeHardDisk
;
365 // Block Media Information:
366 // Media->LogicalPartition , Media->WriteCaching will be filled
367 // in the DiscoverIdeDevcie() function.
369 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
370 IdeDev
->BlkIo
.Media
->MediaId
= 1;
371 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
372 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
373 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
374 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
377 // Calculate device capacity
379 Capacity
= ((UINT32
)AtaIdentifyPointer
->AtaData
.user_addressable_sectors_hi
<< 16) |
380 AtaIdentifyPointer
->AtaData
.user_addressable_sectors_lo
;
381 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
390 gBS
->FreePool (AtaIdentifyPointer
);
392 // Make sure the pIdData will not be freed again.
394 IdeDev
->IdData
= NULL
;
396 return EFI_DEVICE_ERROR
;
400 This function is a helper function used to change the char order in a string. It
401 is designed specially for the PrintAtaModuleName() function. After the IDE device
402 is detected, the IDE driver gets the device module name by sending ATA command
403 called ATA Identify Command or ATAPI Identify Command to the specified IDE device.
404 The module name returned is a string of ASCII characters: the first character is bit8--bit15
405 of the first word, the second character is BIT0--bit7 of the first word and so on. Thus
406 the string can not be print directly before it is preprocessed by this func to change
407 the order of characters in each word in the string.
409 @param Destination Indicates the destination string.
410 @param Source Indicates the source string.
411 @param Size the length of the string
415 IN CHAR8
*Destination
,
423 for (Index
= 0; Index
< Size
; Index
+= 2) {
425 Temp
= Source
[Index
+ 1];
426 Destination
[Index
+ 1] = Source
[Index
];
427 Destination
[Index
] = Temp
;
431 This function is called by ATAIdentify() or ATAPIIdentify() to print device's module name.
433 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
434 all the information of the IDE device.
438 IN IDE_BLK_IO_DEV
*IdeDev
441 if (IdeDev
->IdData
== NULL
) {
445 SwapStringChars (IdeDev
->ModelName
, IdeDev
->IdData
->AtaData
.ModelName
, 40);
446 IdeDev
->ModelName
[40] = 0x00;
450 This function is used to send out ATA commands conforms to the PIO Data In Protocol.
452 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
453 all the information of the IDE device.
454 @param Buffer buffer contained data transferred from device to host.
455 @param ByteCount data size in byte unit of the buffer.
456 @param AtaCommand value of the Command Register
457 @param Head value of the Head/Device Register
458 @param SectorCount value of the Sector Count Register
459 @param SectorNumber value of the Sector Number Register
460 @param CylinderLsb value of the low byte of the Cylinder Register
461 @param CylinderMsb value of the high byte of the Cylinder Register
463 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
464 @retval EFI_DEVICE_ERROR command sent failed.
469 IN IDE_BLK_IO_DEV
*IdeDev
,
474 IN UINT8 SectorCount
,
475 IN UINT8 SectorNumber
,
476 IN UINT8 CylinderLsb
,
485 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
486 if (EFI_ERROR (Status
)) {
487 return EFI_DEVICE_ERROR
;
491 // e0:1110,0000-- bit7 and bit5 are reserved bits.
492 // bit6 set means LBA mode
496 IdeDev
->IoPort
->Head
,
497 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
501 // All ATAPI device's ATA commands can be issued regardless of the
504 if (IdeDev
->Type
== IdeHardDisk
) {
506 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
507 if (EFI_ERROR (Status
)) {
508 return EFI_DEVICE_ERROR
;
512 // set all the command parameters
513 // Before write to all the following registers, BSY and DRQ must be 0.
515 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
516 if (EFI_ERROR (Status
)) {
517 return EFI_DEVICE_ERROR
;
520 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
521 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
524 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
525 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
526 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
527 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
530 // send command via Command Register
532 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
534 Buffer16
= (UINT16
*) Buffer
;
537 // According to PIO data in protocol, host can perform a series of reads to
538 // the data register after each time device set DRQ ready;
539 // The data size of "a series of read" is command specific.
540 // For most ATA command, data size received from device will not exceed
541 // 1 sector, hence the data size for "a series of read" can be the whole data
542 // size of one command request.
543 // For ATA command such as Read Sector command, the data size of one ATA
544 // command request is often larger than 1 sector, according to the
545 // Read Sector command, the data size of "a series of read" is exactly 1
547 // Here for simplification reason, we specify the data size for
548 // "a series of read" to 1 sector (256 words) if data size of one ATA command
549 // request is larger than 256 words.
554 // used to record bytes of currently transfered data
558 while (WordCount
< ByteCount
/ 2) {
560 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
562 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
563 if (EFI_ERROR (Status
)) {
564 return EFI_DEVICE_ERROR
;
567 Status
= CheckErrorStatus (IdeDev
);
568 if (EFI_ERROR (Status
)) {
569 return EFI_DEVICE_ERROR
;
573 // Get the byte count for one series of read
575 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
576 Increment
= ByteCount
/ 2 - WordCount
;
579 IDEReadPortWMultiple (
581 IdeDev
->IoPort
->Data
,
586 WordCount
+= Increment
;
587 Buffer16
+= Increment
;
591 DRQClear (IdeDev
, ATATIMEOUT
);
593 return CheckErrorStatus (IdeDev
);
597 This function is used to send out ATA commands conforms to the
598 PIO Data Out Protocol.
600 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
601 to record all the information of the IDE device.
602 @param *Buffer buffer contained data transferred from host to device.
603 @param ByteCount data size in byte unit of the buffer.
604 @param AtaCommand value of the Command Register
605 @param Head value of the Head/Device Register
606 @param SectorCount value of the Sector Count Register
607 @param SectorNumber value of the Sector Number Register
608 @param CylinderLsb value of the low byte of the Cylinder Register
609 @param CylinderMsb value of the high byte of the Cylinder Register
611 @retval EFI_SUCCESS send out the ATA command and device received required
613 @retval EFI_DEVICE_ERROR command sent failed.
618 IN IDE_BLK_IO_DEV
*IdeDev
,
623 IN UINT8 SectorCount
,
624 IN UINT8 SectorNumber
,
625 IN UINT8 CylinderLsb
,
634 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
635 if (EFI_ERROR (Status
)) {
636 return EFI_DEVICE_ERROR
;
640 // select device via Head/Device register.
641 // Before write Head/Device register, BSY and DRQ must be 0.
643 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
644 if (EFI_ERROR (Status
)) {
645 return EFI_DEVICE_ERROR
;
649 // e0:1110,0000-- bit7 and bit5 are reserved bits.
650 // bit6 set means LBA mode
654 IdeDev
->IoPort
->Head
,
655 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
658 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
659 if (EFI_ERROR (Status
)) {
660 return EFI_DEVICE_ERROR
;
664 // set all the command parameters
665 // Before write to all the following registers, BSY and DRQ must be 0.
667 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
668 if (EFI_ERROR (Status
)) {
669 return EFI_DEVICE_ERROR
;
672 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
673 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
674 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
675 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
678 // send command via Command Register
680 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
682 Buffer16
= (UINT16
*) Buffer
;
685 // According to PIO data out protocol, host can perform a series of
686 // writes to the data register after each time device set DRQ ready;
687 // The data size of "a series of read" is command specific.
688 // For most ATA command, data size written to device will not exceed 1 sector,
689 // hence the data size for "a series of write" can be the data size of one
691 // For ATA command such as Write Sector command, the data size of one
692 // ATA command request is often larger than 1 sector, according to the
693 // Write Sector command, the data size of "a series of read" is exactly
695 // Here for simplification reason, we specify the data size for
696 // "a series of write" to 1 sector (256 words) if data size of one ATA command
697 // request is larger than 256 words.
702 while (WordCount
< ByteCount
/ 2) {
705 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
706 // data transfer can be performed only when DRQ is ready.
708 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
709 if (EFI_ERROR (Status
)) {
710 return EFI_DEVICE_ERROR
;
713 Status
= CheckErrorStatus (IdeDev
);
714 if (EFI_ERROR (Status
)) {
715 return EFI_DEVICE_ERROR
;
719 // Check the remaining byte count is less than 512 bytes
721 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
722 Increment
= ByteCount
/ 2 - WordCount
;
725 // perform a series of write without check DRQ ready
728 IDEWritePortWMultiple (
730 IdeDev
->IoPort
->Data
,
734 WordCount
+= Increment
;
735 Buffer16
+= Increment
;
739 DRQClear (IdeDev
, ATATIMEOUT
);
741 return CheckErrorStatus (IdeDev
);
745 This function is used to analyze the Status Register and print out
746 some debug information and if there is ERR bit set in the Status
747 Register, the Error Register's value is also be parsed and print out.
749 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to
750 record all the information of the IDE device.
752 @retval EFI_SUCCESS No err information in the Status Register.
753 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
758 IN IDE_BLK_IO_DEV
*IdeDev
761 UINT8 StatusRegister
;
764 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
768 if ((StatusRegister
& ATA_STSREG_DWF
) != 0) {
771 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
776 if ((StatusRegister
& ATA_STSREG_CORR
) != 0) {
779 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
784 if ((StatusRegister
& ATA_STSREG_ERR
) != 0) {
785 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
787 if ((ErrorRegister
& ATA_ERRREG_BBK
) != 0) {
790 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
795 if ((ErrorRegister
& ATA_ERRREG_UNC
) != 0) {
798 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
803 if ((ErrorRegister
& ATA_ERRREG_MC
) != 0) {
806 "CheckErrorStatus()-- %02x : Error : Media Change\n",
811 if ((ErrorRegister
& ATA_ERRREG_ABRT
) != 0) {
814 "CheckErrorStatus()-- %02x : Error : Abort\n",
819 if ((ErrorRegister
& ATA_ERRREG_TK0NF
) != 0) {
822 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
827 if ((ErrorRegister
& ATA_ERRREG_AMNF
) != 0) {
830 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
838 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
842 return EFI_DEVICE_ERROR
;
847 This function is called by the AtaBlkIoReadBlocks() to perform reading from
850 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
851 all the information of the IDE device.
852 @param DataBuffer A pointer to the destination buffer for the data.
853 @param Lba The starting logical block address to read from on the device media.
854 @param NumberOfBlocks The number of transfer data blocks.
856 @return status is fully dependent on the return status of AtaPioDataIn() function.
861 IN IDE_BLK_IO_DEV
*IdeDev
,
864 IN UINTN NumberOfBlocks
868 UINTN BlocksRemaining
;
883 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
885 AtaCommand
= ATA_CMD_READ_SECTORS
;
888 BlocksRemaining
= NumberOfBlocks
;
890 Lba32
= (UINT32
) Lba
;
892 Status
= EFI_SUCCESS
;
894 while (BlocksRemaining
> 0) {
897 // in ATA-3 spec, LBA is in 28 bit width
899 Lba0
= (UINT8
) Lba32
;
900 Lba1
= (UINT8
) (Lba32
>> 8);
901 Lba2
= (UINT8
) (Lba32
>> 16);
903 // low 4 bit of Lba3 stands for LBA bit24~bit27.
905 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
907 if (BlocksRemaining
>= 0x100) {
910 // SectorCount8 is sent to Sector Count register, 0x00 means 256
911 // sectors to be read
915 // SectorCount is used to record the number of sectors to be read
920 SectorCount8
= (UINT8
) BlocksRemaining
;
921 SectorCount
= (UINT16
) BlocksRemaining
;
925 // ByteCount is the number of bytes that will be read
927 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
930 // call AtaPioDataIn() to send Read Sector Command and receive data read
932 Status
= AtaPioDataIn (
943 if (EFI_ERROR (Status
)) {
947 Lba32
+= SectorCount
;
948 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
949 BlocksRemaining
-= SectorCount
;
956 This function is called by the AtaBlkIoWriteBlocks() to perform writing onto
959 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used to record
960 all the information of the IDE device.
961 @param BufferData A pointer to the source buffer for the data.
962 @param Lba The starting logical block address to write onto the device media.
963 @param NumberOfBlocks The number of transfer data blocks.
965 @return status is fully dependent on the return status of AtaPioDataIn() function.
970 IN IDE_BLK_IO_DEV
*IdeDev
,
973 IN UINTN NumberOfBlocks
977 UINTN BlocksRemaining
;
992 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
994 AtaCommand
= ATA_CMD_WRITE_SECTORS
;
996 BlocksRemaining
= NumberOfBlocks
;
998 Lba32
= (UINT32
) Lba
;
1000 Status
= EFI_SUCCESS
;
1002 while (BlocksRemaining
> 0) {
1004 Lba0
= (UINT8
) Lba32
;
1005 Lba1
= (UINT8
) (Lba32
>> 8);
1006 Lba2
= (UINT8
) (Lba32
>> 16);
1007 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
1009 if (BlocksRemaining
>= 0x100) {
1012 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
1015 SectorCount8
= 0x00;
1017 // SectorCount is used to record the number of sectors to be written
1022 SectorCount8
= (UINT8
) BlocksRemaining
;
1023 SectorCount
= (UINT16
) BlocksRemaining
;
1026 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1028 Status
= AtaPioDataOut (
1039 if (EFI_ERROR (Status
)) {
1043 Lba32
+= SectorCount
;
1044 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1045 BlocksRemaining
-= SectorCount
;
1051 This function is used to implement the Soft Reset on the specified device. But,
1052 the ATA Soft Reset mechanism is so strong a reset method that it will force
1053 resetting on both devices connected to the same cable.
1055 It is called by IdeBlkIoReset(), a interface function of Block
1058 This function can also be used by the ATAPI device to perform reset when
1059 ATAPI Reset command is failed.
1061 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1062 all the information of the IDE device.
1063 @retval EFI_SUCCESS Soft reset completes successfully.
1064 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
1066 @note The registers initial values after ATA soft reset are different
1067 to the ATA device and ATAPI device.
1071 IN IDE_BLK_IO_DEV
*IdeDev
1075 UINT8 DeviceControl
;
1079 // set SRST bit to initiate soft reset
1081 DeviceControl
|= ATA_CTLREG_SRST
;
1084 // disable Interrupt
1086 DeviceControl
|= BIT1
;
1088 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1091 // SRST should assert for at least 5 us, we use 10 us for
1092 // better compatibility
1097 // Enable interrupt to support UDMA, and clear SRST bit
1100 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1103 // Wait for at least 2 ms to check BSY status, we use 10 ms
1104 // for better compatibility
1108 // slave device needs at most 31s to clear BSY
1110 if (WaitForBSYClear (IdeDev
, 31000) == EFI_TIMEOUT
) {
1111 return EFI_DEVICE_ERROR
;
1117 This function is used to send out ATA commands conforms to the PIO Data In
1118 Protocol, supporting ATA/ATAPI-6 standard
1120 Comparing with ATA-3 data in protocol, we have two differents here:
1121 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1122 wait will frequently fail... cause writing function return error)
1124 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1125 slow down writing performance by 100 times!)
1127 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1128 to record all the information of the IDE device.
1129 @param Buffer buffer contained data transferred from device to host.
1130 @param ByteCount data size in byte unit of the buffer.
1131 @param AtaCommand value of the Command Register
1132 @param StartLba the start LBA of this transaction
1133 @param SectorCount the count of sectors to be transfered
1135 @retval EFI_SUCCESS send out the ATA command and device send required data successfully.
1136 @retval EFI_DEVICE_ERROR command sent failed.
1141 IN IDE_BLK_IO_DEV
*IdeDev
,
1142 IN OUT VOID
*Buffer
,
1143 IN UINT32 ByteCount
,
1144 IN UINT8 AtaCommand
,
1145 IN EFI_LBA StartLba
,
1146 IN UINT16 SectorCount
1159 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1160 if (EFI_ERROR (Status
)) {
1161 return EFI_DEVICE_ERROR
;
1165 // Select device, set bit6 as 1 to indicate LBA mode is used
1167 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1171 IdeDev
->IoPort
->Head
,
1176 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1178 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1179 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1181 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1182 if (EFI_ERROR (Status
)) {
1183 return EFI_DEVICE_ERROR
;
1188 // Fill feature register if needed
1190 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
1191 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1195 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1197 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1198 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1200 SectorCount8
= (UINT8
) SectorCount
;
1201 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1204 // Fill the start LBA registers, which are also two-byte FIFO
1206 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1207 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1208 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1209 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1210 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1211 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1213 LbaLow
= (UINT8
) StartLba
;
1214 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1215 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1216 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1217 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1218 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1221 // Send command via Command Register, invoking the processing of this command
1223 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1225 Buffer16
= (UINT16
*) Buffer
;
1228 // According to PIO data in protocol, host can perform a series of reads to
1229 // the data register after each time device set DRQ ready;
1238 // used to record bytes of currently transfered data
1242 while (WordCount
< ByteCount
/ 2) {
1244 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1246 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1247 if (EFI_ERROR (Status
)) {
1248 return EFI_DEVICE_ERROR
;
1251 Status
= CheckErrorStatus (IdeDev
);
1252 if (EFI_ERROR (Status
)) {
1253 return EFI_DEVICE_ERROR
;
1257 // Get the byte count for one series of read
1259 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1260 Increment
= ByteCount
/ 2 - WordCount
;
1263 IDEReadPortWMultiple (
1265 IdeDev
->IoPort
->Data
,
1270 WordCount
+= Increment
;
1271 Buffer16
+= Increment
;
1275 return CheckErrorStatus (IdeDev
);
1278 Send ATA Ext command into device with NON_DATA protocol.
1280 @param IdeDev Standard IDE device private data structure
1281 @param AtaCommand The ATA command to be sent
1282 @param Device The value in Device register
1283 @param Feature The value in Feature register
1284 @param SectorCount The value in SectorCount register
1285 @param LbaAddress The LBA address in 48-bit mode
1287 @retval EFI_SUCCESS Reading succeed
1288 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1292 AtaCommandIssueExt (
1293 IN IDE_BLK_IO_DEV
*IdeDev
,
1294 IN UINT8 AtaCommand
,
1297 IN UINT16 SectorCount
,
1298 IN EFI_LBA LbaAddress
1308 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1309 if (EFI_ERROR (Status
)) {
1310 return EFI_DEVICE_ERROR
;
1314 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1318 IdeDev
->IoPort
->Head
,
1319 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1323 // ATA commands for ATA device must be issued when DRDY is set
1325 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1326 if (EFI_ERROR (Status
)) {
1327 return EFI_DEVICE_ERROR
;
1331 // Pass parameter into device register block
1333 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1336 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1338 Feature8
= (UINT8
) (Feature
>> 8);
1339 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1341 Feature8
= (UINT8
) Feature
;
1342 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1345 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1347 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1348 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1350 SectorCount8
= (UINT8
) SectorCount
;
1351 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1354 // Fill the start LBA registers, which are also two-byte FIFO
1356 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1357 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1358 LbaLow
= (UINT8
) LbaAddress
;
1359 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1361 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1362 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1363 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1364 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1366 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1367 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1368 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1369 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1372 // Work around for Segate 160G disk writing
1377 // Send command via Command Register
1379 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1382 // Stall at least 400ns
1389 Send ATA Ext command into device with NON_DATA protocol
1391 @param IdeDev Standard IDE device private data structure
1392 @param AtaCommand The ATA command to be sent
1393 @param Device The value in Device register
1394 @param Feature The value in Feature register
1395 @param SectorCount The value in SectorCount register
1396 @param LbaAddress The LBA address in 48-bit mode
1398 @retval EFI_SUCCESS Reading succeed
1399 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1404 IN IDE_BLK_IO_DEV
*IdeDev
,
1405 IN UINT8 AtaCommand
,
1408 IN UINT16 SectorCount
,
1409 IN EFI_LBA LbaAddress
1420 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1421 if (EFI_ERROR (Status
)) {
1422 return EFI_DEVICE_ERROR
;
1426 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1430 IdeDev
->IoPort
->Head
,
1431 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1435 // ATA commands for ATA device must be issued when DRDY is set
1437 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1438 if (EFI_ERROR (Status
)) {
1439 return EFI_DEVICE_ERROR
;
1442 Lba0
= (UINT8
) LbaAddress
;
1443 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1444 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1445 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1446 Device
= (UINT8
) (Device
| Lba3
);
1449 // Pass parameter into device register block
1451 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1454 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1456 Feature8
= (UINT8
) Feature
;
1457 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1460 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1462 SectorCount8
= (UINT8
) SectorCount
;
1463 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1466 // Fill the start LBA registers, which are also two-byte FIFO
1469 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
1470 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
1471 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
1474 // Send command via Command Register
1476 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1479 // Stall at least 400ns
1486 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
1488 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1489 to record all the information of the IDE device.
1490 @param DataBuffer A pointer to the source buffer for the data.
1491 @param StartLba The starting logical block address to write to
1492 on the device media.
1493 @param NumberOfBlocks The number of transfer data blocks.
1494 @param UdmaOp The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
1495 AtaUdmaWriteOp, AtaUdmaWriteExOp
1497 @retval EFI_SUCCESS the operation is successful.
1498 @retval EFI_OUT_OF_RESOURCES Build PRD table failed
1499 @retval EFI_UNSUPPORTED Unknown channel or operations command
1500 @retval EFI_DEVICE_ERROR Ata command execute failed
1505 IN IDE_BLK_IO_DEV
*IdeDev
,
1506 IN VOID
*DataBuffer
,
1507 IN EFI_LBA StartLba
,
1508 IN UINTN NumberOfBlocks
,
1509 IN ATA_UDMA_OPERATION UdmaOp
1512 IDE_DMA_PRD
*PrdAddr
;
1513 IDE_DMA_PRD
*UsedPrdAddr
;
1514 IDE_DMA_PRD
*TempPrdAddr
;
1515 UINT8 RegisterValue
;
1517 UINT64 IoPortForBmic
;
1518 UINT64 IoPortForBmis
;
1519 UINT64 IoPortForBmid
;
1523 UINTN ByteAvailable
;
1525 UINTN RemainBlockNum
;
1526 UINT8 DeviceControl
;
1531 EFI_PHYSICAL_ADDRESS DeviceAddress
;
1532 UINTN MaxDmaCommandSectors
;
1533 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp
;
1538 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
1539 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
1540 AtaCommand
= ATA_CMD_READ_DMA
;
1542 case AtaUdmaReadExtOp
:
1543 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
1544 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
1545 AtaCommand
= ATA_CMD_READ_DMA_EXT
;
1547 case AtaUdmaWriteOp
:
1548 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
1549 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
1550 AtaCommand
= ATA_CMD_WRITE_DMA
;
1552 case AtaUdmaWriteExtOp
:
1553 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
1554 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
1555 AtaCommand
= ATA_CMD_WRITE_DMA_EXT
;
1558 return EFI_UNSUPPORTED
;
1565 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1566 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1569 // Enable interrupt to support UDMA
1572 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1574 if (IdePrimary
== IdeDev
->Channel
) {
1575 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
1576 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
1577 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
1579 if (IdeSecondary
== IdeDev
->Channel
) {
1580 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
1581 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
1582 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
1584 return EFI_UNSUPPORTED
;
1589 // Read BMIS register and clear ERROR and INTR bit
1591 IdeDev
->PciIo
->Io
.Read (
1594 EFI_PCI_IO_PASS_THROUGH_BAR
,
1600 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1602 IdeDev
->PciIo
->Io
.Write (
1605 EFI_PCI_IO_PASS_THROUGH_BAR
,
1611 Status
= EFI_SUCCESS
;
1613 RemainBlockNum
= NumberOfBlocks
;
1614 while (RemainBlockNum
> 0) {
1616 if (RemainBlockNum
>= MaxDmaCommandSectors
) {
1618 // SectorCount is used to record the number of sectors to be read
1619 // Max 65536 sectors can be transfered at a time.
1621 NumberOfBlocks
= MaxDmaCommandSectors
;
1622 RemainBlockNum
-= MaxDmaCommandSectors
;
1624 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
1629 // Calculate the number of PRD table to make sure the memory region
1630 // not cross 64K boundary
1632 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
1633 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
1638 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
1639 Status
= IdeDev
->PciIo
->AllocateBuffer (
1642 EfiBootServicesData
,
1647 if (EFI_ERROR (Status
)) {
1648 return EFI_OUT_OF_RESOURCES
;
1650 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
1652 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
1654 // To make sure PRD is allocated in one 64K page
1656 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
1657 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
1659 if ((UINTN
) PrdAddr
& 0x03) {
1660 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
1662 UsedPrdAddr
= PrdAddr
;
1667 // Build the PRD table
1669 Status
= IdeDev
->PciIo
->Map (
1677 if (EFI_ERROR (Status
)) {
1678 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1679 return EFI_OUT_OF_RESOURCES
;
1681 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
1682 TempPrdAddr
= UsedPrdAddr
;
1685 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
1687 if (ByteCount
<= ByteAvailable
) {
1688 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
1689 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
1690 TempPrdAddr
->EndOfTable
= 0x8000;
1694 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
1695 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
1697 ByteCount
-= ByteAvailable
;
1698 PrdBuffer
+= ByteAvailable
;
1703 // Set the base address to BMID register
1705 IdeDev
->PciIo
->Io
.Write (
1707 EfiPciIoWidthUint32
,
1708 EFI_PCI_IO_PASS_THROUGH_BAR
,
1715 // Set BMIC register to identify the operation direction
1717 IdeDev
->PciIo
->Io
.Read (
1720 EFI_PCI_IO_PASS_THROUGH_BAR
,
1726 if (UdmaOp
== AtaUdmaReadExtOp
|| UdmaOp
== AtaUdmaReadOp
) {
1727 RegisterValue
|= BMIC_NREAD
;
1729 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
1732 IdeDev
->PciIo
->Io
.Write (
1735 EFI_PCI_IO_PASS_THROUGH_BAR
,
1741 if (UdmaOp
== AtaUdmaWriteExtOp
|| UdmaOp
== AtaUdmaReadExtOp
) {
1742 Status
= AtaCommandIssueExt (
1747 (UINT16
) NumberOfBlocks
,
1751 Status
= AtaCommandIssue (
1756 (UINT16
) NumberOfBlocks
,
1761 if (EFI_ERROR (Status
)) {
1762 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1763 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
1764 return EFI_DEVICE_ERROR
;
1768 // Set START bit of BMIC register
1770 IdeDev
->PciIo
->Io
.Read (
1773 EFI_PCI_IO_PASS_THROUGH_BAR
,
1779 RegisterValue
|= BMIC_START
;
1781 IdeDev
->PciIo
->Io
.Write (
1784 EFI_PCI_IO_PASS_THROUGH_BAR
,
1791 // Check the INTERRUPT and ERROR bit of BMIS
1792 // Max transfer number of sectors for one command is 65536(32Mbyte),
1793 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
1794 // So set the variable Count to 2000, for about 2 second timeout time.
1796 Status
= EFI_SUCCESS
;
1800 IdeDev
->PciIo
->Io
.Read (
1803 EFI_PCI_IO_PASS_THROUGH_BAR
,
1808 if (((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) != 0) || (Count
== 0)) {
1809 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Count
== 0)) {
1810 Status
= EFI_DEVICE_ERROR
;
1820 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
1821 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
1823 // Read BMIS register and clear ERROR and INTR bit
1825 IdeDev
->PciIo
->Io
.Read (
1828 EFI_PCI_IO_PASS_THROUGH_BAR
,
1834 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
1836 IdeDev
->PciIo
->Io
.Write (
1839 EFI_PCI_IO_PASS_THROUGH_BAR
,
1845 // Read Status Register of IDE device to clear interrupt
1847 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
1849 // Clear START bit of BMIC register
1851 IdeDev
->PciIo
->Io
.Read (
1854 EFI_PCI_IO_PASS_THROUGH_BAR
,
1860 RegisterValue
&= ~((UINT8
) BMIC_START
);
1862 IdeDev
->PciIo
->Io
.Write (
1865 EFI_PCI_IO_PASS_THROUGH_BAR
,
1871 if ((RegisterValue
& BMIS_ERROR
) != 0) {
1872 return EFI_DEVICE_ERROR
;
1875 if (EFI_ERROR (Status
)) {
1878 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
1879 StartLba
+= NumberOfBlocks
;
1883 // Disable interrupt of Select device
1885 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
1886 DeviceControl
|= ATA_CTLREG_IEN_L
;
1887 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
1894 This function is called by the AtaBlkIoReadBlocks() to perform reading from
1895 media in block unit. The function has been enhanced to support >120GB access
1896 and transfer at most 65536 blocks per command
1898 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1899 all the information of the IDE device.
1900 @param DataBuffer A pointer to the destination buffer for the data.
1901 @param StartLba The starting logical block address to read from on the device media.
1902 @param NumberOfBlocks The number of transfer data blocks.
1904 @return status depends on the function DoAtaUdma() returns.
1908 IN IDE_BLK_IO_DEV
*IdeDev
,
1909 IN VOID
*DataBuffer
,
1910 IN EFI_LBA StartLba
,
1911 IN UINTN NumberOfBlocks
1914 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadExtOp
);
1917 This function is called by the AtaBlkIoReadBlocks() to perform
1918 reading from media in block unit. The function has been enhanced to
1919 support >120GB access and transfer at most 65536 blocks per command
1921 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1922 all the information of the IDE device.
1923 @param DataBuffer A pointer to the destination buffer for the data.
1924 @param StartLba The starting logical block address to read from
1925 on the device media.
1926 @param NumberOfBlocks The number of transfer data blocks.
1928 @return status depends on the function DoAtaUdma() returns.
1932 IN IDE_BLK_IO_DEV
*IdeDev
,
1933 IN VOID
*DataBuffer
,
1934 IN EFI_LBA StartLba
,
1935 IN UINTN NumberOfBlocks
1938 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadOp
);
1942 This function is called by the AtaBlkIoReadBlocks() to perform
1943 reading from media in block unit. The function has been enhanced to
1944 support >120GB access and transfer at most 65536 blocks per command
1946 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record
1947 all the information of the IDE device.
1948 @param DataBuffer A pointer to the destination buffer for the data.
1949 @param StartLba The starting logical block address to read from on the device media.
1950 @param NumberOfBlocks The number of transfer data blocks.
1952 @return status is fully dependent on the return status of AtaPioDataInExt() function.
1956 IN IDE_BLK_IO_DEV
*IdeDev
,
1957 IN VOID
*DataBuffer
,
1958 IN EFI_LBA StartLba
,
1959 IN UINTN NumberOfBlocks
1963 UINTN BlocksRemaining
;
1971 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1973 AtaCommand
= ATA_CMD_READ_SECTORS_EXT
;
1974 Buffer
= DataBuffer
;
1975 BlocksRemaining
= NumberOfBlocks
;
1977 Status
= EFI_SUCCESS
;
1979 while (BlocksRemaining
> 0) {
1981 if (BlocksRemaining
>= 0x10000) {
1983 // SectorCount is used to record the number of sectors to be read
1984 // Max 65536 sectors can be transfered at a time.
1986 SectorCount
= 0xffff;
1988 SectorCount
= (UINT16
) BlocksRemaining
;
1992 // ByteCount is the number of bytes that will be read
1994 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1997 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1999 Status
= AtaPioDataInExt (
2007 if (EFI_ERROR (Status
)) {
2011 Lba64
+= SectorCount
;
2012 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
2013 BlocksRemaining
-= SectorCount
;
2019 This function is the ATA implementation for ReadBlocks in the
2020 Block I/O Protocol interface.
2022 @param IdeBlkIoDevice Indicates the calling context.
2023 @param MediaId The media id that the read request is for.
2024 @param Lba The starting logical block address to read from on the device.
2025 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2026 of the intrinsic block size of the device.
2028 @param Buffer A pointer to the destination buffer for the data. The caller
2029 is responsible for either having implicit or explicit ownership
2030 of the memory that data is read into.
2032 @retval EFI_SUCCESS Read Blocks successfully.
2033 @retval EFI_DEVICE_ERROR Read Blocks failed.
2034 @retval EFI_NO_MEDIA There is no media in the device.
2035 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2036 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2037 intrinsic block size of the device.
2038 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
2039 or the data buffer is not valid.
2041 @note If Read Block error because of device error, this function will call
2042 AtaSoftReset() function to reset device.
2046 AtaBlkIoReadBlocks (
2047 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
2050 IN UINTN BufferSize
,
2054 EFI_BLOCK_IO_MEDIA
*Media
;
2056 UINTN NumberOfBlocks
;
2059 if (Buffer
== NULL
) {
2060 return EFI_INVALID_PARAMETER
;
2063 if (BufferSize
== 0) {
2067 Status
= EFI_SUCCESS
;
2070 // Get the intrinsic block size
2072 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
2073 BlockSize
= Media
->BlockSize
;
2075 NumberOfBlocks
= BufferSize
/ BlockSize
;
2077 if (MediaId
!= Media
->MediaId
) {
2078 return EFI_MEDIA_CHANGED
;
2081 if (BufferSize
% BlockSize
!= 0) {
2082 return EFI_BAD_BUFFER_SIZE
;
2085 if (!(Media
->MediaPresent
)) {
2086 return EFI_NO_MEDIA
;
2089 if (Lba
> Media
->LastBlock
) {
2090 return EFI_INVALID_PARAMETER
;
2093 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
2094 return EFI_INVALID_PARAMETER
;
2097 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
2098 return EFI_INVALID_PARAMETER
;
2101 Status
= EFI_SUCCESS
;
2102 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
2104 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
2106 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2107 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2109 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2113 // For ATA-3 compatible device, use ATA-3 read block mechanism
2115 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2116 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2118 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2122 if (EFI_ERROR (Status
)) {
2123 AtaSoftReset (IdeBlkIoDevice
);
2124 return EFI_DEVICE_ERROR
;
2131 This function is used to send out ATA commands conforms to the
2132 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
2134 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
2135 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
2136 wait will frequently fail... cause writing function return error)
2138 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
2139 slow down writing performance by 100 times!)
2141 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2142 to record all the information of the IDE device.
2143 @param Buffer buffer contained data transferred from host to device.
2144 @param ByteCount data size in byte unit of the buffer.
2145 @param AtaCommand value of the Command Register
2146 @param StartLba the start LBA of this transaction
2147 @param SectorCount the count of sectors to be transfered
2149 @retval EFI_SUCCESS send out the ATA command and device receive required
2151 @retval EFI_DEVICE_ERROR command sent failed.
2156 IN IDE_BLK_IO_DEV
*IdeDev
,
2158 IN UINT32 ByteCount
,
2159 IN UINT8 AtaCommand
,
2160 IN EFI_LBA StartLba
,
2161 IN UINT16 SectorCount
2174 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2175 if (EFI_ERROR (Status
)) {
2176 return EFI_DEVICE_ERROR
;
2180 // Select device. Set bit6 as 1 to indicate LBA mode is used
2182 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
2186 IdeDev
->IoPort
->Head
,
2191 // Wait for DRDY singnal asserting.
2193 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2194 if (EFI_ERROR (Status
)) {
2195 return EFI_DEVICE_ERROR
;
2199 // Fill feature register if needed
2201 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
2202 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
2206 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2208 SectorCount8
= (UINT8
) (SectorCount
>> 8);
2209 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2211 SectorCount8
= (UINT8
) SectorCount
;
2212 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2215 // Fill the start LBA registers, which are also two-byte FIFO
2217 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
2218 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
2219 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
2220 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2221 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2222 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2224 LbaLow
= (UINT8
) StartLba
;
2225 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
2226 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
2227 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2228 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2229 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2232 // Send command via Command Register, invoking the processing of this command
2234 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2236 Buffer16
= (UINT16
*) Buffer
;
2239 // According to PIO Data Out protocol, host can perform a series of writes to
2240 // the data register after each time device set DRQ ready;
2245 // used to record bytes of currently transfered data
2249 while (WordCount
< ByteCount
/ 2) {
2251 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
2253 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
2254 if (EFI_ERROR (Status
)) {
2255 return EFI_DEVICE_ERROR
;
2258 Status
= CheckErrorStatus (IdeDev
);
2259 if (EFI_ERROR (Status
)) {
2260 return EFI_DEVICE_ERROR
;
2264 // Write data into device by one series of writing to data register
2266 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
2267 Increment
= ByteCount
/ 2 - WordCount
;
2270 IDEWritePortWMultiple (
2272 IdeDev
->IoPort
->Data
,
2277 WordCount
+= Increment
;
2278 Buffer16
+= Increment
;
2281 return CheckErrorStatus (IdeDev
);
2284 This function is called by the AtaBlkIoWriteBlocks() to perform
2285 writing to media in block unit. The function has been enhanced to
2286 support >120GB access and transfer at most 65536 blocks per command
2288 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2289 to record all the information of the IDE device.
2290 @param DataBuffer A pointer to the source buffer for the data.
2291 @param StartLba The starting logical block address to write to
2292 on the device media.
2293 @param NumberOfBlocks The number of transfer data blocks.
2295 @return status depends on the function DoAtaUdma() returns.
2299 IN IDE_BLK_IO_DEV
*IdeDev
,
2300 IN VOID
*DataBuffer
,
2301 IN EFI_LBA StartLba
,
2302 IN UINTN NumberOfBlocks
2305 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteExtOp
);
2309 This function is called by the AtaBlkIoWriteBlocks() to perform
2310 writing to media in block unit.
2312 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2313 to record all the information of the IDE device.
2314 @param DataBuffer A pointer to the source buffer for the data.
2315 @param StartLba The starting logical block address to write to
2316 on the device media.
2317 @param NumberOfBlocks The number of transfer data blocks.
2319 @return status depends on the function DoAtaUdma() returns.
2323 IN IDE_BLK_IO_DEV
*IdeDev
,
2324 IN VOID
*DataBuffer
,
2325 IN EFI_LBA StartLba
,
2326 IN UINTN NumberOfBlocks
2329 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteOp
);
2332 This function is called by the AtaBlkIoWriteBlocks() to perform
2333 writing onto media in block unit. The function has been enhanced to
2334 support >120GB access and transfer at most 65536 blocks per command
2336 @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure,used
2337 to record all the information of the IDE device.
2338 @param DataBuffer A pointer to the source buffer for the data.
2339 @param StartLba The starting logical block address to write onto the device
2341 @param NumberOfBlocks The number of transfer data blocks.
2343 @return status is fully dependent on the return status of AtaPioDataOutExt() function.
2346 AtaWriteSectorsExt (
2347 IN IDE_BLK_IO_DEV
*IdeDev
,
2348 IN VOID
*DataBuffer
,
2349 IN EFI_LBA StartLba
,
2350 IN UINTN NumberOfBlocks
2355 UINTN BlocksRemaining
;
2362 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
2364 AtaCommand
= ATA_CMD_WRITE_SECTORS_EXT
;
2366 Buffer
= DataBuffer
;
2367 BlocksRemaining
= NumberOfBlocks
;
2369 Status
= EFI_SUCCESS
;
2371 while (BlocksRemaining
> 0) {
2373 if (BlocksRemaining
>= 0x10000) {
2375 // SectorCount is used to record the number of sectors to be written.
2376 // Max 65536 sectors can be transfered at a time.
2378 SectorCount
= 0xffff;
2380 SectorCount
= (UINT16
) BlocksRemaining
;
2384 // ByteCount is the number of bytes that will be written
2386 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
2389 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
2391 Status
= AtaPioDataOutExt (
2399 if (EFI_ERROR (Status
)) {
2403 Lba64
+= SectorCount
;
2404 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
2405 BlocksRemaining
-= SectorCount
;
2411 This function is the ATA implementation for WriteBlocks in the
2412 Block I/O Protocol interface.
2414 @param IdeBlkIoDevice Indicates the calling context.
2415 @param MediaId The media id that the write request is for.
2416 @param Lba The starting logical block address to write onto the device.
2417 @param BufferSize The size of the Buffer in bytes. This must be a multiple
2418 of the intrinsic block size of the device.
2419 @param Buffer A pointer to the source buffer for the data.The caller
2420 is responsible for either having implicit or explicit
2421 ownership of the memory that data is written from.
2423 @retval EFI_SUCCESS Write Blocks successfully.
2424 @retval EFI_DEVICE_ERROR Write Blocks failed.
2425 @retval EFI_NO_MEDIA There is no media in the device.
2426 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
2428 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
2429 intrinsic block size of the device.
2430 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
2431 or the data buffer is not valid.
2433 @note If Write Block error because of device error, this function will call
2434 AtaSoftReset() function to reset device.
2437 AtaBlkIoWriteBlocks (
2438 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
2441 IN UINTN BufferSize
,
2446 EFI_BLOCK_IO_MEDIA
*Media
;
2448 UINTN NumberOfBlocks
;
2451 if (Buffer
== NULL
) {
2452 return EFI_INVALID_PARAMETER
;
2455 if (BufferSize
== 0) {
2459 Status
= EFI_SUCCESS
;
2462 // Get the intrinsic block size
2464 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
2465 BlockSize
= Media
->BlockSize
;
2466 NumberOfBlocks
= BufferSize
/ BlockSize
;
2468 if (MediaId
!= Media
->MediaId
) {
2469 return EFI_MEDIA_CHANGED
;
2472 if (BufferSize
% BlockSize
!= 0) {
2473 return EFI_BAD_BUFFER_SIZE
;
2476 if (Lba
> Media
->LastBlock
) {
2477 return EFI_INVALID_PARAMETER
;
2480 if ((Lba
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
2481 return EFI_INVALID_PARAMETER
;
2484 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
2485 return EFI_INVALID_PARAMETER
;
2488 Status
= EFI_SUCCESS
;
2489 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
2491 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
2493 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2494 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2496 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2500 // For ATA-3 compatible device, use ATA-3 write block mechanism
2502 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
2503 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2505 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, Lba
, NumberOfBlocks
);
2509 if (EFI_ERROR (Status
)) {
2510 AtaSoftReset (IdeBlkIoDevice
);
2511 return EFI_DEVICE_ERROR
;
2517 Enable Long Physical Sector Feature for ATA device.
2519 @param IdeDev The IDE device data
2521 @retval EFI_SUCCESS The ATA device supports Long Physical Sector feature
2522 and corresponding fields in BlockIo structure is updated.
2523 @retval EFI_UNSUPPORTED The device is not ATA device or Long Physical Sector
2524 feature is not supported.
2527 AtaEnableLongPhysicalSector (
2528 IN IDE_BLK_IO_DEV
*IdeDev
2531 EFI_ATA_IDENTIFY_DATA
*AtaIdentifyData
;
2532 UINT16 PhyLogicSectorSupport
;
2534 ASSERT (IdeDev
->IdData
!= NULL
);
2536 // Only valid for ATA device
2538 AtaIdentifyData
= (EFI_ATA_IDENTIFY_DATA
*) &IdeDev
->IdData
->AtaData
;
2539 if ((AtaIdentifyData
->config
& 0x8000) != 0) {
2540 return EFI_UNSUPPORTED
;
2542 PhyLogicSectorSupport
= AtaIdentifyData
->phy_logic_sector_support
;
2544 // Check whether Long Physical Sector Feature is supported
2546 if ((PhyLogicSectorSupport
& 0xc000) == 0x4000) {
2547 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
= 1;
2548 IdeDev
->BlkIo
.Media
->LowestAlignedLba
= 0;
2550 // Check whether one physical block contains multiple physical blocks
2552 if ((PhyLogicSectorSupport
& 0x2000) != 0) {
2553 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
=
2554 (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
2556 // Check lowest alignment of logical blocks within physical block
2558 if ((AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0xc000) == 0x4000) {
2559 IdeDev
->BlkIo
.Media
->LowestAlignedLba
=
2560 (EFI_LBA
) ((IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
- ((UINT32
)AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff)) %
2561 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
);
2565 // Check logical block size
2567 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
2568 if ((PhyLogicSectorSupport
& 0x1000) != 0) {
2569 IdeDev
->BlkIo
.Media
->BlockSize
= (UINT32
) (
2570 ((AtaIdentifyData
->logic_sector_size_hi
<< 16) |
2571 AtaIdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
)
2576 return EFI_UNSUPPORTED
;
2580 Send ATA command into device with NON_DATA protocol
2582 @param IdeDev Standard IDE device private data structure
2583 @param AtaCommand The ATA command to be sent
2584 @param Device The value in Device register
2585 @param Feature The value in Feature register
2586 @param SectorCount The value in SectorCount register
2587 @param LbaLow The value in LBA_LOW register
2588 @param LbaMiddle The value in LBA_MIDDLE register
2589 @param LbaHigh The value in LBA_HIGH register
2591 @retval EFI_SUCCESS Reading succeed
2592 @retval EFI_ABORTED Command failed
2593 @retval EFI_DEVICE_ERROR Device status error.
2597 AtaNonDataCommandIn (
2598 IN IDE_BLK_IO_DEV
*IdeDev
,
2599 IN UINT8 AtaCommand
,
2602 IN UINT8 SectorCount
,
2609 UINT8 StatusRegister
;
2611 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2612 if (EFI_ERROR (Status
)) {
2613 return EFI_DEVICE_ERROR
;
2617 // Select device (bit4), set Lba mode(bit6) (use 0xe0 for compatibility)
2621 IdeDev
->IoPort
->Head
,
2622 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2626 // ATA commands for ATA device must be issued when DRDY is set
2628 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2629 if (EFI_ERROR (Status
)) {
2630 return EFI_DEVICE_ERROR
;
2634 // Pass parameter into device register block
2636 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2637 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature
);
2638 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
2639 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2640 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMiddle
);
2641 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2644 // Send command via Command Register
2646 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2649 // Wait for command completion
2650 // For ATAPI_SMART_CMD, we may need more timeout to let device
2651 // adjust internal states.
2653 if (AtaCommand
== ATA_CMD_SMART
) {
2654 Status
= WaitForBSYClear (IdeDev
, ATASMARTTIMEOUT
);
2656 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2658 if (EFI_ERROR (Status
)) {
2659 return EFI_DEVICE_ERROR
;
2662 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
2663 if ((StatusRegister
& ATA_STSREG_ERR
) == ATA_STSREG_ERR
) {
2665 // Failed to execute command, abort operation