2 Copyright (c) 2006, Intel Corporation
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
29 IN IDE_BLK_IO_DEV
*IdeDev
,
30 IN OUT VOID
*DataBuffer
,
32 IN UINTN NumberOfBlocks
37 IN IDE_BLK_IO_DEV
*IdeDev
,
40 IN UINTN NumberOfBlocks
45 IN IDE_BLK_IO_DEV
*IdeDev
,
55 IN IDE_BLK_IO_DEV
*IdeDev
,
64 Sends out an ATA Identify Command to the specified device.
66 This function is called by DiscoverIdeDevice() during its device
67 identification. It sends out the ATA Identify Command to the
68 specified device. Only ATA device responses to this command. If
69 the command succeeds, it returns the Identify data structure which
70 contains information about the device. This function extracts the
71 information it needs to fill the IDE_BLK_IO_DEV data structure,
72 including device type, media block size, media capacity, and etc.
75 pointer pointing to IDE_BLK_IO_DEV data structure,used
76 to record all the information of the IDE device.
78 @retval EFI_SUCCESS Identify ATA device successfully.
80 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or
81 device is not ATA device.
84 parameter IdeDev will be updated in this function.
89 IN IDE_BLK_IO_DEV
*IdeDev
93 EFI_IDENTIFY_DATA
*AtaIdentifyPointer
;
98 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
99 // the ATA Identify command
101 AtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
104 // use ATA PIO Data In protocol to send ATA Identify command
105 // and receive data from device
108 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
109 Status
= AtaPioDataIn (
111 (VOID
*) AtaIdentifyPointer
,
112 sizeof (EFI_IDENTIFY_DATA
),
121 // If ATA Identify command succeeds, then according to the received
123 // identify the device type ( ATA or not ).
124 // If ATA device, fill the information in IdeDev.
125 // If not ATA device, return IDE_DEVICE_ERROR
127 if (!EFI_ERROR (Status
)) {
129 IdeDev
->pIdData
= AtaIdentifyPointer
;
132 // Print ATA Module Name
134 PrintAtaModuleName (IdeDev
);
137 // bit 15 of pAtaIdentify->config is used to identify whether device is
138 // ATA device or ATAPI device.
139 // if 0, means ATA device; if 1, means ATAPI device.
141 if ((AtaIdentifyPointer
->AtaData
.config
& 0x8000) == 0x00) {
143 // Detect if support S.M.A.R.T. If yes, enable it as default
145 AtaSMARTSupport (IdeDev
);
148 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
150 Status
= AtaAtapi6Identify (IdeDev
);
151 if (!EFI_ERROR (Status
)) {
153 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
158 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
160 IdeDev
->Type
= IdeHardDisk
;
163 // Block Media Information:
164 // Media->LogicalPartition , Media->WriteCaching will be filled
165 // in the DiscoverIdeDevcie() function.
167 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
168 IdeDev
->BlkIo
.Media
->MediaId
= 1;
169 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
170 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
171 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
172 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
175 // Calculate device capacity
177 Capacity
= ((UINT32
)AtaIdentifyPointer
->AtaData
.user_addressable_sectors_hi
<< 16) |
178 AtaIdentifyPointer
->AtaData
.user_addressable_sectors_lo
;
179 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
186 gBS
->FreePool (AtaIdentifyPointer
);
188 // Make sure the pIdData will not be freed again.
190 IdeDev
->pIdData
= NULL
;
192 return EFI_DEVICE_ERROR
;
197 This function is called by ATAIdentify() to identity whether this disk
198 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
201 pointer pointing to IDE_BLK_IO_DEV data structure, used
202 to record all the information of the IDE device.
204 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one
205 and 48-bit addressing must be used
207 @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
208 the capacity is below 120G, 48bit addressing is not
212 This function must be called after DEVICE_IDENTITY command has been
213 successfully returned
218 IN IDE_BLK_IO_DEV
*IdeDev
224 EFI_IDENTIFY_DATA
*Atapi6IdentifyStruct
;
226 if (IdeDev
->pIdData
== NULL
) {
227 return EFI_UNSUPPORTED
;
230 Atapi6IdentifyStruct
= IdeDev
->pIdData
;
232 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& bit10
) == 0) {
234 // The device dosn't support 48 bit addressing
236 return EFI_UNSUPPORTED
;
240 // 48 bit address feature set is supported, get maximum capacity
242 Capacity
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[0];
243 for (Index
= 1; Index
< 4; Index
++) {
245 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
247 TmpLba
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[Index
];
248 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
251 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
253 // Capacity exceeds 120GB. 48-bit addressing is really needed
255 IdeDev
->Type
= Ide48bitAddressingHardDisk
;
258 // Fill block media information:Media->LogicalPartition ,
259 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
261 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
262 IdeDev
->BlkIo
.Media
->MediaId
= 1;
263 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
264 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
265 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
266 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
267 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
272 return EFI_UNSUPPORTED
;
276 This function is called by ATAIdentify() or ATAPIIdentify()
277 to print device's module name.
280 pointer pointing to IDE_BLK_IO_DEV data structure, used
281 to record all the information of the IDE device.
286 IN IDE_BLK_IO_DEV
*IdeDev
289 if (IdeDev
->pIdData
== NULL
) {
293 SwapStringChars (IdeDev
->ModelName
, IdeDev
->pIdData
->AtaData
.ModelName
, 40);
294 IdeDev
->ModelName
[40] = 0x00;
298 This function is used to send out ATA commands conforms to the
299 PIO Data In Protocol.
302 pointer pointing to IDE_BLK_IO_DEV data structure, used
303 to record all the information of the IDE device.
306 buffer contained data transferred from device to host.
309 data size in byte unit of the buffer.
311 @param[in] AtaCommand
312 value of the Command Register
315 value of the Head/Device Register
317 @param[in] SectorCount
318 value of the Sector Count Register
320 @param[in] SectorNumber
321 value of the Sector Number Register
323 @param[in] CylinderLsb
324 value of the low byte of the Cylinder Register
326 @param[in] CylinderMsb
327 value of the high byte of the Cylinder Register
329 @retval EFI_SUCCESS send out the ATA command and device send required
332 @retval EFI_DEVICE_ERROR command sent failed.
337 IN IDE_BLK_IO_DEV
*IdeDev
,
342 IN UINT8 SectorCount
,
343 IN UINT8 SectorNumber
,
344 IN UINT8 CylinderLsb
,
353 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
354 if (EFI_ERROR (Status
)) {
355 return EFI_DEVICE_ERROR
;
359 // e0:1110,0000-- bit7 and bit5 are reserved bits.
360 // bit6 set means LBA mode
364 IdeDev
->IoPort
->Head
,
365 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
369 // All ATAPI device's ATA commands can be issued regardless of the
372 if (IdeDev
->Type
== IdeHardDisk
) {
374 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
375 if (EFI_ERROR (Status
)) {
376 return EFI_DEVICE_ERROR
;
380 // set all the command parameters
381 // Before write to all the following registers, BSY and DRQ must be 0.
383 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
384 if (EFI_ERROR (Status
)) {
385 return EFI_DEVICE_ERROR
;
388 if (AtaCommand
== SET_FEATURES_CMD
) {
389 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
392 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
393 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
394 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
395 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
398 // send command via Command Register
400 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
402 Buffer16
= (UINT16
*) Buffer
;
405 // According to PIO data in protocol, host can perform a series of reads to
406 // the data register after each time device set DRQ ready;
407 // The data size of "a series of read" is command specific.
408 // For most ATA command, data size received from device will not exceed
409 // 1 sector, hence the data size for "a series of read" can be the whole data
410 // size of one command request.
411 // For ATA command such as Read Sector command, the data size of one ATA
412 // command request is often larger than 1 sector, according to the
413 // Read Sector command, the data size of "a series of read" is exactly 1
415 // Here for simplification reason, we specify the data size for
416 // "a series of read" to 1 sector (256 words) if data size of one ATA command
417 // request is larger than 256 words.
422 // used to record bytes of currently transfered data
426 while (WordCount
< ByteCount
/ 2) {
428 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
430 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
431 if (EFI_ERROR (Status
)) {
432 return EFI_DEVICE_ERROR
;
435 Status
= CheckErrorStatus (IdeDev
);
436 if (EFI_ERROR (Status
)) {
437 return EFI_DEVICE_ERROR
;
441 // Get the byte count for one series of read
443 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
444 Increment
= ByteCount
/ 2 - WordCount
;
447 IDEReadPortWMultiple (
449 IdeDev
->IoPort
->Data
,
454 WordCount
+= Increment
;
455 Buffer16
+= Increment
;
459 DRQClear (IdeDev
, ATATIMEOUT
);
461 return CheckErrorStatus (IdeDev
);
465 This function is used to send out ATA commands conforms to the
466 PIO Data Out Protocol.
469 pointer pointing to IDE_BLK_IO_DEV data structure, used
470 to record all the information of the IDE device.
472 @param *Buffer buffer contained data transferred from host to device.
473 @param ByteCount data size in byte unit of the buffer.
474 @param AtaCommand value of the Command Register
475 @param Head value of the Head/Device Register
476 @param SectorCount value of the Sector Count Register
477 @param SectorNumber value of the Sector Number Register
478 @param CylinderLsb value of the low byte of the Cylinder Register
479 @param CylinderMsb value of the high byte of the Cylinder Register
481 @retval EFI_SUCCESS send out the ATA command and device received required
484 @retval EFI_DEVICE_ERROR command sent failed.
489 IN IDE_BLK_IO_DEV
*IdeDev
,
494 IN UINT8 SectorCount
,
495 IN UINT8 SectorNumber
,
496 IN UINT8 CylinderLsb
,
505 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
506 if (EFI_ERROR (Status
)) {
507 return EFI_DEVICE_ERROR
;
511 // select device via Head/Device register.
512 // Before write Head/Device register, BSY and DRQ must be 0.
514 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
515 if (EFI_ERROR (Status
)) {
516 return EFI_DEVICE_ERROR
;
520 // e0:1110,0000-- bit7 and bit5 are reserved bits.
521 // bit6 set means LBA mode
525 IdeDev
->IoPort
->Head
,
526 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
529 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
530 if (EFI_ERROR (Status
)) {
531 return EFI_DEVICE_ERROR
;
535 // set all the command parameters
536 // Before write to all the following registers, BSY and DRQ must be 0.
538 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
539 if (EFI_ERROR (Status
)) {
540 return EFI_DEVICE_ERROR
;
543 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
544 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
545 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
546 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
549 // send command via Command Register
551 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
553 Buffer16
= (UINT16
*) Buffer
;
556 // According to PIO data out protocol, host can perform a series of
557 // writes to the data register after each time device set DRQ ready;
558 // The data size of "a series of read" is command specific.
559 // For most ATA command, data size written to device will not exceed 1 sector,
560 // hence the data size for "a series of write" can be the data size of one
562 // For ATA command such as Write Sector command, the data size of one
563 // ATA command request is often larger than 1 sector, according to the
564 // Write Sector command, the data size of "a series of read" is exactly
566 // Here for simplification reason, we specify the data size for
567 // "a series of write" to 1 sector (256 words) if data size of one ATA command
568 // request is larger than 256 words.
573 while (WordCount
< ByteCount
/ 2) {
576 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
577 // data transfer can be performed only when DRQ is ready.
579 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
580 if (EFI_ERROR (Status
)) {
581 return EFI_DEVICE_ERROR
;
584 Status
= CheckErrorStatus (IdeDev
);
585 if (EFI_ERROR (Status
)) {
586 return EFI_DEVICE_ERROR
;
590 // Check the remaining byte count is less than 512 bytes
592 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
593 Increment
= ByteCount
/ 2 - WordCount
;
596 // perform a series of write without check DRQ ready
599 IDEWritePortWMultiple (
601 IdeDev
->IoPort
->Data
,
605 WordCount
+= Increment
;
606 Buffer16
+= Increment
;
610 DRQClear (IdeDev
, ATATIMEOUT
);
612 return CheckErrorStatus (IdeDev
);
616 This function is used to analyze the Status Register and print out
617 some debug information and if there is ERR bit set in the Status
618 Register, the Error Register's value is also be parsed and print out.
621 pointer pointing to IDE_BLK_IO_DEV data structure, used
622 to record all the information of the IDE device.
624 @retval EFI_SUCCESS No err information in the Status Register.
625 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
630 IN IDE_BLK_IO_DEV
*IdeDev
633 UINT8 StatusRegister
;
641 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
645 if (StatusRegister
& DWF
) {
648 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
653 if (StatusRegister
& CORR
) {
656 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
661 if (StatusRegister
& ERR
) {
662 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
664 if (ErrorRegister
& BBK_ERR
) {
667 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
672 if (ErrorRegister
& UNC_ERR
) {
675 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
680 if (ErrorRegister
& MC_ERR
) {
683 "CheckErrorStatus()-- %02x : Error : Media Change\n",
688 if (ErrorRegister
& ABRT_ERR
) {
691 "CheckErrorStatus()-- %02x : Error : Abort\n",
696 if (ErrorRegister
& TK0NF_ERR
) {
699 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
704 if (ErrorRegister
& AMNF_ERR
) {
707 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
715 if ((StatusRegister
& (ERR
| DWF
| CORR
)) == 0) {
719 return EFI_DEVICE_ERROR
;
724 This function is called by the AtaBlkIoReadBlocks() to perform
725 reading from media in block unit.
728 pointer pointing to IDE_BLK_IO_DEV data structure, used
729 to record all the information of the IDE device.
731 @param[in] *DataBuffer
732 A pointer to the destination buffer for the data.
735 The starting logical block address to read from
738 @param[in] NumberOfBlocks
739 The number of transfer data blocks.
741 @return return status is fully dependent on the return status
742 of AtaPioDataIn() function.
747 IN IDE_BLK_IO_DEV
*IdeDev
,
750 IN UINTN NumberOfBlocks
754 UINTN BlocksRemaining
;
769 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
771 AtaCommand
= READ_SECTORS_CMD
;
774 BlocksRemaining
= NumberOfBlocks
;
776 Lba32
= (UINT32
) Lba
;
778 Status
= EFI_SUCCESS
;
780 while (BlocksRemaining
> 0) {
783 // in ATA-3 spec, LBA is in 28 bit width
785 Lba0
= (UINT8
) Lba32
;
786 Lba1
= (UINT8
) (Lba32
>> 8);
787 Lba2
= (UINT8
) (Lba32
>> 16);
789 // low 4 bit of Lba3 stands for LBA bit24~bit27.
791 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
793 if (BlocksRemaining
>= 0x100) {
796 // SectorCount8 is sent to Sector Count register, 0x00 means 256
797 // sectors to be read
801 // SectorCount is used to record the number of sectors to be read
806 SectorCount8
= (UINT8
) BlocksRemaining
;
807 SectorCount
= (UINT16
) BlocksRemaining
;
811 // ByteCount is the number of bytes that will be read
813 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
816 // call AtaPioDataIn() to send Read Sector Command and receive data read
818 Status
= AtaPioDataIn (
829 if (EFI_ERROR (Status
)) {
833 Lba32
+= SectorCount
;
834 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
835 BlocksRemaining
-= SectorCount
;
842 This function is called by the AtaBlkIoWriteBlocks() to perform
843 writing onto media in block unit.
846 pointer pointing to IDE_BLK_IO_DEV data structure,used
847 to record all the information of the IDE device.
849 @param[in] *BufferData
850 A pointer to the source buffer for the data.
853 The starting logical block address to write onto
856 @param[in] NumberOfBlocks
857 The number of transfer data blocks.
859 @return return status is fully dependent on the return status
860 of AtaPioDataOut() function.
865 IN IDE_BLK_IO_DEV
*IdeDev
,
868 IN UINTN NumberOfBlocks
872 UINTN BlocksRemaining
;
887 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
889 AtaCommand
= WRITE_SECTORS_CMD
;
891 BlocksRemaining
= NumberOfBlocks
;
893 Lba32
= (UINT32
) Lba
;
895 Status
= EFI_SUCCESS
;
897 while (BlocksRemaining
> 0) {
899 Lba0
= (UINT8
) Lba32
;
900 Lba1
= (UINT8
) (Lba32
>> 8);
901 Lba2
= (UINT8
) (Lba32
>> 16);
902 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
904 if (BlocksRemaining
>= 0x100) {
907 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
912 // SectorCount is used to record the number of sectors to be written
917 SectorCount8
= (UINT8
) BlocksRemaining
;
918 SectorCount
= (UINT16
) BlocksRemaining
;
921 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
923 Status
= AtaPioDataOut (
934 if (EFI_ERROR (Status
)) {
938 Lba32
+= SectorCount
;
939 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
940 BlocksRemaining
-= SectorCount
;
947 This function is used to implement the Soft Reset on the specified
948 device. But, the ATA Soft Reset mechanism is so strong a reset method
949 that it will force resetting on both devices connected to the
952 It is called by IdeBlkIoReset(), a interface function of Block
955 This function can also be used by the ATAPI device to perform reset when
956 ATAPI Reset command is failed.
959 pointer pointing to IDE_BLK_IO_DEV data structure, used
960 to record all the information of the IDE device.
962 @retval EFI_SUCCESS Soft reset completes successfully.
963 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
966 The registers initial values after ATA soft reset are different
967 to the ATA device and ATAPI device.
972 IN IDE_BLK_IO_DEV
*IdeDev
980 // set SRST bit to initiate soft reset
982 DeviceControl
|= SRST
;
987 DeviceControl
|= bit1
;
989 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
994 // Enable interrupt to support UDMA, and clear SRST bit
997 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
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 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1108 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1110 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1111 if (EFI_ERROR (Status
)) {
1112 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1116 // For ATA-3 compatible device, use ATA-3 read block mechanism
1117 // Notice DMA operation can only handle 32bit address
1119 if ((UINTN
) Buffer
<= 0xFFFFFFFF) {
1120 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1123 if (EFI_ERROR (Status
) || ((UINTN
) Buffer
> 0xFFFFFFFF)) {
1124 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1128 if (EFI_ERROR (Status
)) {
1129 AtaSoftReset (IdeBlkIoDevice
);
1130 return EFI_DEVICE_ERROR
;
1138 This function is the ATA implementation for WriteBlocks in the
1139 Block I/O Protocol interface.
1141 @param[in] *IdeBlkIoDevice
1142 Indicates the calling context.
1145 The media id that the write request is for.
1148 The starting logical block address to write onto
1151 @param[in] BufferSize
1152 The size of the Buffer in bytes. This must be a
1153 multiple of the intrinsic block size of the device.
1156 A pointer to the source buffer for the data.
1157 The caller is responsible for either having implicit
1158 or explicit ownership of the memory that data is
1161 @retval EFI_SUCCESS Write Blocks successfully.
1162 @retval EFI_DEVICE_ERROR Write Blocks failed.
1163 @retval EFI_NO_MEDIA There is no media in the device.
1164 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1166 @retval EFI_BAD_BUFFER_SIZE
1167 The BufferSize parameter is not a multiple of the
1168 intrinsic block size of the device.
1170 @retval EFI_INVALID_PARAMETER
1171 The write request contains LBAs that are not valid,
1172 or the data buffer is not valid.
1175 If Write Block error because of device error, this function will call
1176 AtaSoftReset() function to reset device.
1180 AtaBlkIoWriteBlocks (
1181 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1184 IN UINTN BufferSize
,
1189 EFI_BLOCK_IO_MEDIA
*Media
;
1191 UINTN NumberOfBlocks
;
1194 if (Buffer
== NULL
) {
1195 return EFI_INVALID_PARAMETER
;
1198 if (BufferSize
== 0) {
1202 Status
= EFI_SUCCESS
;
1205 // Get the intrinsic block size
1207 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1208 BlockSize
= Media
->BlockSize
;
1209 NumberOfBlocks
= BufferSize
/ BlockSize
;
1211 if (MediaId
!= Media
->MediaId
) {
1212 return EFI_MEDIA_CHANGED
;
1215 if (BufferSize
% BlockSize
!= 0) {
1216 return EFI_BAD_BUFFER_SIZE
;
1219 if (LBA
> Media
->LastBlock
) {
1220 return EFI_INVALID_PARAMETER
;
1223 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1224 return EFI_INVALID_PARAMETER
;
1227 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1228 return EFI_INVALID_PARAMETER
;
1231 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1233 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1235 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1236 if (EFI_ERROR (Status
)) {
1237 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1241 // For ATA-3 compatible device, use ATA-3 write block mechanism
1243 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1244 if (EFI_ERROR (Status
) || ((UINTN
) Buffer
> 0xFFFFFFFF)) {
1245 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1249 if (EFI_ERROR (Status
)) {
1250 AtaSoftReset (IdeBlkIoDevice
);
1251 return EFI_DEVICE_ERROR
;
1258 This function is called by the AtaBlkIoReadBlocks() to perform
1259 reading from media in block unit. The function has been enhanced to
1260 support >120GB access and transfer at most 65536 blocks per command
1263 pointer pointing to IDE_BLK_IO_DEV data structure, used
1264 to record all the information of the IDE device.
1266 @param[in] *DataBuffer A pointer to the destination buffer for the data.
1267 @param[in] StartLba The starting logical block address to read from
1268 on the device media.
1269 @param[in] NumberOfBlocks The number of transfer data blocks.
1271 @return return status is fully dependent on the return status
1272 of AtaPioDataInExt() function.
1277 IN IDE_BLK_IO_DEV
*IdeDev
,
1278 IN VOID
*DataBuffer
,
1279 IN EFI_LBA StartLba
,
1280 IN UINTN NumberOfBlocks
1284 UINTN BlocksRemaining
;
1292 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1294 AtaCommand
= READ_SECTORS_EXT_CMD
;
1295 Buffer
= DataBuffer
;
1296 BlocksRemaining
= NumberOfBlocks
;
1298 Status
= EFI_SUCCESS
;
1300 while (BlocksRemaining
> 0) {
1302 if (BlocksRemaining
>= 0x10000) {
1304 // SectorCount is used to record the number of sectors to be read
1305 // Max 65536 sectors can be transfered at a time.
1307 SectorCount
= 0xffff;
1309 SectorCount
= (UINT16
) BlocksRemaining
;
1313 // ByteCount is the number of bytes that will be read
1315 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1318 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1320 Status
= AtaPioDataInExt (
1328 if (EFI_ERROR (Status
)) {
1332 Lba64
+= SectorCount
;
1333 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1334 BlocksRemaining
-= SectorCount
;
1341 This function is called by the AtaBlkIoWriteBlocks() to perform
1342 writing onto media in block unit. The function has been enhanced to
1343 support >120GB access and transfer at most 65536 blocks per command
1346 pointer pointing to IDE_BLK_IO_DEV data structure,used
1347 to record all the information of the IDE device.
1349 @param[in] *DataBuffer
1350 A pointer to the source buffer for the data.
1353 The starting logical block address to write onto
1356 @param[in] NumberOfBlocks
1357 The number of transfer data blocks.
1359 @return status is fully dependent on the return status
1360 of AtaPioDataOutExt() function.
1364 AtaWriteSectorsExt (
1365 IN IDE_BLK_IO_DEV
*IdeDev
,
1366 IN VOID
*DataBuffer
,
1367 IN EFI_LBA StartLba
,
1368 IN UINTN NumberOfBlocks
1373 UINTN BlocksRemaining
;
1380 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1382 AtaCommand
= WRITE_SECTORS_EXT_CMD
;
1384 Buffer
= DataBuffer
;
1385 BlocksRemaining
= NumberOfBlocks
;
1387 Status
= EFI_SUCCESS
;
1389 while (BlocksRemaining
> 0) {
1391 if (BlocksRemaining
>= 0x10000) {
1393 // SectorCount is used to record the number of sectors to be written.
1394 // Max 65536 sectors can be transfered at a time.
1396 SectorCount
= 0xffff;
1398 SectorCount
= (UINT16
) BlocksRemaining
;
1402 // ByteCount is the number of bytes that will be written
1404 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1407 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1409 Status
= AtaPioDataOutExt (
1417 if (EFI_ERROR (Status
)) {
1421 Lba64
+= SectorCount
;
1422 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1423 BlocksRemaining
-= SectorCount
;
1430 This function is used to send out ATA commands conforms to the
1431 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1433 Comparing with ATA-3 data in protocol, we have two differents here:<BR>
1434 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1435 wait will frequently fail... cause writing function return error)
1437 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1438 slow down writing performance by 100 times!)
1440 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1441 to record all the information of the IDE device.
1443 @param[in,out] *Buffer buffer contained data transferred from device to host.
1444 @param[in] ByteCount data size in byte unit of the buffer.
1445 @param[in] AtaCommand value of the Command Register
1446 @param[in] StartLba the start LBA of this transaction
1447 @param[in] SectorCount the count of sectors to be transfered
1449 @retval EFI_SUCCESS send out the ATA command and device send required
1452 @retval EFI_DEVICE_ERROR command sent failed.
1457 IN IDE_BLK_IO_DEV
*IdeDev
,
1458 IN OUT VOID
*Buffer
,
1459 IN UINT32 ByteCount
,
1460 IN UINT8 AtaCommand
,
1461 IN EFI_LBA StartLba
,
1462 IN UINT16 SectorCount
1475 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1476 if (EFI_ERROR (Status
)) {
1477 return EFI_DEVICE_ERROR
;
1481 // Select device, set bit6 as 1 to indicate LBA mode is used
1483 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1487 IdeDev
->IoPort
->Head
,
1492 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1494 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1495 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1497 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1498 if (EFI_ERROR (Status
)) {
1499 return EFI_DEVICE_ERROR
;
1504 // Fill feature register if needed
1506 if (AtaCommand
== SET_FEATURES_CMD
) {
1507 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1511 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1513 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1514 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1516 SectorCount8
= (UINT8
) SectorCount
;
1517 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1520 // Fill the start LBA registers, which are also two-byte FIFO
1522 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1523 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1524 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1525 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1526 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1527 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1529 LbaLow
= (UINT8
) StartLba
;
1530 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1531 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1532 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1533 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1534 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1537 // Send command via Command Register, invoking the processing of this command
1539 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1541 Buffer16
= (UINT16
*) Buffer
;
1544 // According to PIO data in protocol, host can perform a series of reads to
1545 // the data register after each time device set DRQ ready;
1554 // used to record bytes of currently transfered data
1558 while (WordCount
< ByteCount
/ 2) {
1560 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1562 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1563 if (EFI_ERROR (Status
)) {
1564 return EFI_DEVICE_ERROR
;
1567 Status
= CheckErrorStatus (IdeDev
);
1568 if (EFI_ERROR (Status
)) {
1569 return EFI_DEVICE_ERROR
;
1573 // Get the byte count for one series of read
1575 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1576 Increment
= ByteCount
/ 2 - WordCount
;
1579 IDEReadPortWMultiple (
1581 IdeDev
->IoPort
->Data
,
1586 WordCount
+= Increment
;
1587 Buffer16
+= Increment
;
1591 return CheckErrorStatus (IdeDev
);
1595 This function is used to send out ATA commands conforms to the
1596 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1598 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
1599 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1600 wait will frequently fail... cause writing function return error)
1602 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1603 slow down writing performance by 100 times!)
1606 pointer pointing to IDE_BLK_IO_DEV data structure, used
1607 to record all the information of the IDE device.
1609 @param[in] *Buffer buffer contained data transferred from host to device.
1610 @param[in] ByteCount data size in byte unit of the buffer.
1611 @param[in] AtaCommand value of the Command Register
1612 @param[in] StartLba the start LBA of this transaction
1613 @param[in] SectorCount the count of sectors to be transfered
1615 @retval EFI_SUCCESS send out the ATA command and device receive required
1618 @retval EFI_DEVICE_ERROR command sent failed.
1623 IN IDE_BLK_IO_DEV
*IdeDev
,
1625 IN UINT32 ByteCount
,
1626 IN UINT8 AtaCommand
,
1627 IN EFI_LBA StartLba
,
1628 IN UINT16 SectorCount
1641 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1642 if (EFI_ERROR (Status
)) {
1643 return EFI_DEVICE_ERROR
;
1647 // Select device. Set bit6 as 1 to indicate LBA mode is used
1649 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1653 IdeDev
->IoPort
->Head
,
1658 // Wait for DRDY singnal asserting.
1660 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1661 if (EFI_ERROR (Status
)) {
1662 return EFI_DEVICE_ERROR
;
1666 // Fill feature register if needed
1668 if (AtaCommand
== SET_FEATURES_CMD
) {
1669 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1673 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1675 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1676 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1678 SectorCount8
= (UINT8
) SectorCount
;
1679 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1682 // Fill the start LBA registers, which are also two-byte FIFO
1684 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1685 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1686 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1687 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1688 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1689 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1691 LbaLow
= (UINT8
) StartLba
;
1692 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1693 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1694 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1695 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1696 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1699 // Send command via Command Register, invoking the processing of this command
1701 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1703 Buffer16
= (UINT16
*) Buffer
;
1706 // According to PIO Data Out protocol, host can perform a series of writes to
1707 // the data register after each time device set DRQ ready;
1712 // used to record bytes of currently transfered data
1716 while (WordCount
< ByteCount
/ 2) {
1718 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1720 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1721 if (EFI_ERROR (Status
)) {
1722 return EFI_DEVICE_ERROR
;
1725 Status
= CheckErrorStatus (IdeDev
);
1726 if (EFI_ERROR (Status
)) {
1727 return EFI_DEVICE_ERROR
;
1731 // Write data into device by one series of writing to data register
1733 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1734 Increment
= ByteCount
/ 2 - WordCount
;
1737 IDEWritePortWMultiple (
1739 IdeDev
->IoPort
->Data
,
1744 WordCount
+= Increment
;
1745 Buffer16
+= Increment
;
1752 return CheckErrorStatus (IdeDev
);
1757 Enable SMART of the disk if supported
1760 pointer pointing to IDE_BLK_IO_DEV data structure,used
1761 to record all the information of the IDE device.
1766 IN IDE_BLK_IO_DEV
*IdeDev
1770 BOOLEAN SMARTSupported
;
1772 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
1778 // Detect if the device supports S.M.A.R.T.
1780 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
1782 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
1786 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
1788 // S.M.A.R.T is not supported by the device
1790 SMARTSupported
= FALSE
;
1792 SMARTSupported
= TRUE
;
1796 if (!SMARTSupported
) {
1798 // Report nonsupport status code
1800 REPORT_STATUS_CODE (
1801 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1802 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
1806 // Enable this feature
1808 REPORT_STATUS_CODE (
1810 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
1813 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1814 Status
= AtaNonDataCommandIn (
1818 ATA_SMART_ENABLE_OPERATION
,
1825 // Detect if this feature is enabled
1827 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
1829 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
1830 Status
= AtaPioDataIn (
1832 (VOID
*) TmpAtaIdentifyPointer
,
1833 sizeof (EFI_IDENTIFY_DATA
),
1841 if (EFI_ERROR (Status
)) {
1842 gBS
->FreePool (TmpAtaIdentifyPointer
);
1847 // Check if the feature is enabled
1849 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
1853 AtaNonDataCommandIn (
1857 ATA_SMART_RETURN_STATUS
,
1863 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
1864 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
1866 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
1868 // The threshold exceeded condition is not detected by the device
1870 REPORT_STATUS_CODE (
1872 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
1875 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
1877 // The threshold exceeded condition is detected by the device
1879 REPORT_STATUS_CODE (
1881 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
1887 // Report disabled status code
1889 REPORT_STATUS_CODE (
1890 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1891 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
1895 gBS
->FreePool (TmpAtaIdentifyPointer
);
1902 Send ATA Ext command into device with NON_DATA protocol
1904 @param IdeDev Standard IDE device private data structure
1905 @param AtaCommand The ATA command to be sent
1906 @param Device The value in Device register
1907 @param Feature The value in Feature register
1908 @param SectorCount The value in SectorCount register
1909 @param LbaAddress The LBA address in 48-bit mode
1911 @retval EFI_SUCCESS Reading succeed
1912 @retval EFI_DEVICE_ERROR Error executing commands on this device
1916 AtaCommandIssueExt (
1917 IN IDE_BLK_IO_DEV
*IdeDev
,
1918 IN UINT8 AtaCommand
,
1921 IN UINT16 SectorCount
,
1922 IN EFI_LBA LbaAddress
1932 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1933 if (EFI_ERROR (Status
)) {
1934 return EFI_DEVICE_ERROR
;
1938 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1942 IdeDev
->IoPort
->Head
,
1943 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1947 // ATA commands for ATA device must be issued when DRDY is set
1949 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1950 if (EFI_ERROR (Status
)) {
1951 return EFI_DEVICE_ERROR
;
1955 // Pass parameter into device register block
1957 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1960 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1962 Feature8
= (UINT8
) (Feature
>> 8);
1963 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1965 Feature8
= (UINT8
) Feature
;
1966 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1969 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1971 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1972 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1974 SectorCount8
= (UINT8
) SectorCount
;
1975 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1978 // Fill the start LBA registers, which are also two-byte FIFO
1980 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1981 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1982 LbaLow
= (UINT8
) LbaAddress
;
1983 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1985 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1986 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1987 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1988 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1990 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1991 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1992 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1993 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1996 // Work around for Segate 160G disk writing
2001 // Send command via Command Register
2003 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2006 // Stall at least 400ns
2014 Send ATA Ext command into device with NON_DATA protocol
2016 @param IdeDev Standard IDE device private data structure
2017 @param AtaCommand The ATA command to be sent
2018 @param Device The value in Device register
2019 @param Feature The value in Feature register
2020 @param SectorCount The value in SectorCount register
2021 @param LbaAddress The LBA address in 48-bit mode
2023 @retval EFI_SUCCESS Reading succeed
2024 @retval EFI_DEVICE_ERROR Error executing commands on this device
2029 IN IDE_BLK_IO_DEV
*IdeDev
,
2030 IN UINT8 AtaCommand
,
2033 IN UINT16 SectorCount
,
2034 IN EFI_LBA LbaAddress
2045 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2046 if (EFI_ERROR (Status
)) {
2047 return EFI_DEVICE_ERROR
;
2051 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2055 IdeDev
->IoPort
->Head
,
2056 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2060 // ATA commands for ATA device must be issued when DRDY is set
2062 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2063 if (EFI_ERROR (Status
)) {
2064 return EFI_DEVICE_ERROR
;
2067 Lba0
= (UINT8
) LbaAddress
;
2068 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2069 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2070 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2074 // Pass parameter into device register block
2076 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2079 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2081 Feature8
= (UINT8
) Feature
;
2082 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2085 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2087 SectorCount8
= (UINT8
) SectorCount
;
2088 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2091 // Fill the start LBA registers, which are also two-byte FIFO
2094 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
2095 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
2096 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
2099 // Send command via Command Register
2101 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2104 // Stall at least 400ns
2112 This function is called by the AtaBlkIoReadBlocks() to perform
2113 reading from media in block unit. The function has been enhanced to
2114 support >120GB access and transfer at most 65536 blocks per command
2116 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2117 to record all the information of the IDE device.
2119 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2121 @param[in] StartLba The starting logical block address to read from
2122 on the device media.
2124 @param[in] NumberOfBlocks The number of transfer data blocks.
2126 @return The device status of UDMA operation. If the operation is
2127 successful, return EFI_SUCCESS.
2129 TODO: EFI_UNSUPPORTED - add return value to function comment
2130 TODO: EFI_DEVICE_ERROR - add return value to function comment
2131 TODO: EFI_DEVICE_ERROR - add return value to function comment
2132 TODO: EFI_DEVICE_ERROR - add return value to function comment
2136 IN IDE_BLK_IO_DEV
*IdeDev
,
2137 IN VOID
*DataBuffer
,
2138 IN EFI_LBA StartLba
,
2139 IN UINTN NumberOfBlocks
2142 IDE_DMA_PRD
*PrdAddr
;
2143 IDE_DMA_PRD
*UsedPrdAddr
;
2144 IDE_DMA_PRD
*TempPrdAddr
;
2145 UINT8 RegisterValue
;
2147 UINT64 IoPortForBmic
;
2148 UINT64 IoPortForBmis
;
2149 UINT64 IoPortForBmid
;
2153 UINTN ByteAvailable
;
2155 UINTN RemainBlockNum
;
2156 UINT8 DeviceControl
;
2159 // Channel and device differential. Select device.
2161 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2164 // Enable interrupt to support UDMA and Select device
2167 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2169 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2171 if (IdePrimary
== IdeDev
->Channel
) {
2172 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2173 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2174 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2176 if (IdeSecondary
== IdeDev
->Channel
) {
2177 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2178 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2179 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2181 return EFI_UNSUPPORTED
;
2185 RemainBlockNum
= NumberOfBlocks
;
2186 while (RemainBlockNum
> 0) {
2188 if (RemainBlockNum
>= MAX_DMA_EXT_COMMAND_SECTORS
) {
2190 // SectorCount is used to record the number of sectors to be read
2191 // Max 65536 sectors can be transfered at a time.
2193 NumberOfBlocks
= MAX_DMA_EXT_COMMAND_SECTORS
;
2194 RemainBlockNum
-= MAX_DMA_EXT_COMMAND_SECTORS
;
2196 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2201 // Calculate the number of PRD table to make sure the memory region
2202 // not cross 64K boundary
2204 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2205 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2210 PrdAddr
= (IDE_DMA_PRD
*) AllocateZeroPool ((2 * PrdTableNum
* sizeof (IDE_DMA_PRD
)));
2213 // To make sure PRD is allocated in one 64K page
2215 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2216 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2218 if ((UINTN
) PrdAddr
& 0x03) {
2219 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2221 UsedPrdAddr
= PrdAddr
;
2226 // Build the PRD table
2228 PrdBuffer
= DataBuffer
;
2229 TempPrdAddr
= UsedPrdAddr
;
2232 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2234 if (ByteCount
<= ByteAvailable
) {
2235 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2236 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2237 TempPrdAddr
->EndOfTable
= 0x8000;
2241 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2242 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2244 ByteCount
-= ByteAvailable
;
2245 PrdBuffer
+= ByteAvailable
;
2250 // Set the base address to BMID register
2252 IdeDev
->PciIo
->Io
.Write (
2254 EfiPciIoWidthUint32
,
2255 EFI_PCI_IO_PASS_THROUGH_BAR
,
2262 // Set BMIC register to identify the operation direction
2264 IdeDev
->PciIo
->Io
.Read (
2267 EFI_PCI_IO_PASS_THROUGH_BAR
,
2273 RegisterValue
|= BMIC_nREAD
;
2275 IdeDev
->PciIo
->Io
.Write (
2278 EFI_PCI_IO_PASS_THROUGH_BAR
,
2285 // Read BMIS register and clear ERROR and INTR bit
2287 IdeDev
->PciIo
->Io
.Read (
2290 EFI_PCI_IO_PASS_THROUGH_BAR
,
2296 RegisterValue
|= BMIS_INTERRUPT
| BMIS_ERROR
;
2298 IdeDev
->PciIo
->Io
.Write (
2301 EFI_PCI_IO_PASS_THROUGH_BAR
,
2308 // Issue READ DMA EXT command
2310 Status
= AtaCommandIssueExt (
2315 (UINT16
) NumberOfBlocks
,
2318 if (EFI_ERROR (Status
)) {
2319 gBS
->FreePool (PrdAddr
);
2320 return EFI_DEVICE_ERROR
;
2324 // Set START bit of BMIC register
2326 IdeDev
->PciIo
->Io
.Read (
2329 EFI_PCI_IO_PASS_THROUGH_BAR
,
2335 RegisterValue
|= BMIC_START
;
2337 IdeDev
->PciIo
->Io
.Write (
2340 EFI_PCI_IO_PASS_THROUGH_BAR
,
2347 // Check the INTERRUPT and ERROR bit of BMIS
2351 IdeDev
->PciIo
->Io
.Read (
2354 EFI_PCI_IO_PASS_THROUGH_BAR
,
2359 if (RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) {
2360 if (RegisterValue
& BMIS_ERROR
) {
2361 gBS
->FreePool (PrdAddr
);
2362 return EFI_DEVICE_ERROR
;
2370 gBS
->FreePool (PrdAddr
);
2373 // Set START bit of BMIC register
2375 IdeDev
->PciIo
->Io
.Read (
2378 EFI_PCI_IO_PASS_THROUGH_BAR
,
2384 RegisterValue
&= ~((UINT8
) BMIC_START
);
2386 IdeDev
->PciIo
->Io
.Write (
2389 EFI_PCI_IO_PASS_THROUGH_BAR
,
2395 if (RegisterValue
& BMIS_ERROR
) {
2396 return EFI_DEVICE_ERROR
;
2399 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2400 StartLba
+= NumberOfBlocks
;
2407 This function is called by the AtaBlkIoReadBlocks() to perform
2408 reading from media in block unit. The function has been enhanced to
2409 support >120GB access and transfer at most 65536 blocks per command
2412 pointer pointing to IDE_BLK_IO_DEV data structure, used
2413 to record all the information of the IDE device.
2415 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2416 @param[in] StartLba The starting logical block address to read from
2417 on the device media.
2418 @param[in] NumberOfBlocks The number of transfer data blocks.
2420 @return The device status of UDMA operation. If the operation is
2421 successful, return EFI_SUCCESS.
2423 TODO: EFI_UNSUPPORTED - add return value to function comment
2424 TODO: EFI_DEVICE_ERROR - add return value to function comment
2425 TODO: EFI_DEVICE_ERROR - add return value to function comment
2426 TODO: EFI_DEVICE_ERROR - add return value to function comment
2430 IN IDE_BLK_IO_DEV
*IdeDev
,
2431 IN VOID
*DataBuffer
,
2432 IN EFI_LBA StartLba
,
2433 IN UINTN NumberOfBlocks
2436 IDE_DMA_PRD
*PrdAddr
;
2437 IDE_DMA_PRD
*UsedPrdAddr
;
2438 IDE_DMA_PRD
*TempPrdAddr
;
2439 UINT8 RegisterValue
;
2441 UINT64 IoPortForBmic
;
2442 UINT64 IoPortForBmis
;
2443 UINT64 IoPortForBmid
;
2447 UINTN ByteAvailable
;
2449 UINTN RemainBlockNum
;
2450 UINT8 DeviceControl
;
2453 // Channel and device differential
2455 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2458 // Enable interrupt to support UDMA and Select device
2461 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2463 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2465 if (IdePrimary
== IdeDev
->Channel
) {
2466 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2467 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2468 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2470 if (IdeSecondary
== IdeDev
->Channel
) {
2471 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2472 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2473 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2475 return EFI_UNSUPPORTED
;
2479 RemainBlockNum
= NumberOfBlocks
;
2480 while (RemainBlockNum
> 0) {
2482 if (RemainBlockNum
>= MAX_DMA_COMMAND_SECTORS
) {
2484 // SectorCount is used to record the number of sectors to be read
2485 // Max 256 sectors can be transfered at a time.
2487 NumberOfBlocks
= MAX_DMA_COMMAND_SECTORS
;
2488 RemainBlockNum
-= MAX_DMA_COMMAND_SECTORS
;
2490 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2495 // Calculate the number of PRD table to make sure the memory region
2496 // not cross 64K boundary
2498 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2499 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2504 PrdAddr
= (IDE_DMA_PRD
*) AllocateZeroPool ((2 * PrdTableNum
* sizeof (IDE_DMA_PRD
)));
2506 // To make sure PRD is allocated in one 64K page
2508 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2509 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2511 if ((UINTN
) PrdAddr
& 0x03) {
2512 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2514 UsedPrdAddr
= PrdAddr
;
2519 // Build the PRD table
2521 PrdBuffer
= DataBuffer
;
2522 TempPrdAddr
= UsedPrdAddr
;
2525 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2527 if (ByteCount
<= ByteAvailable
) {
2528 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2529 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2530 TempPrdAddr
->EndOfTable
= 0x8000;
2534 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2535 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2537 ByteCount
-= ByteAvailable
;
2538 PrdBuffer
+= ByteAvailable
;
2543 // Set the base address to BMID register
2545 IdeDev
->PciIo
->Io
.Write (
2547 EfiPciIoWidthUint32
,
2548 EFI_PCI_IO_PASS_THROUGH_BAR
,
2555 // Set BMIC register to identify the operation direction
2557 IdeDev
->PciIo
->Io
.Read (
2560 EFI_PCI_IO_PASS_THROUGH_BAR
,
2566 RegisterValue
|= BMIC_nREAD
;
2568 IdeDev
->PciIo
->Io
.Write (
2571 EFI_PCI_IO_PASS_THROUGH_BAR
,
2578 // Read BMIS register and clear ERROR and INTR bit
2580 IdeDev
->PciIo
->Io
.Read (
2583 EFI_PCI_IO_PASS_THROUGH_BAR
,
2589 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2591 IdeDev
->PciIo
->Io
.Write (
2594 EFI_PCI_IO_PASS_THROUGH_BAR
,
2601 // Issue READ DMA command
2603 Status
= AtaCommandIssue (
2608 (UINT16
) NumberOfBlocks
,
2611 if (EFI_ERROR (Status
)) {
2612 gBS
->FreePool (PrdAddr
);
2613 return EFI_DEVICE_ERROR
;
2617 // Set START bit of BMIC register
2619 IdeDev
->PciIo
->Io
.Read (
2622 EFI_PCI_IO_PASS_THROUGH_BAR
,
2628 RegisterValue
|= BMIC_START
;
2630 IdeDev
->PciIo
->Io
.Write (
2633 EFI_PCI_IO_PASS_THROUGH_BAR
,
2640 // Check the INTERRUPT and ERROR bit of BMIS
2644 IdeDev
->PciIo
->Io
.Read (
2647 EFI_PCI_IO_PASS_THROUGH_BAR
,
2652 if (RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) {
2653 if (RegisterValue
& BMIS_ERROR
) {
2654 gBS
->FreePool (PrdAddr
);
2655 return EFI_DEVICE_ERROR
;
2663 gBS
->FreePool (PrdAddr
);
2666 // Set START bit of BMIC register
2668 IdeDev
->PciIo
->Io
.Read (
2671 EFI_PCI_IO_PASS_THROUGH_BAR
,
2677 RegisterValue
&= ~((UINT8
) BMIC_START
);
2679 IdeDev
->PciIo
->Io
.Write (
2682 EFI_PCI_IO_PASS_THROUGH_BAR
,
2688 if (RegisterValue
& BMIS_ERROR
) {
2689 return EFI_DEVICE_ERROR
;
2692 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2693 StartLba
+= NumberOfBlocks
;
2700 This function is called by the AtaBlkIoWriteBlocks() to perform
2701 writing to media in block unit. The function has been enhanced to
2702 support >120GB access and transfer at most 65536 blocks per command
2704 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2705 to record all the information of the IDE device.
2707 @param[in] *DataBuffer A pointer to the source buffer for the data.
2709 @param[in] StartLba The starting logical block address to write to
2710 on the device media.
2712 @param[in] NumberOfBlocks The number of transfer data blocks.
2714 @return The device status of UDMA operation. If the operation is
2715 successful, return EFI_SUCCESS.
2717 TODO: EFI_UNSUPPORTED - add return value to function comment
2718 TODO: EFI_DEVICE_ERROR - add return value to function comment
2719 TODO: EFI_DEVICE_ERROR - add return value to function comment
2723 IN IDE_BLK_IO_DEV
*IdeDev
,
2724 IN VOID
*DataBuffer
,
2725 IN EFI_LBA StartLba
,
2726 IN UINTN NumberOfBlocks
2729 IDE_DMA_PRD
*PrdAddr
;
2730 IDE_DMA_PRD
*UsedPrdAddr
;
2731 IDE_DMA_PRD
*TempPrdAddr
;
2732 UINT8 RegisterValue
;
2734 UINT64 IoPortForBmic
;
2735 UINT64 IoPortForBmis
;
2736 UINT64 IoPortForBmid
;
2740 UINTN ByteAvailable
;
2742 UINTN RemainBlockNum
;
2743 UINT8 DeviceControl
;
2746 // Channel and device differential
2748 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2751 // Enable interrupt to support UDMA and Select device
2754 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2756 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2758 if (IdePrimary
== IdeDev
->Channel
) {
2759 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2760 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2761 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2763 if (IdeSecondary
== IdeDev
->Channel
) {
2764 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2765 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2766 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2768 return EFI_UNSUPPORTED
;
2772 RemainBlockNum
= NumberOfBlocks
;
2773 while (RemainBlockNum
> 0) {
2775 if (RemainBlockNum
>= MAX_DMA_EXT_COMMAND_SECTORS
) {
2777 // SectorCount is used to record the number of sectors to be read
2778 // Max 65536 sectors can be transfered at a time.
2780 NumberOfBlocks
= MAX_DMA_EXT_COMMAND_SECTORS
;
2781 RemainBlockNum
-= MAX_DMA_EXT_COMMAND_SECTORS
;
2783 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2788 // Calculate the number of PRD table to make sure the memory region
2789 // not cross 64K boundary
2791 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2792 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2797 PrdAddr
= (IDE_DMA_PRD
*) AllocateZeroPool ((2 * PrdTableNum
* sizeof (IDE_DMA_PRD
)));
2799 // To make sure PRD is allocated in one 64K page
2801 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2802 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2804 if ((UINTN
) PrdAddr
& 0x03) {
2805 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2807 UsedPrdAddr
= PrdAddr
;
2812 // Build the PRD table
2814 PrdBuffer
= DataBuffer
;
2815 TempPrdAddr
= UsedPrdAddr
;
2818 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2820 if (ByteCount
<= ByteAvailable
) {
2821 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2822 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2823 TempPrdAddr
->EndOfTable
= 0x8000;
2827 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2828 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2830 ByteCount
-= ByteAvailable
;
2831 PrdBuffer
+= ByteAvailable
;
2836 // Set the base address to BMID register
2838 IdeDev
->PciIo
->Io
.Write (
2840 EfiPciIoWidthUint32
,
2841 EFI_PCI_IO_PASS_THROUGH_BAR
,
2848 // Set BMIC register to identify the operation direction
2850 IdeDev
->PciIo
->Io
.Read (
2853 EFI_PCI_IO_PASS_THROUGH_BAR
,
2861 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
2863 IdeDev
->PciIo
->Io
.Write (
2866 EFI_PCI_IO_PASS_THROUGH_BAR
,
2873 // Read BMIS register and clear ERROR and INTR bit
2875 IdeDev
->PciIo
->Io
.Read (
2878 EFI_PCI_IO_PASS_THROUGH_BAR
,
2884 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2886 IdeDev
->PciIo
->Io
.Write (
2889 EFI_PCI_IO_PASS_THROUGH_BAR
,
2896 // Issue WRITE DMA EXT command
2898 Status
= AtaCommandIssueExt (
2903 (UINT16
) NumberOfBlocks
,
2906 if (EFI_ERROR (Status
)) {
2907 gBS
->FreePool (PrdAddr
);
2908 return EFI_DEVICE_ERROR
;
2912 // Set START bit of BMIC register
2914 IdeDev
->PciIo
->Io
.Read (
2917 EFI_PCI_IO_PASS_THROUGH_BAR
,
2923 RegisterValue
|= BMIC_START
;
2925 IdeDev
->PciIo
->Io
.Write (
2928 EFI_PCI_IO_PASS_THROUGH_BAR
,
2935 // Check the INTERRUPT and ERROR bit of BMIS
2939 IdeDev
->PciIo
->Io
.Read (
2942 EFI_PCI_IO_PASS_THROUGH_BAR
,
2947 if (RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) {
2948 if (RegisterValue
& BMIS_ERROR
) {
2949 gBS
->FreePool (PrdAddr
);
2950 return EFI_DEVICE_ERROR
;
2958 gBS
->FreePool (PrdAddr
);
2961 // Set START bit of BMIC register
2963 IdeDev
->PciIo
->Io
.Read (
2966 EFI_PCI_IO_PASS_THROUGH_BAR
,
2972 RegisterValue
&= ~((UINT8
) BMIC_START
);
2974 IdeDev
->PciIo
->Io
.Write (
2977 EFI_PCI_IO_PASS_THROUGH_BAR
,
2983 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2984 StartLba
+= NumberOfBlocks
;
2991 This function is called by the AtaBlkIoWriteBlocks() to perform
2992 writing to media in block unit. The function has been enhanced to
2993 support >120GB access and transfer at most 65536 blocks per command
2996 pointer pointing to IDE_BLK_IO_DEV data structure, used
2997 to record all the information of the IDE device.
2999 @param[in] *DataBuffer
3000 A pointer to the source buffer for the data.
3003 The starting logical block address to write to
3004 on the device media.
3006 @param[in] NumberOfBlocks
3007 The number of transfer data blocks.
3009 @return The device status of UDMA operation. If the operation is
3010 successful, return EFI_SUCCESS.
3012 TODO: EFI_UNSUPPORTED - add return value to function comment
3013 TODO: EFI_DEVICE_ERROR - add return value to function comment
3014 TODO: EFI_DEVICE_ERROR - add return value to function comment
3018 IN IDE_BLK_IO_DEV
*IdeDev
,
3019 IN VOID
*DataBuffer
,
3020 IN EFI_LBA StartLba
,
3021 IN UINTN NumberOfBlocks
3024 IDE_DMA_PRD
*PrdAddr
;
3025 IDE_DMA_PRD
*UsedPrdAddr
;
3026 IDE_DMA_PRD
*TempPrdAddr
;
3027 UINT8 RegisterValue
;
3029 UINT64 IoPortForBmic
;
3030 UINT64 IoPortForBmis
;
3031 UINT64 IoPortForBmid
;
3035 UINTN ByteAvailable
;
3037 UINTN RemainBlockNum
;
3038 UINT8 DeviceControl
;
3041 // Channel and device differential
3043 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
3046 // Enable interrupt to support UDMA
3049 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
3051 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
3053 if (IdePrimary
== IdeDev
->Channel
) {
3054 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
3055 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
3056 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
3058 if (IdeSecondary
== IdeDev
->Channel
) {
3059 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
3060 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
3061 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
3063 return EFI_UNSUPPORTED
;
3067 RemainBlockNum
= NumberOfBlocks
;
3068 while (RemainBlockNum
> 0) {
3070 if (RemainBlockNum
>= MAX_DMA_COMMAND_SECTORS
) {
3072 // SectorCount is used to record the number of sectors to be read
3073 // Max 256 sectors can be transfered at a time.
3075 NumberOfBlocks
= MAX_DMA_COMMAND_SECTORS
;
3076 RemainBlockNum
-= MAX_DMA_COMMAND_SECTORS
;
3078 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
3083 // Calculate the number of PRD table to make sure the memory region
3084 // not cross 64K boundary
3086 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
3087 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
3092 PrdAddr
= (IDE_DMA_PRD
*) AllocateZeroPool ((2 * PrdTableNum
* sizeof (IDE_DMA_PRD
)));
3095 // To make sure PRD is allocated in one 64K page
3097 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
3098 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
3100 if ((UINTN
) PrdAddr
& 0x03) {
3101 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
3103 UsedPrdAddr
= PrdAddr
;
3108 // Build the PRD table
3110 PrdBuffer
= DataBuffer
;
3111 TempPrdAddr
= UsedPrdAddr
;
3114 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
3116 if (ByteCount
<= ByteAvailable
) {
3117 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
3118 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
3119 TempPrdAddr
->EndOfTable
= 0x8000;
3123 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
3124 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
3126 ByteCount
-= ByteAvailable
;
3127 PrdBuffer
+= ByteAvailable
;
3132 // Set the base address to BMID register
3134 IdeDev
->PciIo
->Io
.Write (
3136 EfiPciIoWidthUint32
,
3137 EFI_PCI_IO_PASS_THROUGH_BAR
,
3144 // Set BMIC register to identify the operation direction
3146 IdeDev
->PciIo
->Io
.Read (
3149 EFI_PCI_IO_PASS_THROUGH_BAR
,
3157 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
3159 IdeDev
->PciIo
->Io
.Write (
3162 EFI_PCI_IO_PASS_THROUGH_BAR
,
3169 // Read BMIS register and clear ERROR and INTR bit
3171 IdeDev
->PciIo
->Io
.Read (
3174 EFI_PCI_IO_PASS_THROUGH_BAR
,
3180 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
3182 IdeDev
->PciIo
->Io
.Write (
3185 EFI_PCI_IO_PASS_THROUGH_BAR
,
3192 // Issue WRITE DMA command
3194 Status
= AtaCommandIssue (
3199 (UINT16
) NumberOfBlocks
,
3202 if (EFI_ERROR (Status
)) {
3203 gBS
->FreePool (PrdAddr
);
3204 return EFI_DEVICE_ERROR
;
3208 // Set START bit of BMIC register
3210 IdeDev
->PciIo
->Io
.Read (
3213 EFI_PCI_IO_PASS_THROUGH_BAR
,
3219 RegisterValue
|= BMIC_START
;
3221 IdeDev
->PciIo
->Io
.Write (
3224 EFI_PCI_IO_PASS_THROUGH_BAR
,
3231 // Check the INTERRUPT and ERROR bit of BMIS
3235 IdeDev
->PciIo
->Io
.Read (
3238 EFI_PCI_IO_PASS_THROUGH_BAR
,
3243 if (RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) {
3244 if (RegisterValue
& BMIS_ERROR
) {
3245 gBS
->FreePool (PrdAddr
);
3246 return EFI_DEVICE_ERROR
;
3254 gBS
->FreePool (PrdAddr
);
3257 // Set START bit of BMIC register
3259 IdeDev
->PciIo
->Io
.Read (
3262 EFI_PCI_IO_PASS_THROUGH_BAR
,
3268 RegisterValue
&= ~((UINT8
) BMIC_START
);
3270 IdeDev
->PciIo
->Io
.Write (
3273 EFI_PCI_IO_PASS_THROUGH_BAR
,
3279 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
3280 StartLba
+= NumberOfBlocks
;