2 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 @par Revision Reference:
12 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
13 update - ATAIdentity() func
14 update - AtaBlockIoReadBlocks() func
15 update - AtaBlockIoWriteBlocks() func
16 add - AtaAtapi6Identify() func
17 add - AtaReadSectorsExt() func
18 add - AtaWriteSectorsExt() func
19 add - AtaPioDataInExt() func
20 add - AtaPioDataOutExt() func
27 Sends out an ATA Identify Command to the specified device.
29 This function is called by DiscoverIdeDevice() during its device
30 identification. It sends out the ATA Identify Command to the
31 specified device. Only ATA device responses to this command. If
32 the command succeeds, it returns the Identify data structure which
33 contains information about the device. This function extracts the
34 information it needs to fill the IDE_BLK_IO_DEV data structure,
35 including device type, media block size, media capacity, and etc.
38 pointer pointing to IDE_BLK_IO_DEV data structure,used
39 to record all the information of the IDE device.
41 @retval EFI_SUCCESS Identify ATA device successfully.
43 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or
44 device is not ATA device.
47 parameter IdeDev will be updated in this function.
52 IN IDE_BLK_IO_DEV
*IdeDev
56 EFI_IDENTIFY_DATA
*AtaIdentifyPointer
;
62 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
63 // the ATA Identify command
65 AtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
66 if (AtaIdentifyPointer
== NULL
) {
67 return EFI_OUT_OF_RESOURCES
;
71 // use ATA PIO Data In protocol to send ATA Identify command
72 // and receive data from device
74 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
79 Status
= AtaPioDataIn (
81 (VOID
*) AtaIdentifyPointer
,
82 sizeof (EFI_IDENTIFY_DATA
),
83 ATA_CMD_IDENTIFY_DRIVE
,
91 // If ATA Identify command succeeds, then according to the received
93 // identify the device type ( ATA or not ).
94 // If ATA device, fill the information in IdeDev.
95 // If not ATA device, return IDE_DEVICE_ERROR
97 if (!EFI_ERROR (Status
)) {
99 IdeDev
->pIdData
= AtaIdentifyPointer
;
102 // Print ATA Module Name
104 PrintAtaModuleName (IdeDev
);
107 // bit 15 of pAtaIdentify->config is used to identify whether device is
108 // ATA device or ATAPI device.
109 // if 0, means ATA device; if 1, means ATAPI device.
111 if ((AtaIdentifyPointer
->AtaData
.config
& 0x8000) == 0x00) {
113 // Detect if support S.M.A.R.T. If yes, enable it as default
115 AtaSMARTSupport (IdeDev
);
118 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
120 Status
= AtaAtapi6Identify (IdeDev
);
121 if (!EFI_ERROR (Status
)) {
123 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
126 } else if (Status
== EFI_DEVICE_ERROR
) {
128 // Some disk with big capacity (>200GB) is slow when being identified
129 // and will return all zero for word83.
130 // We try twice at first. If it fails, we do a SoftRest and try again.
135 // Do a SoftRest before the third attempt.
137 AtaSoftReset (IdeDev
);
142 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
144 IdeDev
->Type
= IdeHardDisk
;
147 // Block Media Information:
148 // Media->LogicalPartition , Media->WriteCaching will be filled
149 // in the DiscoverIdeDevcie() function.
151 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
152 IdeDev
->BlkIo
.Media
->MediaId
= 1;
153 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
154 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
155 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
156 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
159 // Calculate device capacity
161 Capacity
= ((UINT32
)AtaIdentifyPointer
->AtaData
.user_addressable_sectors_hi
<< 16) |
162 AtaIdentifyPointer
->AtaData
.user_addressable_sectors_lo
;
163 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
172 gBS
->FreePool (AtaIdentifyPointer
);
174 // Make sure the pIdData will not be freed again.
176 IdeDev
->pIdData
= NULL
;
178 return EFI_DEVICE_ERROR
;
183 This function is called by ATAIdentify() to identity whether this disk
184 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
187 pointer pointing to IDE_BLK_IO_DEV data structure, used
188 to record all the information of the IDE device.
190 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one
191 and 48-bit addressing must be used
193 @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
194 the capacity is below 120G, 48bit addressing is not needed
196 @retval EFI_DEVICE_ERROR The identify data in IdeDev is incorrect
198 @retval EFI_INVALID_PARAMETER The identify data in IdeDev is NULL.
201 This function must be called after DEVICE_IDENTITY command has been
202 successfully returned
207 IN IDE_BLK_IO_DEV
*IdeDev
213 EFI_IDENTIFY_DATA
*Atapi6IdentifyStruct
;
215 if (IdeDev
->pIdData
== NULL
) {
216 return EFI_INVALID_PARAMETER
;
219 Atapi6IdentifyStruct
= IdeDev
->pIdData
;
221 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& (BIT15
| BIT14
)) != 0x4000) {
223 // Per ATA-6 spec, word83: bit15 is zero and bit14 is one
225 return EFI_DEVICE_ERROR
;
228 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& BIT10
) == 0) {
230 // The device dosn't support 48 bit addressing
232 return EFI_UNSUPPORTED
;
236 // 48 bit address feature set is supported, get maximum capacity
238 Capacity
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[0];
239 for (Index
= 1; Index
< 4; Index
++) {
241 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
243 TmpLba
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[Index
];
244 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
247 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
249 // Capacity exceeds 120GB. 48-bit addressing is really needed
251 IdeDev
->Type
= Ide48bitAddressingHardDisk
;
254 // Fill block media information:Media->LogicalPartition ,
255 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
257 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
258 IdeDev
->BlkIo
.Media
->MediaId
= 1;
259 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
260 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
261 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
262 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
263 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
268 return EFI_UNSUPPORTED
;
272 This function is called by ATAIdentify() or ATAPIIdentify()
273 to print device's module name.
276 pointer pointing to IDE_BLK_IO_DEV data structure, used
277 to record all the information of the IDE device.
282 IN IDE_BLK_IO_DEV
*IdeDev
285 if (IdeDev
->pIdData
== NULL
) {
289 SwapStringChars (IdeDev
->ModelName
, IdeDev
->pIdData
->AtaData
.ModelName
, 40);
290 IdeDev
->ModelName
[40] = 0x00;
294 This function is used to send out ATA commands conforms to the
295 PIO Data In Protocol.
298 pointer pointing to IDE_BLK_IO_DEV data structure, used
299 to record all the information of the IDE device.
302 buffer contained data transferred from device to host.
305 data size in byte unit of the buffer.
307 @param[in] AtaCommand
308 value of the Command Register
311 value of the Head/Device Register
313 @param[in] SectorCount
314 value of the Sector Count Register
316 @param[in] SectorNumber
317 value of the Sector Number Register
319 @param[in] CylinderLsb
320 value of the low byte of the Cylinder Register
322 @param[in] CylinderMsb
323 value of the high byte of the Cylinder Register
325 @retval EFI_SUCCESS send out the ATA command and device send required
328 @retval EFI_DEVICE_ERROR command sent failed.
333 IN IDE_BLK_IO_DEV
*IdeDev
,
338 IN UINT8 SectorCount
,
339 IN UINT8 SectorNumber
,
340 IN UINT8 CylinderLsb
,
349 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
350 if (EFI_ERROR (Status
)) {
351 return EFI_DEVICE_ERROR
;
355 // e0:1110,0000-- bit7 and bit5 are reserved bits.
356 // bit6 set means LBA mode
360 IdeDev
->IoPort
->Head
,
361 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
365 // All ATAPI device's ATA commands can be issued regardless of the
368 if (IdeDev
->Type
== IdeHardDisk
) {
370 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
371 if (EFI_ERROR (Status
)) {
372 return EFI_DEVICE_ERROR
;
376 // set all the command parameters
377 // Before write to all the following registers, BSY and DRQ must be 0.
379 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
380 if (EFI_ERROR (Status
)) {
381 return EFI_DEVICE_ERROR
;
384 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
385 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
388 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
389 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
390 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
391 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
394 // send command via Command Register
396 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
398 Buffer16
= (UINT16
*) Buffer
;
401 // According to PIO data in protocol, host can perform a series of reads to
402 // the data register after each time device set DRQ ready;
403 // The data size of "a series of read" is command specific.
404 // For most ATA command, data size received from device will not exceed
405 // 1 sector, hence the data size for "a series of read" can be the whole data
406 // size of one command request.
407 // For ATA command such as Read Sector command, the data size of one ATA
408 // command request is often larger than 1 sector, according to the
409 // Read Sector command, the data size of "a series of read" is exactly 1
411 // Here for simplification reason, we specify the data size for
412 // "a series of read" to 1 sector (256 words) if data size of one ATA command
413 // request is larger than 256 words.
418 // used to record bytes of currently transfered data
422 while (WordCount
< ByteCount
/ 2) {
424 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
426 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
427 if (EFI_ERROR (Status
)) {
428 return EFI_DEVICE_ERROR
;
431 Status
= CheckErrorStatus (IdeDev
);
432 if (EFI_ERROR (Status
)) {
433 return EFI_DEVICE_ERROR
;
437 // Get the byte count for one series of read
439 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
440 Increment
= ByteCount
/ 2 - WordCount
;
443 IDEReadPortWMultiple (
445 IdeDev
->IoPort
->Data
,
450 WordCount
+= Increment
;
451 Buffer16
+= Increment
;
455 DRQClear (IdeDev
, ATATIMEOUT
);
457 return CheckErrorStatus (IdeDev
);
461 This function is used to send out ATA commands conforms to the
462 PIO Data Out Protocol.
465 pointer pointing to IDE_BLK_IO_DEV data structure, used
466 to record all the information of the IDE device.
468 @param *Buffer buffer contained data transferred from host to device.
469 @param ByteCount data size in byte unit of the buffer.
470 @param AtaCommand value of the Command Register
471 @param Head value of the Head/Device Register
472 @param SectorCount value of the Sector Count Register
473 @param SectorNumber value of the Sector Number Register
474 @param CylinderLsb value of the low byte of the Cylinder Register
475 @param CylinderMsb value of the high byte of the Cylinder Register
477 @retval EFI_SUCCESS send out the ATA command and device received required
480 @retval EFI_DEVICE_ERROR command sent failed.
485 IN IDE_BLK_IO_DEV
*IdeDev
,
490 IN UINT8 SectorCount
,
491 IN UINT8 SectorNumber
,
492 IN UINT8 CylinderLsb
,
501 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
502 if (EFI_ERROR (Status
)) {
503 return EFI_DEVICE_ERROR
;
507 // select device via Head/Device register.
508 // Before write Head/Device register, BSY and DRQ must be 0.
510 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
511 if (EFI_ERROR (Status
)) {
512 return EFI_DEVICE_ERROR
;
516 // e0:1110,0000-- bit7 and bit5 are reserved bits.
517 // bit6 set means LBA mode
521 IdeDev
->IoPort
->Head
,
522 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
525 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
526 if (EFI_ERROR (Status
)) {
527 return EFI_DEVICE_ERROR
;
531 // set all the command parameters
532 // Before write to all the following registers, BSY and DRQ must be 0.
534 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
535 if (EFI_ERROR (Status
)) {
536 return EFI_DEVICE_ERROR
;
539 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
540 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
541 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
542 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
545 // send command via Command Register
547 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
549 Buffer16
= (UINT16
*) Buffer
;
552 // According to PIO data out protocol, host can perform a series of
553 // writes to the data register after each time device set DRQ ready;
554 // The data size of "a series of read" is command specific.
555 // For most ATA command, data size written to device will not exceed 1 sector,
556 // hence the data size for "a series of write" can be the data size of one
558 // For ATA command such as Write Sector command, the data size of one
559 // ATA command request is often larger than 1 sector, according to the
560 // Write Sector command, the data size of "a series of read" is exactly
562 // Here for simplification reason, we specify the data size for
563 // "a series of write" to 1 sector (256 words) if data size of one ATA command
564 // request is larger than 256 words.
569 while (WordCount
< ByteCount
/ 2) {
572 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
573 // data transfer can be performed only when DRQ is ready.
575 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
576 if (EFI_ERROR (Status
)) {
577 return EFI_DEVICE_ERROR
;
580 Status
= CheckErrorStatus (IdeDev
);
581 if (EFI_ERROR (Status
)) {
582 return EFI_DEVICE_ERROR
;
586 // Check the remaining byte count is less than 512 bytes
588 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
589 Increment
= ByteCount
/ 2 - WordCount
;
592 // perform a series of write without check DRQ ready
595 IDEWritePortWMultiple (
597 IdeDev
->IoPort
->Data
,
601 WordCount
+= Increment
;
602 Buffer16
+= Increment
;
606 DRQClear (IdeDev
, ATATIMEOUT
);
608 return CheckErrorStatus (IdeDev
);
612 This function is used to analyze the Status Register and print out
613 some debug information and if there is ERR bit set in the Status
614 Register, the Error Register's value is also be parsed and print out.
617 pointer pointing to IDE_BLK_IO_DEV data structure, used
618 to record all the information of the IDE device.
620 @retval EFI_SUCCESS No err information in the Status Register.
621 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
626 IN IDE_BLK_IO_DEV
*IdeDev
629 UINT8 StatusRegister
;
632 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
636 if ((StatusRegister
& ATA_STSREG_DWF
) != 0) {
639 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
644 if ((StatusRegister
& ATA_STSREG_CORR
) != 0) {
647 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
652 if ((StatusRegister
& ATA_STSREG_ERR
) != 0) {
653 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
655 if ((ErrorRegister
& ATA_ERRREG_BBK
) != 0) {
658 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
663 if ((ErrorRegister
& ATA_ERRREG_UNC
) != 0) {
666 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
671 if ((ErrorRegister
& ATA_ERRREG_MC
) != 0) {
674 "CheckErrorStatus()-- %02x : Error : Media Change\n",
679 if ((ErrorRegister
& ATA_ERRREG_ABRT
) != 0) {
682 "CheckErrorStatus()-- %02x : Error : Abort\n",
687 if ((ErrorRegister
& ATA_ERRREG_TK0NF
) != 0) {
690 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
695 if ((ErrorRegister
& ATA_ERRREG_AMNF
) != 0) {
698 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
706 if ((StatusRegister
& (ATA_STSREG_ERR
| ATA_STSREG_DWF
| ATA_STSREG_CORR
)) == 0) {
710 return EFI_DEVICE_ERROR
;
715 This function is called by the AtaBlkIoReadBlocks() to perform
716 reading from media in block unit.
719 pointer pointing to IDE_BLK_IO_DEV data structure, used
720 to record all the information of the IDE device.
722 @param[in] *DataBuffer
723 A pointer to the destination buffer for the data.
726 The starting logical block address to read from
729 @param[in] NumberOfBlocks
730 The number of transfer data blocks.
732 @return return status is fully dependent on the return status
733 of AtaPioDataIn() function.
738 IN IDE_BLK_IO_DEV
*IdeDev
,
741 IN UINTN NumberOfBlocks
745 UINTN BlocksRemaining
;
760 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
762 AtaCommand
= ATA_CMD_READ_SECTORS
;
765 BlocksRemaining
= NumberOfBlocks
;
767 Lba32
= (UINT32
) Lba
;
769 Status
= EFI_SUCCESS
;
771 while (BlocksRemaining
> 0) {
774 // in ATA-3 spec, LBA is in 28 bit width
776 Lba0
= (UINT8
) Lba32
;
777 Lba1
= (UINT8
) (Lba32
>> 8);
778 Lba2
= (UINT8
) (Lba32
>> 16);
780 // low 4 bit of Lba3 stands for LBA bit24~bit27.
782 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
784 if (BlocksRemaining
>= 0x100) {
787 // SectorCount8 is sent to Sector Count register, 0x00 means 256
788 // sectors to be read
792 // SectorCount is used to record the number of sectors to be read
797 SectorCount8
= (UINT8
) BlocksRemaining
;
798 SectorCount
= (UINT16
) BlocksRemaining
;
802 // ByteCount is the number of bytes that will be read
804 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
807 // call AtaPioDataIn() to send Read Sector Command and receive data read
809 Status
= AtaPioDataIn (
820 if (EFI_ERROR (Status
)) {
824 Lba32
+= SectorCount
;
825 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
826 BlocksRemaining
-= SectorCount
;
833 This function is called by the AtaBlkIoWriteBlocks() to perform
834 writing onto media in block unit.
837 pointer pointing to IDE_BLK_IO_DEV data structure,used
838 to record all the information of the IDE device.
840 @param[in] *BufferData
841 A pointer to the source buffer for the data.
844 The starting logical block address to write onto
847 @param[in] NumberOfBlocks
848 The number of transfer data blocks.
850 @return return status is fully dependent on the return status
851 of AtaPioDataOut() function.
856 IN IDE_BLK_IO_DEV
*IdeDev
,
859 IN UINTN NumberOfBlocks
863 UINTN BlocksRemaining
;
878 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
880 AtaCommand
= ATA_CMD_WRITE_SECTORS
;
882 BlocksRemaining
= NumberOfBlocks
;
884 Lba32
= (UINT32
) Lba
;
886 Status
= EFI_SUCCESS
;
888 while (BlocksRemaining
> 0) {
890 Lba0
= (UINT8
) Lba32
;
891 Lba1
= (UINT8
) (Lba32
>> 8);
892 Lba2
= (UINT8
) (Lba32
>> 16);
893 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
895 if (BlocksRemaining
>= 0x100) {
898 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
903 // SectorCount is used to record the number of sectors to be written
908 SectorCount8
= (UINT8
) BlocksRemaining
;
909 SectorCount
= (UINT16
) BlocksRemaining
;
912 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
914 Status
= AtaPioDataOut (
925 if (EFI_ERROR (Status
)) {
929 Lba32
+= SectorCount
;
930 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
931 BlocksRemaining
-= SectorCount
;
938 This function is used to implement the Soft Reset on the specified
939 device. But, the ATA Soft Reset mechanism is so strong a reset method
940 that it will force resetting on both devices connected to the
943 It is called by IdeBlkIoReset(), a interface function of Block
946 This function can also be used by the ATAPI device to perform reset when
947 ATAPI Reset command is failed.
950 pointer pointing to IDE_BLK_IO_DEV data structure, used
951 to record all the information of the IDE device.
953 @retval EFI_SUCCESS Soft reset completes successfully.
954 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
957 The registers initial values after ATA soft reset are different
958 to the ATA device and ATAPI device.
963 IN IDE_BLK_IO_DEV
*IdeDev
971 // set SRST bit to initiate soft reset
973 DeviceControl
|= ATA_CTLREG_SRST
;
978 DeviceControl
|= BIT1
;
980 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
983 // SRST should assert for at least 5 us, we use 10 us for
984 // better compatibility
989 // Enable interrupt to support UDMA, and clear SRST bit
992 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
995 // Wait for at least 2 ms to check BSY status, we use 10 ms
996 // for better compatibility
1000 // slave device needs at most 31s to clear BSY
1002 if (WaitForBSYClear (IdeDev
, 31000) == EFI_TIMEOUT
) {
1003 return EFI_DEVICE_ERROR
;
1010 This function is the ATA implementation for ReadBlocks in the
1011 Block I/O Protocol interface.
1013 @param[in] *IdeBlkIoDevice
1014 Indicates the calling context.
1017 The media id that the read request is for.
1020 The starting logical block address to read from
1023 @param[in] BufferSize
1024 The size of the Buffer in bytes. This must be a
1025 multiple of the intrinsic block size of the device.
1028 A pointer to the destination buffer for the data.
1029 The caller is responsible for either having implicit
1030 or explicit ownership of the memory that data is read into.
1032 @retval EFI_SUCCESS Read Blocks successfully.
1033 @retval EFI_DEVICE_ERROR Read Blocks failed.
1034 @retval EFI_NO_MEDIA There is no media in the device.
1035 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1037 @retval EFI_BAD_BUFFER_SIZE
1038 The BufferSize parameter is not a multiple of the
1039 intrinsic block size of the device.
1041 @retval EFI_INVALID_PARAMETER
1042 The read request contains LBAs that are not valid,
1043 or the data buffer is not valid.
1046 If Read Block error because of device error, this function will call
1047 AtaSoftReset() function to reset device.
1051 AtaBlkIoReadBlocks (
1052 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1055 IN UINTN BufferSize
,
1059 EFI_BLOCK_IO_MEDIA
*Media
;
1061 UINTN NumberOfBlocks
;
1064 if (Buffer
== NULL
) {
1065 return EFI_INVALID_PARAMETER
;
1068 if (BufferSize
== 0) {
1072 Status
= EFI_SUCCESS
;
1075 // Get the intrinsic block size
1077 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1078 BlockSize
= Media
->BlockSize
;
1080 NumberOfBlocks
= BufferSize
/ BlockSize
;
1082 if (MediaId
!= Media
->MediaId
) {
1083 return EFI_MEDIA_CHANGED
;
1086 if (BufferSize
% BlockSize
!= 0) {
1087 return EFI_BAD_BUFFER_SIZE
;
1090 if (!(Media
->MediaPresent
)) {
1091 return EFI_NO_MEDIA
;
1094 if (LBA
> Media
->LastBlock
) {
1095 return EFI_INVALID_PARAMETER
;
1098 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1099 return EFI_INVALID_PARAMETER
;
1102 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1103 return EFI_INVALID_PARAMETER
;
1106 Status
= EFI_SUCCESS
;
1107 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1109 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1111 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1112 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1114 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1118 // For ATA-3 compatible device, use ATA-3 read block mechanism
1120 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1121 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1123 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1127 if (EFI_ERROR (Status
)) {
1128 AtaSoftReset (IdeBlkIoDevice
);
1129 return EFI_DEVICE_ERROR
;
1137 This function is the ATA implementation for WriteBlocks in the
1138 Block I/O Protocol interface.
1140 @param[in] *IdeBlkIoDevice
1141 Indicates the calling context.
1144 The media id that the write request is for.
1147 The starting logical block address to write onto
1150 @param[in] BufferSize
1151 The size of the Buffer in bytes. This must be a
1152 multiple of the intrinsic block size of the device.
1155 A pointer to the source buffer for the data.
1156 The caller is responsible for either having implicit
1157 or explicit ownership of the memory that data is
1160 @retval EFI_SUCCESS Write Blocks successfully.
1161 @retval EFI_DEVICE_ERROR Write Blocks failed.
1162 @retval EFI_NO_MEDIA There is no media in the device.
1163 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1165 @retval EFI_BAD_BUFFER_SIZE
1166 The BufferSize parameter is not a multiple of the
1167 intrinsic block size of the device.
1169 @retval EFI_INVALID_PARAMETER
1170 The write request contains LBAs that are not valid,
1171 or the data buffer is not valid.
1174 If Write Block error because of device error, this function will call
1175 AtaSoftReset() function to reset device.
1179 AtaBlkIoWriteBlocks (
1180 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1183 IN UINTN BufferSize
,
1188 EFI_BLOCK_IO_MEDIA
*Media
;
1190 UINTN NumberOfBlocks
;
1193 if (Buffer
== NULL
) {
1194 return EFI_INVALID_PARAMETER
;
1197 if (BufferSize
== 0) {
1201 Status
= EFI_SUCCESS
;
1204 // Get the intrinsic block size
1206 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1207 BlockSize
= Media
->BlockSize
;
1208 NumberOfBlocks
= BufferSize
/ BlockSize
;
1210 if (MediaId
!= Media
->MediaId
) {
1211 return EFI_MEDIA_CHANGED
;
1214 if (BufferSize
% BlockSize
!= 0) {
1215 return EFI_BAD_BUFFER_SIZE
;
1218 if (LBA
> Media
->LastBlock
) {
1219 return EFI_INVALID_PARAMETER
;
1222 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1223 return EFI_INVALID_PARAMETER
;
1226 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1227 return EFI_INVALID_PARAMETER
;
1230 Status
= EFI_SUCCESS
;
1231 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1233 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1235 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1236 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1238 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1242 // For ATA-3 compatible device, use ATA-3 write block mechanism
1244 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1245 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1247 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1251 if (EFI_ERROR (Status
)) {
1252 AtaSoftReset (IdeBlkIoDevice
);
1253 return EFI_DEVICE_ERROR
;
1260 This function is called by the AtaBlkIoReadBlocks() to perform
1261 reading from media in block unit. The function has been enhanced to
1262 support >120GB access and transfer at most 65536 blocks per command
1265 pointer pointing to IDE_BLK_IO_DEV data structure, used
1266 to record all the information of the IDE device.
1268 @param[in] *DataBuffer A pointer to the destination buffer for the data.
1269 @param[in] StartLba The starting logical block address to read from
1270 on the device media.
1271 @param[in] NumberOfBlocks The number of transfer data blocks.
1273 @return return status is fully dependent on the return status
1274 of AtaPioDataInExt() function.
1279 IN IDE_BLK_IO_DEV
*IdeDev
,
1280 IN VOID
*DataBuffer
,
1281 IN EFI_LBA StartLba
,
1282 IN UINTN NumberOfBlocks
1286 UINTN BlocksRemaining
;
1294 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1296 AtaCommand
= ATA_CMD_READ_SECTORS_EXT
;
1297 Buffer
= DataBuffer
;
1298 BlocksRemaining
= NumberOfBlocks
;
1300 Status
= EFI_SUCCESS
;
1302 while (BlocksRemaining
> 0) {
1304 if (BlocksRemaining
>= 0x10000) {
1306 // SectorCount is used to record the number of sectors to be read
1307 // Max 65536 sectors can be transfered at a time.
1309 SectorCount
= 0xffff;
1311 SectorCount
= (UINT16
) BlocksRemaining
;
1315 // ByteCount is the number of bytes that will be read
1317 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1320 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1322 Status
= AtaPioDataInExt (
1330 if (EFI_ERROR (Status
)) {
1334 Lba64
+= SectorCount
;
1335 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1336 BlocksRemaining
-= SectorCount
;
1343 This function is called by the AtaBlkIoWriteBlocks() to perform
1344 writing onto media in block unit. The function has been enhanced to
1345 support >120GB access and transfer at most 65536 blocks per command
1348 pointer pointing to IDE_BLK_IO_DEV data structure,used
1349 to record all the information of the IDE device.
1351 @param[in] *DataBuffer
1352 A pointer to the source buffer for the data.
1355 The starting logical block address to write onto
1358 @param[in] NumberOfBlocks
1359 The number of transfer data blocks.
1361 @return status is fully dependent on the return status
1362 of AtaPioDataOutExt() function.
1366 AtaWriteSectorsExt (
1367 IN IDE_BLK_IO_DEV
*IdeDev
,
1368 IN VOID
*DataBuffer
,
1369 IN EFI_LBA StartLba
,
1370 IN UINTN NumberOfBlocks
1375 UINTN BlocksRemaining
;
1382 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1384 AtaCommand
= ATA_CMD_WRITE_SECTORS_EXT
;
1386 Buffer
= DataBuffer
;
1387 BlocksRemaining
= NumberOfBlocks
;
1389 Status
= EFI_SUCCESS
;
1391 while (BlocksRemaining
> 0) {
1393 if (BlocksRemaining
>= 0x10000) {
1395 // SectorCount is used to record the number of sectors to be written.
1396 // Max 65536 sectors can be transfered at a time.
1398 SectorCount
= 0xffff;
1400 SectorCount
= (UINT16
) BlocksRemaining
;
1404 // ByteCount is the number of bytes that will be written
1406 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1409 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1411 Status
= AtaPioDataOutExt (
1419 if (EFI_ERROR (Status
)) {
1423 Lba64
+= SectorCount
;
1424 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1425 BlocksRemaining
-= SectorCount
;
1432 This function is used to send out ATA commands conforms to the
1433 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1435 Comparing with ATA-3 data in protocol, we have two differents here:<BR>
1436 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1437 wait will frequently fail... cause writing function return error)
1439 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1440 slow down writing performance by 100 times!)
1442 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1443 to record all the information of the IDE device.
1445 @param[in, out] *Buffer buffer contained data transferred from device to host.
1446 @param[in] ByteCount data size in byte unit of the buffer.
1447 @param[in] AtaCommand value of the Command Register
1448 @param[in] StartLba the start LBA of this transaction
1449 @param[in] SectorCount the count of sectors to be transfered
1451 @retval EFI_SUCCESS send out the ATA command and device send required
1454 @retval EFI_DEVICE_ERROR command sent failed.
1459 IN IDE_BLK_IO_DEV
*IdeDev
,
1460 IN OUT VOID
*Buffer
,
1461 IN UINT32 ByteCount
,
1462 IN UINT8 AtaCommand
,
1463 IN EFI_LBA StartLba
,
1464 IN UINT16 SectorCount
1477 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1478 if (EFI_ERROR (Status
)) {
1479 return EFI_DEVICE_ERROR
;
1483 // Select device, set bit6 as 1 to indicate LBA mode is used
1485 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1489 IdeDev
->IoPort
->Head
,
1494 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1496 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1497 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1499 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1500 if (EFI_ERROR (Status
)) {
1501 return EFI_DEVICE_ERROR
;
1506 // Fill feature register if needed
1508 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
1509 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1513 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1515 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1516 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1518 SectorCount8
= (UINT8
) SectorCount
;
1519 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1522 // Fill the start LBA registers, which are also two-byte FIFO
1524 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1525 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1526 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1527 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1528 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1529 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1531 LbaLow
= (UINT8
) StartLba
;
1532 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1533 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1534 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1535 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1536 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1539 // Send command via Command Register, invoking the processing of this command
1541 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1543 Buffer16
= (UINT16
*) Buffer
;
1546 // According to PIO data in protocol, host can perform a series of reads to
1547 // the data register after each time device set DRQ ready;
1556 // used to record bytes of currently transfered data
1560 while (WordCount
< ByteCount
/ 2) {
1562 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1564 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1565 if (EFI_ERROR (Status
)) {
1566 return EFI_DEVICE_ERROR
;
1569 Status
= CheckErrorStatus (IdeDev
);
1570 if (EFI_ERROR (Status
)) {
1571 return EFI_DEVICE_ERROR
;
1575 // Get the byte count for one series of read
1577 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1578 Increment
= ByteCount
/ 2 - WordCount
;
1581 IDEReadPortWMultiple (
1583 IdeDev
->IoPort
->Data
,
1588 WordCount
+= Increment
;
1589 Buffer16
+= Increment
;
1593 return CheckErrorStatus (IdeDev
);
1597 This function is used to send out ATA commands conforms to the
1598 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1600 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
1601 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1602 wait will frequently fail... cause writing function return error)
1604 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1605 slow down writing performance by 100 times!)
1608 pointer pointing to IDE_BLK_IO_DEV data structure, used
1609 to record all the information of the IDE device.
1611 @param[in] *Buffer buffer contained data transferred from host to device.
1612 @param[in] ByteCount data size in byte unit of the buffer.
1613 @param[in] AtaCommand value of the Command Register
1614 @param[in] StartLba the start LBA of this transaction
1615 @param[in] SectorCount the count of sectors to be transfered
1617 @retval EFI_SUCCESS send out the ATA command and device receive required
1620 @retval EFI_DEVICE_ERROR command sent failed.
1625 IN IDE_BLK_IO_DEV
*IdeDev
,
1627 IN UINT32 ByteCount
,
1628 IN UINT8 AtaCommand
,
1629 IN EFI_LBA StartLba
,
1630 IN UINT16 SectorCount
1643 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1644 if (EFI_ERROR (Status
)) {
1645 return EFI_DEVICE_ERROR
;
1649 // Select device. Set bit6 as 1 to indicate LBA mode is used
1651 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1655 IdeDev
->IoPort
->Head
,
1660 // Wait for DRDY singnal asserting.
1662 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1663 if (EFI_ERROR (Status
)) {
1664 return EFI_DEVICE_ERROR
;
1668 // Fill feature register if needed
1670 if (AtaCommand
== ATA_CMD_SET_FEATURES
) {
1671 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1675 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1677 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1678 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1680 SectorCount8
= (UINT8
) SectorCount
;
1681 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1684 // Fill the start LBA registers, which are also two-byte FIFO
1686 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1687 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1688 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1689 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1690 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1691 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1693 LbaLow
= (UINT8
) StartLba
;
1694 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1695 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1696 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1697 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1698 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1701 // Send command via Command Register, invoking the processing of this command
1703 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1705 Buffer16
= (UINT16
*) Buffer
;
1708 // According to PIO Data Out protocol, host can perform a series of writes to
1709 // the data register after each time device set DRQ ready;
1714 // used to record bytes of currently transfered data
1718 while (WordCount
< ByteCount
/ 2) {
1720 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1722 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1723 if (EFI_ERROR (Status
)) {
1724 return EFI_DEVICE_ERROR
;
1727 Status
= CheckErrorStatus (IdeDev
);
1728 if (EFI_ERROR (Status
)) {
1729 return EFI_DEVICE_ERROR
;
1733 // Write data into device by one series of writing to data register
1735 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1736 Increment
= ByteCount
/ 2 - WordCount
;
1739 IDEWritePortWMultiple (
1741 IdeDev
->IoPort
->Data
,
1746 WordCount
+= Increment
;
1747 Buffer16
+= Increment
;
1754 return CheckErrorStatus (IdeDev
);
1759 Enable SMART of the disk if supported
1762 pointer pointing to IDE_BLK_IO_DEV data structure,used
1763 to record all the information of the IDE device.
1768 IN IDE_BLK_IO_DEV
*IdeDev
1772 BOOLEAN SMARTSupported
;
1774 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
1780 // Detect if the device supports S.M.A.R.T.
1782 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
1784 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
1788 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
1790 // S.M.A.R.T is not supported by the device
1792 SMARTSupported
= FALSE
;
1794 SMARTSupported
= TRUE
;
1798 if (!SMARTSupported
) {
1800 // Report nonsupport status code
1802 REPORT_STATUS_CODE (
1803 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1804 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
1808 // Enable this feature
1810 REPORT_STATUS_CODE (
1812 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
1815 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1816 Status
= AtaNonDataCommandIn (
1820 ATA_SMART_ENABLE_OPERATION
,
1827 // Detect if this feature is enabled
1829 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
1830 if (TmpAtaIdentifyPointer
== NULL
) {
1834 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
1835 Status
= AtaPioDataIn (
1837 (VOID
*) TmpAtaIdentifyPointer
,
1838 sizeof (EFI_IDENTIFY_DATA
),
1839 ATA_CMD_IDENTIFY_DRIVE
,
1846 if (EFI_ERROR (Status
)) {
1847 gBS
->FreePool (TmpAtaIdentifyPointer
);
1852 // Check if the feature is enabled
1854 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
1858 AtaNonDataCommandIn (
1862 ATA_SMART_RETURN_STATUS
,
1868 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
1869 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
1871 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
1873 // The threshold exceeded condition is not detected by the device
1875 REPORT_STATUS_CODE (
1877 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
1880 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
1882 // The threshold exceeded condition is detected by the device
1884 REPORT_STATUS_CODE (
1886 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
1892 // Report disabled status code
1894 REPORT_STATUS_CODE (
1895 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1896 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
1900 gBS
->FreePool (TmpAtaIdentifyPointer
);
1907 Enable Long Physical Sector Feature for ATA device.
1909 @param IdeDev The IDE device data
1911 @retval EFI_SUCCESS The ATA device supports Long Physical Sector feature
1912 and corresponding fields in BlockIo structure is updated.
1913 @retval EFI_UNSUPPORTED The device is not ATA device or Long Physical Sector
1914 feature is not supported.
1917 AtaEnableLongPhysicalSector (
1918 IN IDE_BLK_IO_DEV
*IdeDev
1921 EFI_ATA_IDENTIFY_DATA
*AtaIdentifyData
;
1922 UINT16 PhyLogicSectorSupport
;
1924 ASSERT (IdeDev
->pIdData
!= NULL
);
1926 // Only valid for ATA device
1928 AtaIdentifyData
= (EFI_ATA_IDENTIFY_DATA
*) &IdeDev
->pIdData
->AtaData
;
1929 if (AtaIdentifyData
->config
& 0x8000) {
1930 return EFI_UNSUPPORTED
;
1932 PhyLogicSectorSupport
= AtaIdentifyData
->phy_logic_sector_support
;
1934 // Check whether Long Physical Sector Feature is supported
1936 if ((PhyLogicSectorSupport
& 0xc000) == 0x4000) {
1937 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
= 1;
1938 IdeDev
->BlkIo
.Media
->LowestAlignedLba
= 0;
1940 // Check whether one physical block contains multiple physical blocks
1942 if (PhyLogicSectorSupport
& 0x2000) {
1943 IdeDev
->BlkIo
.Media
->LogicalBlocksPerPhysicalBlock
=
1944 (UINT32
) (1 << (PhyLogicSectorSupport
& 0x000f));
1946 // Check lowest alignment of logical blocks within physical block
1948 if ((AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0xc000) == 0x4000) {
1949 IdeDev
->BlkIo
.Media
->LowestAlignedLba
=
1950 (EFI_LBA
) (AtaIdentifyData
->alignment_logic_in_phy_blocks
& 0x3fff);
1954 // Check logical block size
1956 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
1957 if (PhyLogicSectorSupport
& 0x1000) {
1958 IdeDev
->BlkIo
.Media
->BlockSize
= (UINT32
) (
1959 ((AtaIdentifyData
->logic_sector_size_hi
<< 16) |
1960 AtaIdentifyData
->logic_sector_size_lo
) * sizeof (UINT16
)
1965 return EFI_UNSUPPORTED
;
1971 Send ATA Ext command into device with NON_DATA protocol
1973 @param IdeDev Standard IDE device private data structure
1974 @param AtaCommand The ATA command to be sent
1975 @param Device The value in Device register
1976 @param Feature The value in Feature register
1977 @param SectorCount The value in SectorCount register
1978 @param LbaAddress The LBA address in 48-bit mode
1980 @retval EFI_SUCCESS Reading succeed
1981 @retval EFI_DEVICE_ERROR Error executing commands on this device.
1985 AtaCommandIssueExt (
1986 IN IDE_BLK_IO_DEV
*IdeDev
,
1987 IN UINT8 AtaCommand
,
1990 IN UINT16 SectorCount
,
1991 IN EFI_LBA LbaAddress
2001 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2002 if (EFI_ERROR (Status
)) {
2003 return EFI_DEVICE_ERROR
;
2007 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2011 IdeDev
->IoPort
->Head
,
2012 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2016 // ATA commands for ATA device must be issued when DRDY is set
2018 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2019 if (EFI_ERROR (Status
)) {
2020 return EFI_DEVICE_ERROR
;
2024 // Pass parameter into device register block
2026 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2029 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2031 Feature8
= (UINT8
) (Feature
>> 8);
2032 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2034 Feature8
= (UINT8
) Feature
;
2035 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2038 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2040 SectorCount8
= (UINT8
) (SectorCount
>> 8);
2041 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2043 SectorCount8
= (UINT8
) SectorCount
;
2044 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2047 // Fill the start LBA registers, which are also two-byte FIFO
2049 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2050 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2051 LbaLow
= (UINT8
) LbaAddress
;
2052 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
2054 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
2055 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2056 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2057 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
2059 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
2060 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2061 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2062 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
2065 // Work around for Segate 160G disk writing
2070 // Send command via Command Register
2072 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2075 // Stall at least 400ns
2083 Send ATA Ext command into device with NON_DATA protocol
2085 @param IdeDev Standard IDE device private data structure
2086 @param AtaCommand The ATA command to be sent
2087 @param Device The value in Device register
2088 @param Feature The value in Feature register
2089 @param SectorCount The value in SectorCount register
2090 @param LbaAddress The LBA address in 48-bit mode
2092 @retval EFI_SUCCESS Reading succeed
2093 @retval EFI_DEVICE_ERROR Error executing commands on this device.
2098 IN IDE_BLK_IO_DEV
*IdeDev
,
2099 IN UINT8 AtaCommand
,
2102 IN UINT16 SectorCount
,
2103 IN EFI_LBA LbaAddress
2114 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2115 if (EFI_ERROR (Status
)) {
2116 return EFI_DEVICE_ERROR
;
2120 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2124 IdeDev
->IoPort
->Head
,
2125 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2129 // ATA commands for ATA device must be issued when DRDY is set
2131 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2132 if (EFI_ERROR (Status
)) {
2133 return EFI_DEVICE_ERROR
;
2136 Lba0
= (UINT8
) LbaAddress
;
2137 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2138 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2139 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2140 Device
= (UINT8
) (Device
| Lba3
);
2143 // Pass parameter into device register block
2145 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2148 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2150 Feature8
= (UINT8
) Feature
;
2151 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2154 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2156 SectorCount8
= (UINT8
) SectorCount
;
2157 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2160 // Fill the start LBA registers, which are also two-byte FIFO
2163 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
2164 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
2165 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
2168 // Send command via Command Register
2170 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2173 // Stall at least 400ns
2181 This function is called by the AtaBlkIoReadBlocks() to perform
2182 reading from media in block unit. The function has been enhanced to
2183 support >120GB access and transfer at most 65536 blocks per command
2185 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2186 to record all the information of the IDE device.
2188 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2190 @param[in] StartLba The starting logical block address to read from
2191 on the device media.
2193 @param[in] NumberOfBlocks The number of transfer data blocks.
2195 @return The device status of UDMA operation. If the operation is
2196 successful, return EFI_SUCCESS.
2198 TODO: EFI_UNSUPPORTED - add return value to function comment
2199 TODO: EFI_DEVICE_ERROR - add return value to function comment
2200 TODO: EFI_DEVICE_ERROR - add return value to function comment
2201 TODO: EFI_DEVICE_ERROR - add return value to function comment
2205 IN IDE_BLK_IO_DEV
*IdeDev
,
2206 IN VOID
*DataBuffer
,
2207 IN EFI_LBA StartLba
,
2208 IN UINTN NumberOfBlocks
2211 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadExtOp
);
2215 This function is called by the AtaBlkIoReadBlocks() to perform
2216 reading from media in block unit. The function has been enhanced to
2217 support >120GB access and transfer at most 65536 blocks per command
2220 pointer pointing to IDE_BLK_IO_DEV data structure, used
2221 to record all the information of the IDE device.
2223 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2224 @param[in] StartLba The starting logical block address to read from
2225 on the device media.
2226 @param[in] NumberOfBlocks The number of transfer data blocks.
2228 @return The device status of UDMA operation. If the operation is
2229 successful, return EFI_SUCCESS.
2231 TODO: EFI_UNSUPPORTED - add return value to function comment
2232 TODO: EFI_DEVICE_ERROR - add return value to function comment
2233 TODO: EFI_DEVICE_ERROR - add return value to function comment
2234 TODO: EFI_DEVICE_ERROR - add return value to function comment
2238 IN IDE_BLK_IO_DEV
*IdeDev
,
2239 IN VOID
*DataBuffer
,
2240 IN EFI_LBA StartLba
,
2241 IN UINTN NumberOfBlocks
2244 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadOp
);
2248 This function is called by the AtaBlkIoWriteBlocks() to perform
2249 writing to media in block unit. The function has been enhanced to
2250 support >120GB access and transfer at most 65536 blocks per command
2252 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2253 to record all the information of the IDE device.
2255 @param[in] *DataBuffer A pointer to the source buffer for the data.
2257 @param[in] StartLba The starting logical block address to write to
2258 on the device media.
2260 @param[in] NumberOfBlocks The number of transfer data blocks.
2262 @return The device status of UDMA operation. If the operation is
2263 successful, return EFI_SUCCESS.
2265 TODO: EFI_UNSUPPORTED - add return value to function comment
2266 TODO: EFI_DEVICE_ERROR - add return value to function comment
2267 TODO: EFI_DEVICE_ERROR - add return value to function comment
2271 IN IDE_BLK_IO_DEV
*IdeDev
,
2272 IN VOID
*DataBuffer
,
2273 IN EFI_LBA StartLba
,
2274 IN UINTN NumberOfBlocks
2277 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteExtOp
);
2281 This function is called by the AtaBlkIoWriteBlocks() to perform
2282 writing to media in block unit. The function has been enhanced to
2283 support >120GB access and transfer at most 65536 blocks per command
2286 pointer pointing to IDE_BLK_IO_DEV data structure, used
2287 to record all the information of the IDE device.
2289 @param[in] *DataBuffer
2290 A pointer to the source buffer for the data.
2293 The starting logical block address to write to
2294 on the device media.
2296 @param[in] NumberOfBlocks
2297 The number of transfer data blocks.
2299 @return The device status of UDMA operation. If the operation is
2300 successful, return EFI_SUCCESS.
2302 TODO: EFI_UNSUPPORTED - add return value to function comment
2303 TODO: EFI_DEVICE_ERROR - add return value to function comment
2304 TODO: EFI_DEVICE_ERROR - add return value to function comment
2308 IN IDE_BLK_IO_DEV
*IdeDev
,
2309 IN VOID
*DataBuffer
,
2310 IN EFI_LBA StartLba
,
2311 IN UINTN NumberOfBlocks
2314 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteOp
);
2318 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
2321 pointer pointing to IDE_BLK_IO_DEV data structure, used
2322 to record all the information of the IDE device.
2324 @param[in] *DataBuffer
2325 A pointer to the source buffer for the data.
2328 The starting logical block address to write to
2329 on the device media.
2331 @param[in] NumberOfBlocks
2332 The number of transfer data blocks.
2335 The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
2336 AtaUdmaWriteOp, AtaUdmaWriteExOp
2338 @return The device status of UDMA operation. If the operation is
2339 successful, return EFI_SUCCESS.
2344 IN IDE_BLK_IO_DEV
*IdeDev
,
2345 IN VOID
*DataBuffer
,
2346 IN EFI_LBA StartLba
,
2347 IN UINTN NumberOfBlocks
,
2348 IN ATA_UDMA_OPERATION UdmaOp
2351 IDE_DMA_PRD
*PrdAddr
;
2352 IDE_DMA_PRD
*UsedPrdAddr
;
2353 IDE_DMA_PRD
*TempPrdAddr
;
2354 UINT8 RegisterValue
;
2356 UINT64 IoPortForBmic
;
2357 UINT64 IoPortForBmis
;
2358 UINT64 IoPortForBmid
;
2362 UINTN ByteAvailable
;
2364 UINTN RemainBlockNum
;
2365 UINT8 DeviceControl
;
2370 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2371 UINTN MaxDmaCommandSectors
;
2372 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp
;
2377 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
2378 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2379 AtaCommand
= ATA_CMD_READ_DMA
;
2381 case AtaUdmaReadExtOp
:
2382 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
2383 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2384 AtaCommand
= ATA_CMD_READ_DMA_EXT
;
2386 case AtaUdmaWriteOp
:
2387 MaxDmaCommandSectors
= ATAPI_MAX_DMA_CMD_SECTORS
;
2388 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2389 AtaCommand
= ATA_CMD_WRITE_DMA
;
2391 case AtaUdmaWriteExtOp
:
2392 MaxDmaCommandSectors
= ATAPI_MAX_DMA_EXT_CMD_SECTORS
;
2393 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2394 AtaCommand
= ATA_CMD_WRITE_DMA_EXT
;
2397 return EFI_UNSUPPORTED
;
2404 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2405 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2408 // Enable interrupt to support UDMA
2411 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2413 if (IdePrimary
== IdeDev
->Channel
) {
2414 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2415 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2416 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2418 if (IdeSecondary
== IdeDev
->Channel
) {
2419 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2420 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2421 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2423 return EFI_UNSUPPORTED
;
2428 // Read BMIS register and clear ERROR and INTR bit
2430 IdeDev
->PciIo
->Io
.Read (
2433 EFI_PCI_IO_PASS_THROUGH_BAR
,
2439 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2441 IdeDev
->PciIo
->Io
.Write (
2444 EFI_PCI_IO_PASS_THROUGH_BAR
,
2450 Status
= EFI_SUCCESS
;
2452 RemainBlockNum
= NumberOfBlocks
;
2453 while (RemainBlockNum
> 0) {
2455 if (RemainBlockNum
>= MaxDmaCommandSectors
) {
2457 // SectorCount is used to record the number of sectors to be read
2458 // Max 65536 sectors can be transfered at a time.
2460 NumberOfBlocks
= MaxDmaCommandSectors
;
2461 RemainBlockNum
-= MaxDmaCommandSectors
;
2463 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2468 // Calculate the number of PRD table to make sure the memory region
2469 // not cross 64K boundary
2471 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2472 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2477 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2478 Status
= IdeDev
->PciIo
->AllocateBuffer (
2481 EfiBootServicesData
,
2486 if (EFI_ERROR (Status
)) {
2487 return EFI_OUT_OF_RESOURCES
;
2489 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2491 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2493 // To make sure PRD is allocated in one 64K page
2495 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2496 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2498 if ((UINTN
) PrdAddr
& 0x03) {
2499 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2501 UsedPrdAddr
= PrdAddr
;
2506 // Build the PRD table
2508 Status
= IdeDev
->PciIo
->Map (
2516 if (EFI_ERROR (Status
)) {
2517 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2518 return EFI_OUT_OF_RESOURCES
;
2520 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
2521 TempPrdAddr
= UsedPrdAddr
;
2524 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2526 if (ByteCount
<= ByteAvailable
) {
2527 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2528 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2529 TempPrdAddr
->EndOfTable
= 0x8000;
2533 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2534 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2536 ByteCount
-= ByteAvailable
;
2537 PrdBuffer
+= ByteAvailable
;
2542 // Set the base address to BMID register
2544 IdeDev
->PciIo
->Io
.Write (
2546 EfiPciIoWidthUint32
,
2547 EFI_PCI_IO_PASS_THROUGH_BAR
,
2554 // Set BMIC register to identify the operation direction
2556 IdeDev
->PciIo
->Io
.Read (
2559 EFI_PCI_IO_PASS_THROUGH_BAR
,
2565 if (UdmaOp
== AtaUdmaReadExtOp
|| UdmaOp
== AtaUdmaReadOp
) {
2566 RegisterValue
|= BMIC_NREAD
;
2568 RegisterValue
&= ~((UINT8
) BMIC_NREAD
);
2571 IdeDev
->PciIo
->Io
.Write (
2574 EFI_PCI_IO_PASS_THROUGH_BAR
,
2580 if (UdmaOp
== AtaUdmaWriteExtOp
|| UdmaOp
== AtaUdmaReadExtOp
) {
2581 Status
= AtaCommandIssueExt (
2586 (UINT16
) NumberOfBlocks
,
2590 Status
= AtaCommandIssue (
2595 (UINT16
) NumberOfBlocks
,
2600 if (EFI_ERROR (Status
)) {
2601 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2602 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2603 return EFI_DEVICE_ERROR
;
2607 // Set START bit of BMIC register
2609 IdeDev
->PciIo
->Io
.Read (
2612 EFI_PCI_IO_PASS_THROUGH_BAR
,
2618 RegisterValue
|= BMIC_START
;
2620 IdeDev
->PciIo
->Io
.Write (
2623 EFI_PCI_IO_PASS_THROUGH_BAR
,
2630 // Check the INTERRUPT and ERROR bit of BMIS
2631 // Max transfer number of sectors for one command is 65536(32Mbyte),
2632 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
2633 // So set the variable Count to 2000, for about 2 second timeout time.
2635 Status
= EFI_SUCCESS
;
2639 IdeDev
->PciIo
->Io
.Read (
2642 EFI_PCI_IO_PASS_THROUGH_BAR
,
2647 if (((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) != 0) || (Count
== 0)) {
2648 if (((RegisterValue
& BMIS_ERROR
) != 0) || (Count
== 0)) {
2649 Status
= EFI_DEVICE_ERROR
;
2659 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2660 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2662 // Read BMIS register and clear ERROR and INTR bit
2664 IdeDev
->PciIo
->Io
.Read (
2667 EFI_PCI_IO_PASS_THROUGH_BAR
,
2673 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2675 IdeDev
->PciIo
->Io
.Write (
2678 EFI_PCI_IO_PASS_THROUGH_BAR
,
2684 // Read Status Register of IDE device to clear interrupt
2686 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
2688 // Clear START bit of BMIC register
2690 IdeDev
->PciIo
->Io
.Read (
2693 EFI_PCI_IO_PASS_THROUGH_BAR
,
2699 RegisterValue
&= ~((UINT8
) BMIC_START
);
2701 IdeDev
->PciIo
->Io
.Write (
2704 EFI_PCI_IO_PASS_THROUGH_BAR
,
2710 if ((RegisterValue
& BMIS_ERROR
) != 0) {
2711 return EFI_DEVICE_ERROR
;
2714 if (EFI_ERROR (Status
)) {
2717 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2718 StartLba
+= NumberOfBlocks
;
2722 // Disable interrupt of Select device
2724 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
2725 DeviceControl
|= ATA_CTLREG_IEN_L
;
2726 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);