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
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
;
61 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
62 // the ATA Identify command
64 AtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
67 // use ATA PIO Data In protocol to send ATA Identify command
68 // and receive data from device
71 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
72 Status
= AtaPioDataIn (
74 (VOID
*) AtaIdentifyPointer
,
75 sizeof (EFI_IDENTIFY_DATA
),
84 // If ATA Identify command succeeds, then according to the received
86 // identify the device type ( ATA or not ).
87 // If ATA device, fill the information in IdeDev.
88 // If not ATA device, return IDE_DEVICE_ERROR
90 if (!EFI_ERROR (Status
)) {
92 IdeDev
->pIdData
= AtaIdentifyPointer
;
95 // Print ATA Module Name
97 PrintAtaModuleName (IdeDev
);
100 // bit 15 of pAtaIdentify->config is used to identify whether device is
101 // ATA device or ATAPI device.
102 // if 0, means ATA device; if 1, means ATAPI device.
104 if ((AtaIdentifyPointer
->AtaData
.config
& 0x8000) == 0x00) {
106 // Detect if support S.M.A.R.T. If yes, enable it as default
108 AtaSMARTSupport (IdeDev
);
111 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
113 Status
= AtaAtapi6Identify (IdeDev
);
114 if (!EFI_ERROR (Status
)) {
116 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
121 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
123 IdeDev
->Type
= IdeHardDisk
;
126 // Block Media Information:
127 // Media->LogicalPartition , Media->WriteCaching will be filled
128 // in the DiscoverIdeDevcie() function.
130 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
131 IdeDev
->BlkIo
.Media
->MediaId
= 1;
132 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
133 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
134 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
135 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
138 // Calculate device capacity
140 Capacity
= ((UINT32
)AtaIdentifyPointer
->AtaData
.user_addressable_sectors_hi
<< 16) |
141 AtaIdentifyPointer
->AtaData
.user_addressable_sectors_lo
;
142 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
149 gBS
->FreePool (AtaIdentifyPointer
);
151 // Make sure the pIdData will not be freed again.
153 IdeDev
->pIdData
= NULL
;
155 return EFI_DEVICE_ERROR
;
160 This function is called by ATAIdentify() to identity whether this disk
161 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
164 pointer pointing to IDE_BLK_IO_DEV data structure, used
165 to record all the information of the IDE device.
167 @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one
168 and 48-bit addressing must be used
170 @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but
171 the capacity is below 120G, 48bit addressing is not
175 This function must be called after DEVICE_IDENTITY command has been
176 successfully returned
181 IN IDE_BLK_IO_DEV
*IdeDev
187 EFI_IDENTIFY_DATA
*Atapi6IdentifyStruct
;
189 if (IdeDev
->pIdData
== NULL
) {
190 return EFI_UNSUPPORTED
;
193 Atapi6IdentifyStruct
= IdeDev
->pIdData
;
195 if ((Atapi6IdentifyStruct
->AtapiData
.cmd_set_support_83
& bit10
) == 0) {
197 // The device dosn't support 48 bit addressing
199 return EFI_UNSUPPORTED
;
203 // 48 bit address feature set is supported, get maximum capacity
205 Capacity
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[0];
206 for (Index
= 1; Index
< 4; Index
++) {
208 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
210 TmpLba
= Atapi6IdentifyStruct
->AtapiData
.max_user_lba_for_48bit_addr
[Index
];
211 Capacity
|= LShiftU64 (TmpLba
, 16 * Index
);
214 if (Capacity
> MAX_28BIT_ADDRESSING_CAPACITY
) {
216 // Capacity exceeds 120GB. 48-bit addressing is really needed
218 IdeDev
->Type
= Ide48bitAddressingHardDisk
;
221 // Fill block media information:Media->LogicalPartition ,
222 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
224 IdeDev
->BlkIo
.Media
->IoAlign
= 4;
225 IdeDev
->BlkIo
.Media
->MediaId
= 1;
226 IdeDev
->BlkIo
.Media
->RemovableMedia
= FALSE
;
227 IdeDev
->BlkIo
.Media
->MediaPresent
= TRUE
;
228 IdeDev
->BlkIo
.Media
->ReadOnly
= FALSE
;
229 IdeDev
->BlkIo
.Media
->BlockSize
= 0x200;
230 IdeDev
->BlkIo
.Media
->LastBlock
= Capacity
- 1;
235 return EFI_UNSUPPORTED
;
239 This function is called by ATAIdentify() or ATAPIIdentify()
240 to print device's module name.
243 pointer pointing to IDE_BLK_IO_DEV data structure, used
244 to record all the information of the IDE device.
249 IN IDE_BLK_IO_DEV
*IdeDev
252 if (IdeDev
->pIdData
== NULL
) {
256 SwapStringChars (IdeDev
->ModelName
, IdeDev
->pIdData
->AtaData
.ModelName
, 40);
257 IdeDev
->ModelName
[40] = 0x00;
261 This function is used to send out ATA commands conforms to the
262 PIO Data In Protocol.
265 pointer pointing to IDE_BLK_IO_DEV data structure, used
266 to record all the information of the IDE device.
269 buffer contained data transferred from device to host.
272 data size in byte unit of the buffer.
274 @param[in] AtaCommand
275 value of the Command Register
278 value of the Head/Device Register
280 @param[in] SectorCount
281 value of the Sector Count Register
283 @param[in] SectorNumber
284 value of the Sector Number Register
286 @param[in] CylinderLsb
287 value of the low byte of the Cylinder Register
289 @param[in] CylinderMsb
290 value of the high byte of the Cylinder Register
292 @retval EFI_SUCCESS send out the ATA command and device send required
295 @retval EFI_DEVICE_ERROR command sent failed.
300 IN IDE_BLK_IO_DEV
*IdeDev
,
305 IN UINT8 SectorCount
,
306 IN UINT8 SectorNumber
,
307 IN UINT8 CylinderLsb
,
316 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
317 if (EFI_ERROR (Status
)) {
318 return EFI_DEVICE_ERROR
;
322 // e0:1110,0000-- bit7 and bit5 are reserved bits.
323 // bit6 set means LBA mode
327 IdeDev
->IoPort
->Head
,
328 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
332 // All ATAPI device's ATA commands can be issued regardless of the
335 if (IdeDev
->Type
== IdeHardDisk
) {
337 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
338 if (EFI_ERROR (Status
)) {
339 return EFI_DEVICE_ERROR
;
343 // set all the command parameters
344 // Before write to all the following registers, BSY and DRQ must be 0.
346 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
347 if (EFI_ERROR (Status
)) {
348 return EFI_DEVICE_ERROR
;
351 if (AtaCommand
== SET_FEATURES_CMD
) {
352 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
355 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
356 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
357 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
358 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
361 // send command via Command Register
363 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
365 Buffer16
= (UINT16
*) Buffer
;
368 // According to PIO data in protocol, host can perform a series of reads to
369 // the data register after each time device set DRQ ready;
370 // The data size of "a series of read" is command specific.
371 // For most ATA command, data size received from device will not exceed
372 // 1 sector, hence the data size for "a series of read" can be the whole data
373 // size of one command request.
374 // For ATA command such as Read Sector command, the data size of one ATA
375 // command request is often larger than 1 sector, according to the
376 // Read Sector command, the data size of "a series of read" is exactly 1
378 // Here for simplification reason, we specify the data size for
379 // "a series of read" to 1 sector (256 words) if data size of one ATA command
380 // request is larger than 256 words.
385 // used to record bytes of currently transfered data
389 while (WordCount
< ByteCount
/ 2) {
391 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
393 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
394 if (EFI_ERROR (Status
)) {
395 return EFI_DEVICE_ERROR
;
398 Status
= CheckErrorStatus (IdeDev
);
399 if (EFI_ERROR (Status
)) {
400 return EFI_DEVICE_ERROR
;
404 // Get the byte count for one series of read
406 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
407 Increment
= ByteCount
/ 2 - WordCount
;
410 IDEReadPortWMultiple (
412 IdeDev
->IoPort
->Data
,
417 WordCount
+= Increment
;
418 Buffer16
+= Increment
;
422 DRQClear (IdeDev
, ATATIMEOUT
);
424 return CheckErrorStatus (IdeDev
);
428 This function is used to send out ATA commands conforms to the
429 PIO Data Out Protocol.
432 pointer pointing to IDE_BLK_IO_DEV data structure, used
433 to record all the information of the IDE device.
435 @param *Buffer buffer contained data transferred from host to device.
436 @param ByteCount data size in byte unit of the buffer.
437 @param AtaCommand value of the Command Register
438 @param Head value of the Head/Device Register
439 @param SectorCount value of the Sector Count Register
440 @param SectorNumber value of the Sector Number Register
441 @param CylinderLsb value of the low byte of the Cylinder Register
442 @param CylinderMsb value of the high byte of the Cylinder Register
444 @retval EFI_SUCCESS send out the ATA command and device received required
447 @retval EFI_DEVICE_ERROR command sent failed.
452 IN IDE_BLK_IO_DEV
*IdeDev
,
457 IN UINT8 SectorCount
,
458 IN UINT8 SectorNumber
,
459 IN UINT8 CylinderLsb
,
468 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
469 if (EFI_ERROR (Status
)) {
470 return EFI_DEVICE_ERROR
;
474 // select device via Head/Device register.
475 // Before write Head/Device register, BSY and DRQ must be 0.
477 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
478 if (EFI_ERROR (Status
)) {
479 return EFI_DEVICE_ERROR
;
483 // e0:1110,0000-- bit7 and bit5 are reserved bits.
484 // bit6 set means LBA mode
488 IdeDev
->IoPort
->Head
,
489 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0 | Head
)
492 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
493 if (EFI_ERROR (Status
)) {
494 return EFI_DEVICE_ERROR
;
498 // set all the command parameters
499 // Before write to all the following registers, BSY and DRQ must be 0.
501 Status
= DRQClear2 (IdeDev
, ATATIMEOUT
);
502 if (EFI_ERROR (Status
)) {
503 return EFI_DEVICE_ERROR
;
506 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount
);
507 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, SectorNumber
);
508 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, CylinderLsb
);
509 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, CylinderMsb
);
512 // send command via Command Register
514 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
516 Buffer16
= (UINT16
*) Buffer
;
519 // According to PIO data out protocol, host can perform a series of
520 // writes to the data register after each time device set DRQ ready;
521 // The data size of "a series of read" is command specific.
522 // For most ATA command, data size written to device will not exceed 1 sector,
523 // hence the data size for "a series of write" can be the data size of one
525 // For ATA command such as Write Sector command, the data size of one
526 // ATA command request is often larger than 1 sector, according to the
527 // Write Sector command, the data size of "a series of read" is exactly
529 // Here for simplification reason, we specify the data size for
530 // "a series of write" to 1 sector (256 words) if data size of one ATA command
531 // request is larger than 256 words.
536 while (WordCount
< ByteCount
/ 2) {
539 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
540 // data transfer can be performed only when DRQ is ready.
542 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
543 if (EFI_ERROR (Status
)) {
544 return EFI_DEVICE_ERROR
;
547 Status
= CheckErrorStatus (IdeDev
);
548 if (EFI_ERROR (Status
)) {
549 return EFI_DEVICE_ERROR
;
553 // Check the remaining byte count is less than 512 bytes
555 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
556 Increment
= ByteCount
/ 2 - WordCount
;
559 // perform a series of write without check DRQ ready
562 IDEWritePortWMultiple (
564 IdeDev
->IoPort
->Data
,
568 WordCount
+= Increment
;
569 Buffer16
+= Increment
;
573 DRQClear (IdeDev
, ATATIMEOUT
);
575 return CheckErrorStatus (IdeDev
);
579 This function is used to analyze the Status Register and print out
580 some debug information and if there is ERR bit set in the Status
581 Register, the Error Register's value is also be parsed and print out.
584 pointer pointing to IDE_BLK_IO_DEV data structure, used
585 to record all the information of the IDE device.
587 @retval EFI_SUCCESS No err information in the Status Register.
588 @retval EFI_DEVICE_ERROR Any err information in the Status Register.
593 IN IDE_BLK_IO_DEV
*IdeDev
596 UINT8 StatusRegister
;
604 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
608 if (StatusRegister
& DWF
) {
611 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
616 if (StatusRegister
& CORR
) {
619 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
624 if (StatusRegister
& ERR
) {
625 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
627 if (ErrorRegister
& BBK_ERR
) {
630 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
635 if (ErrorRegister
& UNC_ERR
) {
638 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
643 if (ErrorRegister
& MC_ERR
) {
646 "CheckErrorStatus()-- %02x : Error : Media Change\n",
651 if (ErrorRegister
& ABRT_ERR
) {
654 "CheckErrorStatus()-- %02x : Error : Abort\n",
659 if (ErrorRegister
& TK0NF_ERR
) {
662 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
667 if (ErrorRegister
& AMNF_ERR
) {
670 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
678 if ((StatusRegister
& (ERR
| DWF
| CORR
)) == 0) {
682 return EFI_DEVICE_ERROR
;
687 This function is called by the AtaBlkIoReadBlocks() to perform
688 reading from media in block unit.
691 pointer pointing to IDE_BLK_IO_DEV data structure, used
692 to record all the information of the IDE device.
694 @param[in] *DataBuffer
695 A pointer to the destination buffer for the data.
698 The starting logical block address to read from
701 @param[in] NumberOfBlocks
702 The number of transfer data blocks.
704 @return return status is fully dependent on the return status
705 of AtaPioDataIn() function.
710 IN IDE_BLK_IO_DEV
*IdeDev
,
713 IN UINTN NumberOfBlocks
717 UINTN BlocksRemaining
;
732 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
734 AtaCommand
= READ_SECTORS_CMD
;
737 BlocksRemaining
= NumberOfBlocks
;
739 Lba32
= (UINT32
) Lba
;
741 Status
= EFI_SUCCESS
;
743 while (BlocksRemaining
> 0) {
746 // in ATA-3 spec, LBA is in 28 bit width
748 Lba0
= (UINT8
) Lba32
;
749 Lba1
= (UINT8
) (Lba32
>> 8);
750 Lba2
= (UINT8
) (Lba32
>> 16);
752 // low 4 bit of Lba3 stands for LBA bit24~bit27.
754 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
756 if (BlocksRemaining
>= 0x100) {
759 // SectorCount8 is sent to Sector Count register, 0x00 means 256
760 // sectors to be read
764 // SectorCount is used to record the number of sectors to be read
769 SectorCount8
= (UINT8
) BlocksRemaining
;
770 SectorCount
= (UINT16
) BlocksRemaining
;
774 // ByteCount is the number of bytes that will be read
776 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
779 // call AtaPioDataIn() to send Read Sector Command and receive data read
781 Status
= AtaPioDataIn (
792 if (EFI_ERROR (Status
)) {
796 Lba32
+= SectorCount
;
797 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
798 BlocksRemaining
-= SectorCount
;
805 This function is called by the AtaBlkIoWriteBlocks() to perform
806 writing onto media in block unit.
809 pointer pointing to IDE_BLK_IO_DEV data structure,used
810 to record all the information of the IDE device.
812 @param[in] *BufferData
813 A pointer to the source buffer for the data.
816 The starting logical block address to write onto
819 @param[in] NumberOfBlocks
820 The number of transfer data blocks.
822 @return return status is fully dependent on the return status
823 of AtaPioDataOut() function.
828 IN IDE_BLK_IO_DEV
*IdeDev
,
831 IN UINTN NumberOfBlocks
835 UINTN BlocksRemaining
;
850 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
852 AtaCommand
= WRITE_SECTORS_CMD
;
854 BlocksRemaining
= NumberOfBlocks
;
856 Lba32
= (UINT32
) Lba
;
858 Status
= EFI_SUCCESS
;
860 while (BlocksRemaining
> 0) {
862 Lba0
= (UINT8
) Lba32
;
863 Lba1
= (UINT8
) (Lba32
>> 8);
864 Lba2
= (UINT8
) (Lba32
>> 16);
865 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
867 if (BlocksRemaining
>= 0x100) {
870 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
875 // SectorCount is used to record the number of sectors to be written
880 SectorCount8
= (UINT8
) BlocksRemaining
;
881 SectorCount
= (UINT16
) BlocksRemaining
;
884 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
886 Status
= AtaPioDataOut (
897 if (EFI_ERROR (Status
)) {
901 Lba32
+= SectorCount
;
902 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
903 BlocksRemaining
-= SectorCount
;
910 This function is used to implement the Soft Reset on the specified
911 device. But, the ATA Soft Reset mechanism is so strong a reset method
912 that it will force resetting on both devices connected to the
915 It is called by IdeBlkIoReset(), a interface function of Block
918 This function can also be used by the ATAPI device to perform reset when
919 ATAPI Reset command is failed.
922 pointer pointing to IDE_BLK_IO_DEV data structure, used
923 to record all the information of the IDE device.
925 @retval EFI_SUCCESS Soft reset completes successfully.
926 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
929 The registers initial values after ATA soft reset are different
930 to the ATA device and ATAPI device.
935 IN IDE_BLK_IO_DEV
*IdeDev
943 // set SRST bit to initiate soft reset
945 DeviceControl
|= SRST
;
950 DeviceControl
|= bit1
;
952 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
955 // SRST should assert for at least 5 us, we use 10 us for
956 // better compatibility
961 // Enable interrupt to support UDMA, and clear SRST bit
964 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
967 // Wait for at least 2 ms to check BSY status, we use 10 ms
968 // for better compatibility
972 // slave device needs at most 31s to clear BSY
974 if (WaitForBSYClear (IdeDev
, 31000) == EFI_TIMEOUT
) {
975 return EFI_DEVICE_ERROR
;
982 This function is the ATA implementation for ReadBlocks in the
983 Block I/O Protocol interface.
985 @param[in] *IdeBlkIoDevice
986 Indicates the calling context.
989 The media id that the read request is for.
992 The starting logical block address to read from
995 @param[in] BufferSize
996 The size of the Buffer in bytes. This must be a
997 multiple of the intrinsic block size of the device.
1000 A pointer to the destination buffer for the data.
1001 The caller is responsible for either having implicit
1002 or explicit ownership of the memory that data is read into.
1004 @retval EFI_SUCCESS Read Blocks successfully.
1005 @retval EFI_DEVICE_ERROR Read Blocks failed.
1006 @retval EFI_NO_MEDIA There is no media in the device.
1007 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1009 @retval EFI_BAD_BUFFER_SIZE
1010 The BufferSize parameter is not a multiple of the
1011 intrinsic block size of the device.
1013 @retval EFI_INVALID_PARAMETER
1014 The read request contains LBAs that are not valid,
1015 or the data buffer is not valid.
1018 If Read Block error because of device error, this function will call
1019 AtaSoftReset() function to reset device.
1023 AtaBlkIoReadBlocks (
1024 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1027 IN UINTN BufferSize
,
1031 EFI_BLOCK_IO_MEDIA
*Media
;
1033 UINTN NumberOfBlocks
;
1036 if (Buffer
== NULL
) {
1037 return EFI_INVALID_PARAMETER
;
1040 if (BufferSize
== 0) {
1044 Status
= EFI_SUCCESS
;
1047 // Get the intrinsic block size
1049 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1050 BlockSize
= Media
->BlockSize
;
1052 NumberOfBlocks
= BufferSize
/ BlockSize
;
1054 if (MediaId
!= Media
->MediaId
) {
1055 return EFI_MEDIA_CHANGED
;
1058 if (BufferSize
% BlockSize
!= 0) {
1059 return EFI_BAD_BUFFER_SIZE
;
1062 if (!(Media
->MediaPresent
)) {
1063 return EFI_NO_MEDIA
;
1066 if (LBA
> Media
->LastBlock
) {
1067 return EFI_INVALID_PARAMETER
;
1070 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1071 return EFI_INVALID_PARAMETER
;
1074 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1075 return EFI_INVALID_PARAMETER
;
1078 Status
= EFI_SUCCESS
;
1079 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1081 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1083 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1084 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1086 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1090 // For ATA-3 compatible device, use ATA-3 read block mechanism
1092 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1093 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1095 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1099 if (EFI_ERROR (Status
)) {
1100 AtaSoftReset (IdeBlkIoDevice
);
1101 return EFI_DEVICE_ERROR
;
1109 This function is the ATA implementation for WriteBlocks in the
1110 Block I/O Protocol interface.
1112 @param[in] *IdeBlkIoDevice
1113 Indicates the calling context.
1116 The media id that the write request is for.
1119 The starting logical block address to write onto
1122 @param[in] BufferSize
1123 The size of the Buffer in bytes. This must be a
1124 multiple of the intrinsic block size of the device.
1127 A pointer to the source buffer for the data.
1128 The caller is responsible for either having implicit
1129 or explicit ownership of the memory that data is
1132 @retval EFI_SUCCESS Write Blocks successfully.
1133 @retval EFI_DEVICE_ERROR Write Blocks failed.
1134 @retval EFI_NO_MEDIA There is no media in the device.
1135 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1137 @retval EFI_BAD_BUFFER_SIZE
1138 The BufferSize parameter is not a multiple of the
1139 intrinsic block size of the device.
1141 @retval EFI_INVALID_PARAMETER
1142 The write request contains LBAs that are not valid,
1143 or the data buffer is not valid.
1146 If Write Block error because of device error, this function will call
1147 AtaSoftReset() function to reset device.
1151 AtaBlkIoWriteBlocks (
1152 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1155 IN UINTN BufferSize
,
1160 EFI_BLOCK_IO_MEDIA
*Media
;
1162 UINTN NumberOfBlocks
;
1165 if (Buffer
== NULL
) {
1166 return EFI_INVALID_PARAMETER
;
1169 if (BufferSize
== 0) {
1173 Status
= EFI_SUCCESS
;
1176 // Get the intrinsic block size
1178 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1179 BlockSize
= Media
->BlockSize
;
1180 NumberOfBlocks
= BufferSize
/ BlockSize
;
1182 if (MediaId
!= Media
->MediaId
) {
1183 return EFI_MEDIA_CHANGED
;
1186 if (BufferSize
% BlockSize
!= 0) {
1187 return EFI_BAD_BUFFER_SIZE
;
1190 if (LBA
> Media
->LastBlock
) {
1191 return EFI_INVALID_PARAMETER
;
1194 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1195 return EFI_INVALID_PARAMETER
;
1198 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1199 return EFI_INVALID_PARAMETER
;
1202 Status
= EFI_SUCCESS
;
1203 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1205 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1207 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1208 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1210 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1214 // For ATA-3 compatible device, use ATA-3 write block mechanism
1216 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1217 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1219 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1223 if (EFI_ERROR (Status
)) {
1224 AtaSoftReset (IdeBlkIoDevice
);
1225 return EFI_DEVICE_ERROR
;
1232 This function is called by the AtaBlkIoReadBlocks() to perform
1233 reading from media in block unit. The function has been enhanced to
1234 support >120GB access and transfer at most 65536 blocks per command
1237 pointer pointing to IDE_BLK_IO_DEV data structure, used
1238 to record all the information of the IDE device.
1240 @param[in] *DataBuffer A pointer to the destination buffer for the data.
1241 @param[in] StartLba The starting logical block address to read from
1242 on the device media.
1243 @param[in] NumberOfBlocks The number of transfer data blocks.
1245 @return return status is fully dependent on the return status
1246 of AtaPioDataInExt() function.
1251 IN IDE_BLK_IO_DEV
*IdeDev
,
1252 IN VOID
*DataBuffer
,
1253 IN EFI_LBA StartLba
,
1254 IN UINTN NumberOfBlocks
1258 UINTN BlocksRemaining
;
1266 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1268 AtaCommand
= READ_SECTORS_EXT_CMD
;
1269 Buffer
= DataBuffer
;
1270 BlocksRemaining
= NumberOfBlocks
;
1272 Status
= EFI_SUCCESS
;
1274 while (BlocksRemaining
> 0) {
1276 if (BlocksRemaining
>= 0x10000) {
1278 // SectorCount is used to record the number of sectors to be read
1279 // Max 65536 sectors can be transfered at a time.
1281 SectorCount
= 0xffff;
1283 SectorCount
= (UINT16
) BlocksRemaining
;
1287 // ByteCount is the number of bytes that will be read
1289 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1292 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1294 Status
= AtaPioDataInExt (
1302 if (EFI_ERROR (Status
)) {
1306 Lba64
+= SectorCount
;
1307 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1308 BlocksRemaining
-= SectorCount
;
1315 This function is called by the AtaBlkIoWriteBlocks() to perform
1316 writing onto media in block unit. The function has been enhanced to
1317 support >120GB access and transfer at most 65536 blocks per command
1320 pointer pointing to IDE_BLK_IO_DEV data structure,used
1321 to record all the information of the IDE device.
1323 @param[in] *DataBuffer
1324 A pointer to the source buffer for the data.
1327 The starting logical block address to write onto
1330 @param[in] NumberOfBlocks
1331 The number of transfer data blocks.
1333 @return status is fully dependent on the return status
1334 of AtaPioDataOutExt() function.
1338 AtaWriteSectorsExt (
1339 IN IDE_BLK_IO_DEV
*IdeDev
,
1340 IN VOID
*DataBuffer
,
1341 IN EFI_LBA StartLba
,
1342 IN UINTN NumberOfBlocks
1347 UINTN BlocksRemaining
;
1354 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1356 AtaCommand
= WRITE_SECTORS_EXT_CMD
;
1358 Buffer
= DataBuffer
;
1359 BlocksRemaining
= NumberOfBlocks
;
1361 Status
= EFI_SUCCESS
;
1363 while (BlocksRemaining
> 0) {
1365 if (BlocksRemaining
>= 0x10000) {
1367 // SectorCount is used to record the number of sectors to be written.
1368 // Max 65536 sectors can be transfered at a time.
1370 SectorCount
= 0xffff;
1372 SectorCount
= (UINT16
) BlocksRemaining
;
1376 // ByteCount is the number of bytes that will be written
1378 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1381 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1383 Status
= AtaPioDataOutExt (
1391 if (EFI_ERROR (Status
)) {
1395 Lba64
+= SectorCount
;
1396 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1397 BlocksRemaining
-= SectorCount
;
1404 This function is used to send out ATA commands conforms to the
1405 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1407 Comparing with ATA-3 data in protocol, we have two differents here:<BR>
1408 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1409 wait will frequently fail... cause writing function return error)
1411 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1412 slow down writing performance by 100 times!)
1414 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1415 to record all the information of the IDE device.
1417 @param[in,out] *Buffer buffer contained data transferred from device to host.
1418 @param[in] ByteCount data size in byte unit of the buffer.
1419 @param[in] AtaCommand value of the Command Register
1420 @param[in] StartLba the start LBA of this transaction
1421 @param[in] SectorCount the count of sectors to be transfered
1423 @retval EFI_SUCCESS send out the ATA command and device send required
1426 @retval EFI_DEVICE_ERROR command sent failed.
1431 IN IDE_BLK_IO_DEV
*IdeDev
,
1432 IN OUT VOID
*Buffer
,
1433 IN UINT32 ByteCount
,
1434 IN UINT8 AtaCommand
,
1435 IN EFI_LBA StartLba
,
1436 IN UINT16 SectorCount
1449 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1450 if (EFI_ERROR (Status
)) {
1451 return EFI_DEVICE_ERROR
;
1455 // Select device, set bit6 as 1 to indicate LBA mode is used
1457 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1461 IdeDev
->IoPort
->Head
,
1466 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1468 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1469 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1471 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1472 if (EFI_ERROR (Status
)) {
1473 return EFI_DEVICE_ERROR
;
1478 // Fill feature register if needed
1480 if (AtaCommand
== SET_FEATURES_CMD
) {
1481 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1485 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1487 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1488 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1490 SectorCount8
= (UINT8
) SectorCount
;
1491 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1494 // Fill the start LBA registers, which are also two-byte FIFO
1496 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1497 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1498 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1499 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1500 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1501 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1503 LbaLow
= (UINT8
) StartLba
;
1504 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1505 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1506 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1507 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1508 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1511 // Send command via Command Register, invoking the processing of this command
1513 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1515 Buffer16
= (UINT16
*) Buffer
;
1518 // According to PIO data in protocol, host can perform a series of reads to
1519 // the data register after each time device set DRQ ready;
1528 // used to record bytes of currently transfered data
1532 while (WordCount
< ByteCount
/ 2) {
1534 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1536 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1537 if (EFI_ERROR (Status
)) {
1538 return EFI_DEVICE_ERROR
;
1541 Status
= CheckErrorStatus (IdeDev
);
1542 if (EFI_ERROR (Status
)) {
1543 return EFI_DEVICE_ERROR
;
1547 // Get the byte count for one series of read
1549 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1550 Increment
= ByteCount
/ 2 - WordCount
;
1553 IDEReadPortWMultiple (
1555 IdeDev
->IoPort
->Data
,
1560 WordCount
+= Increment
;
1561 Buffer16
+= Increment
;
1565 return CheckErrorStatus (IdeDev
);
1569 This function is used to send out ATA commands conforms to the
1570 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1572 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
1573 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1574 wait will frequently fail... cause writing function return error)
1576 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1577 slow down writing performance by 100 times!)
1580 pointer pointing to IDE_BLK_IO_DEV data structure, used
1581 to record all the information of the IDE device.
1583 @param[in] *Buffer buffer contained data transferred from host to device.
1584 @param[in] ByteCount data size in byte unit of the buffer.
1585 @param[in] AtaCommand value of the Command Register
1586 @param[in] StartLba the start LBA of this transaction
1587 @param[in] SectorCount the count of sectors to be transfered
1589 @retval EFI_SUCCESS send out the ATA command and device receive required
1592 @retval EFI_DEVICE_ERROR command sent failed.
1597 IN IDE_BLK_IO_DEV
*IdeDev
,
1599 IN UINT32 ByteCount
,
1600 IN UINT8 AtaCommand
,
1601 IN EFI_LBA StartLba
,
1602 IN UINT16 SectorCount
1615 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1616 if (EFI_ERROR (Status
)) {
1617 return EFI_DEVICE_ERROR
;
1621 // Select device. Set bit6 as 1 to indicate LBA mode is used
1623 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1627 IdeDev
->IoPort
->Head
,
1632 // Wait for DRDY singnal asserting.
1634 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1635 if (EFI_ERROR (Status
)) {
1636 return EFI_DEVICE_ERROR
;
1640 // Fill feature register if needed
1642 if (AtaCommand
== SET_FEATURES_CMD
) {
1643 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1647 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1649 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1650 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1652 SectorCount8
= (UINT8
) SectorCount
;
1653 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1656 // Fill the start LBA registers, which are also two-byte FIFO
1658 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1659 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1660 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1661 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1662 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1663 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1665 LbaLow
= (UINT8
) StartLba
;
1666 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1667 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1668 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1669 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1670 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1673 // Send command via Command Register, invoking the processing of this command
1675 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1677 Buffer16
= (UINT16
*) Buffer
;
1680 // According to PIO Data Out protocol, host can perform a series of writes to
1681 // the data register after each time device set DRQ ready;
1686 // used to record bytes of currently transfered data
1690 while (WordCount
< ByteCount
/ 2) {
1692 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1694 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1695 if (EFI_ERROR (Status
)) {
1696 return EFI_DEVICE_ERROR
;
1699 Status
= CheckErrorStatus (IdeDev
);
1700 if (EFI_ERROR (Status
)) {
1701 return EFI_DEVICE_ERROR
;
1705 // Write data into device by one series of writing to data register
1707 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1708 Increment
= ByteCount
/ 2 - WordCount
;
1711 IDEWritePortWMultiple (
1713 IdeDev
->IoPort
->Data
,
1718 WordCount
+= Increment
;
1719 Buffer16
+= Increment
;
1726 return CheckErrorStatus (IdeDev
);
1731 Enable SMART of the disk if supported
1734 pointer pointing to IDE_BLK_IO_DEV data structure,used
1735 to record all the information of the IDE device.
1740 IN IDE_BLK_IO_DEV
*IdeDev
1744 BOOLEAN SMARTSupported
;
1746 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
1752 // Detect if the device supports S.M.A.R.T.
1754 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
1756 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
1760 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
1762 // S.M.A.R.T is not supported by the device
1764 SMARTSupported
= FALSE
;
1766 SMARTSupported
= TRUE
;
1770 if (!SMARTSupported
) {
1772 // Report nonsupport status code
1774 REPORT_STATUS_CODE (
1775 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1776 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
1780 // Enable this feature
1782 REPORT_STATUS_CODE (
1784 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
1787 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1788 Status
= AtaNonDataCommandIn (
1792 ATA_SMART_ENABLE_OPERATION
,
1799 // Detect if this feature is enabled
1801 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
1803 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
1804 Status
= AtaPioDataIn (
1806 (VOID
*) TmpAtaIdentifyPointer
,
1807 sizeof (EFI_IDENTIFY_DATA
),
1815 if (EFI_ERROR (Status
)) {
1816 gBS
->FreePool (TmpAtaIdentifyPointer
);
1821 // Check if the feature is enabled
1823 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
1827 AtaNonDataCommandIn (
1831 ATA_SMART_RETURN_STATUS
,
1837 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
1838 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
1840 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
1842 // The threshold exceeded condition is not detected by the device
1844 REPORT_STATUS_CODE (
1846 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
1849 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
1851 // The threshold exceeded condition is detected by the device
1853 REPORT_STATUS_CODE (
1855 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
1861 // Report disabled status code
1863 REPORT_STATUS_CODE (
1864 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1865 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
1869 gBS
->FreePool (TmpAtaIdentifyPointer
);
1876 Send ATA Ext command into device with NON_DATA protocol
1878 @param IdeDev Standard IDE device private data structure
1879 @param AtaCommand The ATA command to be sent
1880 @param Device The value in Device register
1881 @param Feature The value in Feature register
1882 @param SectorCount The value in SectorCount register
1883 @param LbaAddress The LBA address in 48-bit mode
1885 @retval EFI_SUCCESS Reading succeed
1886 @retval EFI_DEVICE_ERROR Error executing commands on this device
1890 AtaCommandIssueExt (
1891 IN IDE_BLK_IO_DEV
*IdeDev
,
1892 IN UINT8 AtaCommand
,
1895 IN UINT16 SectorCount
,
1896 IN EFI_LBA LbaAddress
1906 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1907 if (EFI_ERROR (Status
)) {
1908 return EFI_DEVICE_ERROR
;
1912 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1916 IdeDev
->IoPort
->Head
,
1917 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1921 // ATA commands for ATA device must be issued when DRDY is set
1923 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1924 if (EFI_ERROR (Status
)) {
1925 return EFI_DEVICE_ERROR
;
1929 // Pass parameter into device register block
1931 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1934 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1936 Feature8
= (UINT8
) (Feature
>> 8);
1937 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1939 Feature8
= (UINT8
) Feature
;
1940 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1943 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1945 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1946 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1948 SectorCount8
= (UINT8
) SectorCount
;
1949 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1952 // Fill the start LBA registers, which are also two-byte FIFO
1954 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1955 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1956 LbaLow
= (UINT8
) LbaAddress
;
1957 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1959 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1960 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1961 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1962 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1964 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1965 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1966 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1967 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1970 // Work around for Segate 160G disk writing
1975 // Send command via Command Register
1977 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1980 // Stall at least 400ns
1988 Send ATA Ext command into device with NON_DATA protocol
1990 @param IdeDev Standard IDE device private data structure
1991 @param AtaCommand The ATA command to be sent
1992 @param Device The value in Device register
1993 @param Feature The value in Feature register
1994 @param SectorCount The value in SectorCount register
1995 @param LbaAddress The LBA address in 48-bit mode
1997 @retval EFI_SUCCESS Reading succeed
1998 @retval EFI_DEVICE_ERROR Error executing commands on this device
2003 IN IDE_BLK_IO_DEV
*IdeDev
,
2004 IN UINT8 AtaCommand
,
2007 IN UINT16 SectorCount
,
2008 IN EFI_LBA LbaAddress
2019 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2020 if (EFI_ERROR (Status
)) {
2021 return EFI_DEVICE_ERROR
;
2025 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2029 IdeDev
->IoPort
->Head
,
2030 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2034 // ATA commands for ATA device must be issued when DRDY is set
2036 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2037 if (EFI_ERROR (Status
)) {
2038 return EFI_DEVICE_ERROR
;
2041 Lba0
= (UINT8
) LbaAddress
;
2042 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2043 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2044 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2045 Device
= (UINT8
) (Device
| Lba3
);
2048 // Pass parameter into device register block
2050 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2053 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2055 Feature8
= (UINT8
) Feature
;
2056 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2059 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2061 SectorCount8
= (UINT8
) SectorCount
;
2062 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2065 // Fill the start LBA registers, which are also two-byte FIFO
2068 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
2069 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
2070 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
2073 // Send command via Command Register
2075 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2078 // Stall at least 400ns
2086 This function is called by the AtaBlkIoReadBlocks() to perform
2087 reading from media in block unit. The function has been enhanced to
2088 support >120GB access and transfer at most 65536 blocks per command
2090 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2091 to record all the information of the IDE device.
2093 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2095 @param[in] StartLba The starting logical block address to read from
2096 on the device media.
2098 @param[in] NumberOfBlocks The number of transfer data blocks.
2100 @return The device status of UDMA operation. If the operation is
2101 successful, return EFI_SUCCESS.
2103 TODO: EFI_UNSUPPORTED - add return value to function comment
2104 TODO: EFI_DEVICE_ERROR - add return value to function comment
2105 TODO: EFI_DEVICE_ERROR - add return value to function comment
2106 TODO: EFI_DEVICE_ERROR - add return value to function comment
2110 IN IDE_BLK_IO_DEV
*IdeDev
,
2111 IN VOID
*DataBuffer
,
2112 IN EFI_LBA StartLba
,
2113 IN UINTN NumberOfBlocks
2116 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadExtOp
);
2120 This function is called by the AtaBlkIoReadBlocks() to perform
2121 reading from media in block unit. The function has been enhanced to
2122 support >120GB access and transfer at most 65536 blocks per command
2125 pointer pointing to IDE_BLK_IO_DEV data structure, used
2126 to record all the information of the IDE device.
2128 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2129 @param[in] StartLba The starting logical block address to read from
2130 on the device media.
2131 @param[in] NumberOfBlocks The number of transfer data blocks.
2133 @return The device status of UDMA operation. If the operation is
2134 successful, return EFI_SUCCESS.
2136 TODO: EFI_UNSUPPORTED - add return value to function comment
2137 TODO: EFI_DEVICE_ERROR - add return value to function comment
2138 TODO: EFI_DEVICE_ERROR - add return value to function comment
2139 TODO: EFI_DEVICE_ERROR - add return value to function comment
2143 IN IDE_BLK_IO_DEV
*IdeDev
,
2144 IN VOID
*DataBuffer
,
2145 IN EFI_LBA StartLba
,
2146 IN UINTN NumberOfBlocks
2149 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadOp
);
2153 This function is called by the AtaBlkIoWriteBlocks() to perform
2154 writing to media in block unit. The function has been enhanced to
2155 support >120GB access and transfer at most 65536 blocks per command
2157 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2158 to record all the information of the IDE device.
2160 @param[in] *DataBuffer A pointer to the source buffer for the data.
2162 @param[in] StartLba The starting logical block address to write to
2163 on the device media.
2165 @param[in] NumberOfBlocks The number of transfer data blocks.
2167 @return The device status of UDMA operation. If the operation is
2168 successful, return EFI_SUCCESS.
2170 TODO: EFI_UNSUPPORTED - add return value to function comment
2171 TODO: EFI_DEVICE_ERROR - add return value to function comment
2172 TODO: EFI_DEVICE_ERROR - add return value to function comment
2176 IN IDE_BLK_IO_DEV
*IdeDev
,
2177 IN VOID
*DataBuffer
,
2178 IN EFI_LBA StartLba
,
2179 IN UINTN NumberOfBlocks
2182 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteExtOp
);
2186 This function is called by the AtaBlkIoWriteBlocks() to perform
2187 writing to media in block unit. The function has been enhanced to
2188 support >120GB access and transfer at most 65536 blocks per command
2191 pointer pointing to IDE_BLK_IO_DEV data structure, used
2192 to record all the information of the IDE device.
2194 @param[in] *DataBuffer
2195 A pointer to the source buffer for the data.
2198 The starting logical block address to write to
2199 on the device media.
2201 @param[in] NumberOfBlocks
2202 The number of transfer data blocks.
2204 @return The device status of UDMA operation. If the operation is
2205 successful, return EFI_SUCCESS.
2207 TODO: EFI_UNSUPPORTED - add return value to function comment
2208 TODO: EFI_DEVICE_ERROR - add return value to function comment
2209 TODO: EFI_DEVICE_ERROR - add return value to function comment
2213 IN IDE_BLK_IO_DEV
*IdeDev
,
2214 IN VOID
*DataBuffer
,
2215 IN EFI_LBA StartLba
,
2216 IN UINTN NumberOfBlocks
2219 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteOp
);
2223 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
2226 pointer pointing to IDE_BLK_IO_DEV data structure, used
2227 to record all the information of the IDE device.
2229 @param[in] *DataBuffer
2230 A pointer to the source buffer for the data.
2233 The starting logical block address to write to
2234 on the device media.
2236 @param[in] NumberOfBlocks
2237 The number of transfer data blocks.
2240 The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
2241 AtaUdmaWriteOp, AtaUdmaWriteExOp
2243 @return The device status of UDMA operation. If the operation is
2244 successful, return EFI_SUCCESS.
2249 IN IDE_BLK_IO_DEV
*IdeDev
,
2250 IN VOID
*DataBuffer
,
2251 IN EFI_LBA StartLba
,
2252 IN UINTN NumberOfBlocks
,
2253 IN ATA_UDMA_OPERATION UdmaOp
2256 IDE_DMA_PRD
*PrdAddr
;
2257 IDE_DMA_PRD
*UsedPrdAddr
;
2258 IDE_DMA_PRD
*TempPrdAddr
;
2259 UINT8 RegisterValue
;
2261 UINT64 IoPortForBmic
;
2262 UINT64 IoPortForBmis
;
2263 UINT64 IoPortForBmid
;
2267 UINTN ByteAvailable
;
2269 UINTN RemainBlockNum
;
2270 UINT8 DeviceControl
;
2275 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2276 UINTN MaxDmaCommandSectors
;
2277 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp
;
2282 MaxDmaCommandSectors
= MAX_DMA_COMMAND_SECTORS
;
2283 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2284 AtaCommand
= READ_DMA_CMD
;
2286 case AtaUdmaReadExtOp
:
2287 MaxDmaCommandSectors
= MAX_DMA_EXT_COMMAND_SECTORS
;
2288 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2289 AtaCommand
= READ_DMA_EXT_CMD
;
2291 case AtaUdmaWriteOp
:
2292 MaxDmaCommandSectors
= MAX_DMA_COMMAND_SECTORS
;
2293 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2294 AtaCommand
= WRITE_DMA_CMD
;
2296 case AtaUdmaWriteExtOp
:
2297 MaxDmaCommandSectors
= MAX_DMA_EXT_COMMAND_SECTORS
;
2298 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2299 AtaCommand
= WRITE_DMA_EXT_CMD
;
2302 return EFI_UNSUPPORTED
;
2307 // Channel and device differential
2309 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2312 // Enable interrupt to support UDMA and Select device
2315 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2317 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2319 if (IdePrimary
== IdeDev
->Channel
) {
2320 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2321 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2322 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2324 if (IdeSecondary
== IdeDev
->Channel
) {
2325 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2326 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2327 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2329 return EFI_UNSUPPORTED
;
2333 RemainBlockNum
= NumberOfBlocks
;
2334 while (RemainBlockNum
> 0) {
2336 if (RemainBlockNum
>= MaxDmaCommandSectors
) {
2338 // SectorCount is used to record the number of sectors to be read
2339 // Max 65536 sectors can be transfered at a time.
2341 NumberOfBlocks
= MaxDmaCommandSectors
;
2342 RemainBlockNum
-= MaxDmaCommandSectors
;
2344 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2349 // Calculate the number of PRD table to make sure the memory region
2350 // not cross 64K boundary
2352 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2353 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2358 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2359 Status
= IdeDev
->PciIo
->AllocateBuffer (
2362 EfiBootServicesData
,
2367 if (EFI_ERROR (Status
)) {
2368 return EFI_OUT_OF_RESOURCES
;
2370 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2372 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2374 // To make sure PRD is allocated in one 64K page
2376 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2377 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2379 if ((UINTN
) PrdAddr
& 0x03) {
2380 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2382 UsedPrdAddr
= PrdAddr
;
2387 // Build the PRD table
2389 Status
= IdeDev
->PciIo
->Map (
2397 if (EFI_ERROR (Status
)) {
2398 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2399 return EFI_OUT_OF_RESOURCES
;
2401 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
2402 TempPrdAddr
= UsedPrdAddr
;
2405 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2407 if (ByteCount
<= ByteAvailable
) {
2408 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2409 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2410 TempPrdAddr
->EndOfTable
= 0x8000;
2414 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2415 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2417 ByteCount
-= ByteAvailable
;
2418 PrdBuffer
+= ByteAvailable
;
2423 // Set the base address to BMID register
2425 IdeDev
->PciIo
->Io
.Write (
2427 EfiPciIoWidthUint32
,
2428 EFI_PCI_IO_PASS_THROUGH_BAR
,
2435 // Set BMIC register to identify the operation direction
2437 IdeDev
->PciIo
->Io
.Read (
2440 EFI_PCI_IO_PASS_THROUGH_BAR
,
2446 if (UdmaOp
== AtaUdmaReadExtOp
|| UdmaOp
== AtaUdmaReadOp
) {
2447 RegisterValue
|= BMIC_nREAD
;
2449 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
2452 IdeDev
->PciIo
->Io
.Write (
2455 EFI_PCI_IO_PASS_THROUGH_BAR
,
2462 // Read BMIS register and clear ERROR and INTR bit
2464 IdeDev
->PciIo
->Io
.Read (
2467 EFI_PCI_IO_PASS_THROUGH_BAR
,
2473 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2475 IdeDev
->PciIo
->Io
.Write (
2478 EFI_PCI_IO_PASS_THROUGH_BAR
,
2484 if (UdmaOp
== AtaUdmaWriteExtOp
|| UdmaOp
== AtaUdmaReadExtOp
) {
2485 Status
= AtaCommandIssueExt (
2490 (UINT16
) NumberOfBlocks
,
2494 Status
= AtaCommandIssue (
2499 (UINT16
) NumberOfBlocks
,
2504 if (EFI_ERROR (Status
)) {
2505 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2506 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2507 return EFI_DEVICE_ERROR
;
2511 // Set START bit of BMIC register
2513 IdeDev
->PciIo
->Io
.Read (
2516 EFI_PCI_IO_PASS_THROUGH_BAR
,
2522 RegisterValue
|= BMIC_START
;
2524 IdeDev
->PciIo
->Io
.Write (
2527 EFI_PCI_IO_PASS_THROUGH_BAR
,
2534 // Check the INTERRUPT and ERROR bit of BMIS
2535 // Max transfer number of sectors for one command is 65536(32Mbyte),
2536 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
2537 // So set the variable Count to 2000, for about 2 second timeout time.
2542 IdeDev
->PciIo
->Io
.Read (
2545 EFI_PCI_IO_PASS_THROUGH_BAR
,
2550 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
2551 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
2553 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
2555 IdeDev
->PciIo
->Io
.Read (
2558 EFI_PCI_IO_PASS_THROUGH_BAR
,
2564 RegisterValue
&= ~((UINT8
)BMIC_START
);
2566 IdeDev
->PciIo
->Io
.Write (
2569 EFI_PCI_IO_PASS_THROUGH_BAR
,
2574 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2575 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2576 return EFI_DEVICE_ERROR
;
2585 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2586 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2588 // Read Status Register of IDE device to clear interrupt
2590 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
2592 // Clear START bit of BMIC register
2594 IdeDev
->PciIo
->Io
.Read (
2597 EFI_PCI_IO_PASS_THROUGH_BAR
,
2603 RegisterValue
&= ~((UINT8
) BMIC_START
);
2605 IdeDev
->PciIo
->Io
.Write (
2608 EFI_PCI_IO_PASS_THROUGH_BAR
,
2614 if (RegisterValue
& BMIS_ERROR
) {
2615 return EFI_DEVICE_ERROR
;
2618 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2619 StartLba
+= NumberOfBlocks
;
2623 // Disable interrupt of Select device
2625 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
2626 DeviceControl
|= IEN_L
;
2627 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);