2 Copyright (c) 2006 - 2007 Intel Corporation. <BR>
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 @par Revision Reference:
12 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
13 update - ATAIdentity() func
14 update - AtaBlockIoReadBlocks() func
15 update - AtaBlockIoWriteBlocks() func
16 add - AtaAtapi6Identify() func
17 add - AtaReadSectorsExt() func
18 add - AtaWriteSectorsExt() func
19 add - AtaPioDataInExt() func
20 add - AtaPioDataOutExt() func
27 Sends out an ATA Identify Command to the specified device.
29 This function is called by DiscoverIdeDevice() during its device
30 identification. It sends out the ATA Identify Command to the
31 specified device. Only ATA device responses to this command. If
32 the command succeeds, it returns the Identify data structure which
33 contains information about the device. This function extracts the
34 information it needs to fill the IDE_BLK_IO_DEV data structure,
35 including device type, media block size, media capacity, and etc.
38 pointer pointing to IDE_BLK_IO_DEV data structure,used
39 to record all the information of the IDE device.
41 @retval EFI_SUCCESS Identify ATA device successfully.
43 @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or
44 device is not ATA device.
47 parameter IdeDev will be updated in this function.
52 IN IDE_BLK_IO_DEV
*IdeDev
56 EFI_IDENTIFY_DATA
*AtaIdentifyPointer
;
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
;
599 StatusRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Status
);
603 if (StatusRegister
& DWF
) {
606 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
611 if (StatusRegister
& CORR
) {
614 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
619 if (StatusRegister
& ERR
) {
620 ErrorRegister
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Error
);
622 if (ErrorRegister
& BBK_ERR
) {
625 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
630 if (ErrorRegister
& UNC_ERR
) {
633 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
638 if (ErrorRegister
& MC_ERR
) {
641 "CheckErrorStatus()-- %02x : Error : Media Change\n",
646 if (ErrorRegister
& ABRT_ERR
) {
649 "CheckErrorStatus()-- %02x : Error : Abort\n",
654 if (ErrorRegister
& TK0NF_ERR
) {
657 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
662 if (ErrorRegister
& AMNF_ERR
) {
665 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
673 if ((StatusRegister
& (ERR
| DWF
| CORR
)) == 0) {
677 return EFI_DEVICE_ERROR
;
682 This function is called by the AtaBlkIoReadBlocks() to perform
683 reading from media in block unit.
686 pointer pointing to IDE_BLK_IO_DEV data structure, used
687 to record all the information of the IDE device.
689 @param[in] *DataBuffer
690 A pointer to the destination buffer for the data.
693 The starting logical block address to read from
696 @param[in] NumberOfBlocks
697 The number of transfer data blocks.
699 @return return status is fully dependent on the return status
700 of AtaPioDataIn() function.
705 IN IDE_BLK_IO_DEV
*IdeDev
,
708 IN UINTN NumberOfBlocks
712 UINTN BlocksRemaining
;
727 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
729 AtaCommand
= READ_SECTORS_CMD
;
732 BlocksRemaining
= NumberOfBlocks
;
734 Lba32
= (UINT32
) Lba
;
736 Status
= EFI_SUCCESS
;
738 while (BlocksRemaining
> 0) {
741 // in ATA-3 spec, LBA is in 28 bit width
743 Lba0
= (UINT8
) Lba32
;
744 Lba1
= (UINT8
) (Lba32
>> 8);
745 Lba2
= (UINT8
) (Lba32
>> 16);
747 // low 4 bit of Lba3 stands for LBA bit24~bit27.
749 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
751 if (BlocksRemaining
>= 0x100) {
754 // SectorCount8 is sent to Sector Count register, 0x00 means 256
755 // sectors to be read
759 // SectorCount is used to record the number of sectors to be read
764 SectorCount8
= (UINT8
) BlocksRemaining
;
765 SectorCount
= (UINT16
) BlocksRemaining
;
769 // ByteCount is the number of bytes that will be read
771 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
774 // call AtaPioDataIn() to send Read Sector Command and receive data read
776 Status
= AtaPioDataIn (
787 if (EFI_ERROR (Status
)) {
791 Lba32
+= SectorCount
;
792 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
793 BlocksRemaining
-= SectorCount
;
800 This function is called by the AtaBlkIoWriteBlocks() to perform
801 writing onto media in block unit.
804 pointer pointing to IDE_BLK_IO_DEV data structure,used
805 to record all the information of the IDE device.
807 @param[in] *BufferData
808 A pointer to the source buffer for the data.
811 The starting logical block address to write onto
814 @param[in] NumberOfBlocks
815 The number of transfer data blocks.
817 @return return status is fully dependent on the return status
818 of AtaPioDataOut() function.
823 IN IDE_BLK_IO_DEV
*IdeDev
,
826 IN UINTN NumberOfBlocks
830 UINTN BlocksRemaining
;
845 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
847 AtaCommand
= WRITE_SECTORS_CMD
;
849 BlocksRemaining
= NumberOfBlocks
;
851 Lba32
= (UINT32
) Lba
;
853 Status
= EFI_SUCCESS
;
855 while (BlocksRemaining
> 0) {
857 Lba0
= (UINT8
) Lba32
;
858 Lba1
= (UINT8
) (Lba32
>> 8);
859 Lba2
= (UINT8
) (Lba32
>> 16);
860 Lba3
= (UINT8
) ((Lba32
>> 24) & 0x0f);
862 if (BlocksRemaining
>= 0x100) {
865 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
870 // SectorCount is used to record the number of sectors to be written
875 SectorCount8
= (UINT8
) BlocksRemaining
;
876 SectorCount
= (UINT16
) BlocksRemaining
;
879 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
881 Status
= AtaPioDataOut (
892 if (EFI_ERROR (Status
)) {
896 Lba32
+= SectorCount
;
897 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
898 BlocksRemaining
-= SectorCount
;
905 This function is used to implement the Soft Reset on the specified
906 device. But, the ATA Soft Reset mechanism is so strong a reset method
907 that it will force resetting on both devices connected to the
910 It is called by IdeBlkIoReset(), a interface function of Block
913 This function can also be used by the ATAPI device to perform reset when
914 ATAPI Reset command is failed.
917 pointer pointing to IDE_BLK_IO_DEV data structure, used
918 to record all the information of the IDE device.
920 @retval EFI_SUCCESS Soft reset completes successfully.
921 @retval EFI_DEVICE_ERROR Any step during the reset process is failed.
924 The registers initial values after ATA soft reset are different
925 to the ATA device and ATAPI device.
930 IN IDE_BLK_IO_DEV
*IdeDev
938 // set SRST bit to initiate soft reset
940 DeviceControl
|= SRST
;
945 DeviceControl
|= bit1
;
947 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
950 // SRST should assert for at least 5 us, we use 10 us for
951 // better compatibility
956 // Enable interrupt to support UDMA, and clear SRST bit
959 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
962 // Wait for at least 2 ms to check BSY status, we use 10 ms
963 // for better compatibility
967 // slave device needs at most 31s to clear BSY
969 if (WaitForBSYClear (IdeDev
, 31000) == EFI_TIMEOUT
) {
970 return EFI_DEVICE_ERROR
;
977 This function is the ATA implementation for ReadBlocks in the
978 Block I/O Protocol interface.
980 @param[in] *IdeBlkIoDevice
981 Indicates the calling context.
984 The media id that the read request is for.
987 The starting logical block address to read from
990 @param[in] BufferSize
991 The size of the Buffer in bytes. This must be a
992 multiple of the intrinsic block size of the device.
995 A pointer to the destination buffer for the data.
996 The caller is responsible for either having implicit
997 or explicit ownership of the memory that data is read into.
999 @retval EFI_SUCCESS Read Blocks successfully.
1000 @retval EFI_DEVICE_ERROR Read Blocks failed.
1001 @retval EFI_NO_MEDIA There is no media in the device.
1002 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1004 @retval EFI_BAD_BUFFER_SIZE
1005 The BufferSize parameter is not a multiple of the
1006 intrinsic block size of the device.
1008 @retval EFI_INVALID_PARAMETER
1009 The read request contains LBAs that are not valid,
1010 or the data buffer is not valid.
1013 If Read Block error because of device error, this function will call
1014 AtaSoftReset() function to reset device.
1018 AtaBlkIoReadBlocks (
1019 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1022 IN UINTN BufferSize
,
1026 EFI_BLOCK_IO_MEDIA
*Media
;
1028 UINTN NumberOfBlocks
;
1031 if (Buffer
== NULL
) {
1032 return EFI_INVALID_PARAMETER
;
1035 if (BufferSize
== 0) {
1039 Status
= EFI_SUCCESS
;
1042 // Get the intrinsic block size
1044 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1045 BlockSize
= Media
->BlockSize
;
1047 NumberOfBlocks
= BufferSize
/ BlockSize
;
1049 if (MediaId
!= Media
->MediaId
) {
1050 return EFI_MEDIA_CHANGED
;
1053 if (BufferSize
% BlockSize
!= 0) {
1054 return EFI_BAD_BUFFER_SIZE
;
1057 if (!(Media
->MediaPresent
)) {
1058 return EFI_NO_MEDIA
;
1061 if (LBA
> Media
->LastBlock
) {
1062 return EFI_INVALID_PARAMETER
;
1065 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1066 return EFI_INVALID_PARAMETER
;
1069 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1070 return EFI_INVALID_PARAMETER
;
1073 Status
= EFI_SUCCESS
;
1074 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1076 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1078 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1079 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1081 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1085 // For ATA-3 compatible device, use ATA-3 read block mechanism
1087 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1088 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1090 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1094 if (EFI_ERROR (Status
)) {
1095 AtaSoftReset (IdeBlkIoDevice
);
1096 return EFI_DEVICE_ERROR
;
1104 This function is the ATA implementation for WriteBlocks in the
1105 Block I/O Protocol interface.
1107 @param[in] *IdeBlkIoDevice
1108 Indicates the calling context.
1111 The media id that the write request is for.
1114 The starting logical block address to write onto
1117 @param[in] BufferSize
1118 The size of the Buffer in bytes. This must be a
1119 multiple of the intrinsic block size of the device.
1122 A pointer to the source buffer for the data.
1123 The caller is responsible for either having implicit
1124 or explicit ownership of the memory that data is
1127 @retval EFI_SUCCESS Write Blocks successfully.
1128 @retval EFI_DEVICE_ERROR Write Blocks failed.
1129 @retval EFI_NO_MEDIA There is no media in the device.
1130 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1132 @retval EFI_BAD_BUFFER_SIZE
1133 The BufferSize parameter is not a multiple of the
1134 intrinsic block size of the device.
1136 @retval EFI_INVALID_PARAMETER
1137 The write request contains LBAs that are not valid,
1138 or the data buffer is not valid.
1141 If Write Block error because of device error, this function will call
1142 AtaSoftReset() function to reset device.
1146 AtaBlkIoWriteBlocks (
1147 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1150 IN UINTN BufferSize
,
1155 EFI_BLOCK_IO_MEDIA
*Media
;
1157 UINTN NumberOfBlocks
;
1160 if (Buffer
== NULL
) {
1161 return EFI_INVALID_PARAMETER
;
1164 if (BufferSize
== 0) {
1168 Status
= EFI_SUCCESS
;
1171 // Get the intrinsic block size
1173 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1174 BlockSize
= Media
->BlockSize
;
1175 NumberOfBlocks
= BufferSize
/ BlockSize
;
1177 if (MediaId
!= Media
->MediaId
) {
1178 return EFI_MEDIA_CHANGED
;
1181 if (BufferSize
% BlockSize
!= 0) {
1182 return EFI_BAD_BUFFER_SIZE
;
1185 if (LBA
> Media
->LastBlock
) {
1186 return EFI_INVALID_PARAMETER
;
1189 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1190 return EFI_INVALID_PARAMETER
;
1193 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1194 return EFI_INVALID_PARAMETER
;
1197 Status
= EFI_SUCCESS
;
1198 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1200 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1202 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1203 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1205 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1209 // For ATA-3 compatible device, use ATA-3 write block mechanism
1211 if (IdeBlkIoDevice
->UdmaMode
.Valid
) {
1212 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1214 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1218 if (EFI_ERROR (Status
)) {
1219 AtaSoftReset (IdeBlkIoDevice
);
1220 return EFI_DEVICE_ERROR
;
1227 This function is called by the AtaBlkIoReadBlocks() to perform
1228 reading from media in block unit. The function has been enhanced to
1229 support >120GB access and transfer at most 65536 blocks per command
1232 pointer pointing to IDE_BLK_IO_DEV data structure, used
1233 to record all the information of the IDE device.
1235 @param[in] *DataBuffer A pointer to the destination buffer for the data.
1236 @param[in] StartLba The starting logical block address to read from
1237 on the device media.
1238 @param[in] NumberOfBlocks The number of transfer data blocks.
1240 @return return status is fully dependent on the return status
1241 of AtaPioDataInExt() function.
1246 IN IDE_BLK_IO_DEV
*IdeDev
,
1247 IN VOID
*DataBuffer
,
1248 IN EFI_LBA StartLba
,
1249 IN UINTN NumberOfBlocks
1253 UINTN BlocksRemaining
;
1261 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1263 AtaCommand
= READ_SECTORS_EXT_CMD
;
1264 Buffer
= DataBuffer
;
1265 BlocksRemaining
= NumberOfBlocks
;
1267 Status
= EFI_SUCCESS
;
1269 while (BlocksRemaining
> 0) {
1271 if (BlocksRemaining
>= 0x10000) {
1273 // SectorCount is used to record the number of sectors to be read
1274 // Max 65536 sectors can be transfered at a time.
1276 SectorCount
= 0xffff;
1278 SectorCount
= (UINT16
) BlocksRemaining
;
1282 // ByteCount is the number of bytes that will be read
1284 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1287 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1289 Status
= AtaPioDataInExt (
1297 if (EFI_ERROR (Status
)) {
1301 Lba64
+= SectorCount
;
1302 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1303 BlocksRemaining
-= SectorCount
;
1310 This function is called by the AtaBlkIoWriteBlocks() to perform
1311 writing onto media in block unit. The function has been enhanced to
1312 support >120GB access and transfer at most 65536 blocks per command
1315 pointer pointing to IDE_BLK_IO_DEV data structure,used
1316 to record all the information of the IDE device.
1318 @param[in] *DataBuffer
1319 A pointer to the source buffer for the data.
1322 The starting logical block address to write onto
1325 @param[in] NumberOfBlocks
1326 The number of transfer data blocks.
1328 @return status is fully dependent on the return status
1329 of AtaPioDataOutExt() function.
1333 AtaWriteSectorsExt (
1334 IN IDE_BLK_IO_DEV
*IdeDev
,
1335 IN VOID
*DataBuffer
,
1336 IN EFI_LBA StartLba
,
1337 IN UINTN NumberOfBlocks
1342 UINTN BlocksRemaining
;
1349 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1351 AtaCommand
= WRITE_SECTORS_EXT_CMD
;
1353 Buffer
= DataBuffer
;
1354 BlocksRemaining
= NumberOfBlocks
;
1356 Status
= EFI_SUCCESS
;
1358 while (BlocksRemaining
> 0) {
1360 if (BlocksRemaining
>= 0x10000) {
1362 // SectorCount is used to record the number of sectors to be written.
1363 // Max 65536 sectors can be transfered at a time.
1365 SectorCount
= 0xffff;
1367 SectorCount
= (UINT16
) BlocksRemaining
;
1371 // ByteCount is the number of bytes that will be written
1373 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1376 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1378 Status
= AtaPioDataOutExt (
1386 if (EFI_ERROR (Status
)) {
1390 Lba64
+= SectorCount
;
1391 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1392 BlocksRemaining
-= SectorCount
;
1399 This function is used to send out ATA commands conforms to the
1400 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1402 Comparing with ATA-3 data in protocol, we have two differents here:<BR>
1403 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1404 wait will frequently fail... cause writing function return error)
1406 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1407 slow down writing performance by 100 times!)
1409 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1410 to record all the information of the IDE device.
1412 @param[in,out] *Buffer buffer contained data transferred from device to host.
1413 @param[in] ByteCount data size in byte unit of the buffer.
1414 @param[in] AtaCommand value of the Command Register
1415 @param[in] StartLba the start LBA of this transaction
1416 @param[in] SectorCount the count of sectors to be transfered
1418 @retval EFI_SUCCESS send out the ATA command and device send required
1421 @retval EFI_DEVICE_ERROR command sent failed.
1426 IN IDE_BLK_IO_DEV
*IdeDev
,
1427 IN OUT VOID
*Buffer
,
1428 IN UINT32 ByteCount
,
1429 IN UINT8 AtaCommand
,
1430 IN EFI_LBA StartLba
,
1431 IN UINT16 SectorCount
1444 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1445 if (EFI_ERROR (Status
)) {
1446 return EFI_DEVICE_ERROR
;
1450 // Select device, set bit6 as 1 to indicate LBA mode is used
1452 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1456 IdeDev
->IoPort
->Head
,
1461 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1463 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1464 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1466 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1467 if (EFI_ERROR (Status
)) {
1468 return EFI_DEVICE_ERROR
;
1473 // Fill feature register if needed
1475 if (AtaCommand
== SET_FEATURES_CMD
) {
1476 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1480 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1482 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1483 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1485 SectorCount8
= (UINT8
) SectorCount
;
1486 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1489 // Fill the start LBA registers, which are also two-byte FIFO
1491 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1492 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1493 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1494 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1495 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1496 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1498 LbaLow
= (UINT8
) StartLba
;
1499 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1500 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1501 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1502 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1503 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1506 // Send command via Command Register, invoking the processing of this command
1508 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1510 Buffer16
= (UINT16
*) Buffer
;
1513 // According to PIO data in protocol, host can perform a series of reads to
1514 // the data register after each time device set DRQ ready;
1523 // used to record bytes of currently transfered data
1527 while (WordCount
< ByteCount
/ 2) {
1529 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1531 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1532 if (EFI_ERROR (Status
)) {
1533 return EFI_DEVICE_ERROR
;
1536 Status
= CheckErrorStatus (IdeDev
);
1537 if (EFI_ERROR (Status
)) {
1538 return EFI_DEVICE_ERROR
;
1542 // Get the byte count for one series of read
1544 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1545 Increment
= ByteCount
/ 2 - WordCount
;
1548 IDEReadPortWMultiple (
1550 IdeDev
->IoPort
->Data
,
1555 WordCount
+= Increment
;
1556 Buffer16
+= Increment
;
1560 return CheckErrorStatus (IdeDev
);
1564 This function is used to send out ATA commands conforms to the
1565 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1567 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
1568 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1569 wait will frequently fail... cause writing function return error)
1571 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1572 slow down writing performance by 100 times!)
1575 pointer pointing to IDE_BLK_IO_DEV data structure, used
1576 to record all the information of the IDE device.
1578 @param[in] *Buffer buffer contained data transferred from host to device.
1579 @param[in] ByteCount data size in byte unit of the buffer.
1580 @param[in] AtaCommand value of the Command Register
1581 @param[in] StartLba the start LBA of this transaction
1582 @param[in] SectorCount the count of sectors to be transfered
1584 @retval EFI_SUCCESS send out the ATA command and device receive required
1587 @retval EFI_DEVICE_ERROR command sent failed.
1592 IN IDE_BLK_IO_DEV
*IdeDev
,
1594 IN UINT32 ByteCount
,
1595 IN UINT8 AtaCommand
,
1596 IN EFI_LBA StartLba
,
1597 IN UINT16 SectorCount
1610 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1611 if (EFI_ERROR (Status
)) {
1612 return EFI_DEVICE_ERROR
;
1616 // Select device. Set bit6 as 1 to indicate LBA mode is used
1618 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1622 IdeDev
->IoPort
->Head
,
1627 // Wait for DRDY singnal asserting.
1629 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1630 if (EFI_ERROR (Status
)) {
1631 return EFI_DEVICE_ERROR
;
1635 // Fill feature register if needed
1637 if (AtaCommand
== SET_FEATURES_CMD
) {
1638 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1642 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1644 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1645 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1647 SectorCount8
= (UINT8
) SectorCount
;
1648 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1651 // Fill the start LBA registers, which are also two-byte FIFO
1653 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1654 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1655 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1656 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1657 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1658 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1660 LbaLow
= (UINT8
) StartLba
;
1661 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1662 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1663 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1664 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1665 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1668 // Send command via Command Register, invoking the processing of this command
1670 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1672 Buffer16
= (UINT16
*) Buffer
;
1675 // According to PIO Data Out protocol, host can perform a series of writes to
1676 // the data register after each time device set DRQ ready;
1681 // used to record bytes of currently transfered data
1685 while (WordCount
< ByteCount
/ 2) {
1687 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1689 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1690 if (EFI_ERROR (Status
)) {
1691 return EFI_DEVICE_ERROR
;
1694 Status
= CheckErrorStatus (IdeDev
);
1695 if (EFI_ERROR (Status
)) {
1696 return EFI_DEVICE_ERROR
;
1700 // Write data into device by one series of writing to data register
1702 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1703 Increment
= ByteCount
/ 2 - WordCount
;
1706 IDEWritePortWMultiple (
1708 IdeDev
->IoPort
->Data
,
1713 WordCount
+= Increment
;
1714 Buffer16
+= Increment
;
1721 return CheckErrorStatus (IdeDev
);
1726 Enable SMART of the disk if supported
1729 pointer pointing to IDE_BLK_IO_DEV data structure,used
1730 to record all the information of the IDE device.
1735 IN IDE_BLK_IO_DEV
*IdeDev
1739 BOOLEAN SMARTSupported
;
1741 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
1747 // Detect if the device supports S.M.A.R.T.
1749 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
1751 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
1755 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
1757 // S.M.A.R.T is not supported by the device
1759 SMARTSupported
= FALSE
;
1761 SMARTSupported
= TRUE
;
1765 if (!SMARTSupported
) {
1767 // Report nonsupport status code
1769 REPORT_STATUS_CODE (
1770 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1771 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
1775 // Enable this feature
1777 REPORT_STATUS_CODE (
1779 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
1782 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1783 Status
= AtaNonDataCommandIn (
1787 ATA_SMART_ENABLE_OPERATION
,
1794 // Detect if this feature is enabled
1796 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
1798 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
1799 Status
= AtaPioDataIn (
1801 (VOID
*) TmpAtaIdentifyPointer
,
1802 sizeof (EFI_IDENTIFY_DATA
),
1810 if (EFI_ERROR (Status
)) {
1811 gBS
->FreePool (TmpAtaIdentifyPointer
);
1816 // Check if the feature is enabled
1818 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
1822 AtaNonDataCommandIn (
1826 ATA_SMART_RETURN_STATUS
,
1832 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
1833 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
1835 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
1837 // The threshold exceeded condition is not detected by the device
1839 REPORT_STATUS_CODE (
1841 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
1844 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
1846 // The threshold exceeded condition is detected by the device
1848 REPORT_STATUS_CODE (
1850 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
1856 // Report disabled status code
1858 REPORT_STATUS_CODE (
1859 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1860 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
1864 gBS
->FreePool (TmpAtaIdentifyPointer
);
1871 Send ATA Ext command into device with NON_DATA protocol
1873 @param IdeDev Standard IDE device private data structure
1874 @param AtaCommand The ATA command to be sent
1875 @param Device The value in Device register
1876 @param Feature The value in Feature register
1877 @param SectorCount The value in SectorCount register
1878 @param LbaAddress The LBA address in 48-bit mode
1880 @retval EFI_SUCCESS Reading succeed
1881 @retval EFI_DEVICE_ERROR Error executing commands on this device
1885 AtaCommandIssueExt (
1886 IN IDE_BLK_IO_DEV
*IdeDev
,
1887 IN UINT8 AtaCommand
,
1890 IN UINT16 SectorCount
,
1891 IN EFI_LBA LbaAddress
1901 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1902 if (EFI_ERROR (Status
)) {
1903 return EFI_DEVICE_ERROR
;
1907 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1911 IdeDev
->IoPort
->Head
,
1912 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1916 // ATA commands for ATA device must be issued when DRDY is set
1918 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1919 if (EFI_ERROR (Status
)) {
1920 return EFI_DEVICE_ERROR
;
1924 // Pass parameter into device register block
1926 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1929 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1931 Feature8
= (UINT8
) (Feature
>> 8);
1932 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1934 Feature8
= (UINT8
) Feature
;
1935 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1938 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1940 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1941 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1943 SectorCount8
= (UINT8
) SectorCount
;
1944 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1947 // Fill the start LBA registers, which are also two-byte FIFO
1949 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1950 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1951 LbaLow
= (UINT8
) LbaAddress
;
1952 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1954 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1955 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1956 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1957 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1959 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1960 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1961 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1962 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1965 // Work around for Segate 160G disk writing
1970 // Send command via Command Register
1972 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1975 // Stall at least 400ns
1983 Send ATA Ext command into device with NON_DATA protocol
1985 @param IdeDev Standard IDE device private data structure
1986 @param AtaCommand The ATA command to be sent
1987 @param Device The value in Device register
1988 @param Feature The value in Feature register
1989 @param SectorCount The value in SectorCount register
1990 @param LbaAddress The LBA address in 48-bit mode
1992 @retval EFI_SUCCESS Reading succeed
1993 @retval EFI_DEVICE_ERROR Error executing commands on this device
1998 IN IDE_BLK_IO_DEV
*IdeDev
,
1999 IN UINT8 AtaCommand
,
2002 IN UINT16 SectorCount
,
2003 IN EFI_LBA LbaAddress
2014 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2015 if (EFI_ERROR (Status
)) {
2016 return EFI_DEVICE_ERROR
;
2020 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2024 IdeDev
->IoPort
->Head
,
2025 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2029 // ATA commands for ATA device must be issued when DRDY is set
2031 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2032 if (EFI_ERROR (Status
)) {
2033 return EFI_DEVICE_ERROR
;
2036 Lba0
= (UINT8
) LbaAddress
;
2037 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2038 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2039 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2040 Device
= (UINT8
) (Device
| Lba3
);
2043 // Pass parameter into device register block
2045 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2048 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2050 Feature8
= (UINT8
) Feature
;
2051 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2054 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2056 SectorCount8
= (UINT8
) SectorCount
;
2057 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2060 // Fill the start LBA registers, which are also two-byte FIFO
2063 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
2064 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
2065 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
2068 // Send command via Command Register
2070 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2073 // Stall at least 400ns
2081 This function is called by the AtaBlkIoReadBlocks() to perform
2082 reading from media in block unit. The function has been enhanced to
2083 support >120GB access and transfer at most 65536 blocks per command
2085 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2086 to record all the information of the IDE device.
2088 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2090 @param[in] StartLba The starting logical block address to read from
2091 on the device media.
2093 @param[in] NumberOfBlocks The number of transfer data blocks.
2095 @return The device status of UDMA operation. If the operation is
2096 successful, return EFI_SUCCESS.
2098 TODO: EFI_UNSUPPORTED - add return value to function comment
2099 TODO: EFI_DEVICE_ERROR - add return value to function comment
2100 TODO: EFI_DEVICE_ERROR - add return value to function comment
2101 TODO: EFI_DEVICE_ERROR - add return value to function comment
2105 IN IDE_BLK_IO_DEV
*IdeDev
,
2106 IN VOID
*DataBuffer
,
2107 IN EFI_LBA StartLba
,
2108 IN UINTN NumberOfBlocks
2111 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadExtOp
);
2115 This function is called by the AtaBlkIoReadBlocks() to perform
2116 reading from media in block unit. The function has been enhanced to
2117 support >120GB access and transfer at most 65536 blocks per command
2120 pointer pointing to IDE_BLK_IO_DEV data structure, used
2121 to record all the information of the IDE device.
2123 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2124 @param[in] StartLba The starting logical block address to read from
2125 on the device media.
2126 @param[in] NumberOfBlocks The number of transfer data blocks.
2128 @return The device status of UDMA operation. If the operation is
2129 successful, return EFI_SUCCESS.
2131 TODO: EFI_UNSUPPORTED - add return value to function comment
2132 TODO: EFI_DEVICE_ERROR - add return value to function comment
2133 TODO: EFI_DEVICE_ERROR - add return value to function comment
2134 TODO: EFI_DEVICE_ERROR - add return value to function comment
2138 IN IDE_BLK_IO_DEV
*IdeDev
,
2139 IN VOID
*DataBuffer
,
2140 IN EFI_LBA StartLba
,
2141 IN UINTN NumberOfBlocks
2144 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaReadOp
);
2148 This function is called by the AtaBlkIoWriteBlocks() to perform
2149 writing to media in block unit. The function has been enhanced to
2150 support >120GB access and transfer at most 65536 blocks per command
2152 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2153 to record all the information of the IDE device.
2155 @param[in] *DataBuffer A pointer to the source buffer for the data.
2157 @param[in] StartLba The starting logical block address to write to
2158 on the device media.
2160 @param[in] NumberOfBlocks The number of transfer data blocks.
2162 @return The device status of UDMA operation. If the operation is
2163 successful, return EFI_SUCCESS.
2165 TODO: EFI_UNSUPPORTED - add return value to function comment
2166 TODO: EFI_DEVICE_ERROR - add return value to function comment
2167 TODO: EFI_DEVICE_ERROR - add return value to function comment
2171 IN IDE_BLK_IO_DEV
*IdeDev
,
2172 IN VOID
*DataBuffer
,
2173 IN EFI_LBA StartLba
,
2174 IN UINTN NumberOfBlocks
2177 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteExtOp
);
2181 This function is called by the AtaBlkIoWriteBlocks() to perform
2182 writing to media in block unit. The function has been enhanced to
2183 support >120GB access and transfer at most 65536 blocks per command
2186 pointer pointing to IDE_BLK_IO_DEV data structure, used
2187 to record all the information of the IDE device.
2189 @param[in] *DataBuffer
2190 A pointer to the source buffer for the data.
2193 The starting logical block address to write to
2194 on the device media.
2196 @param[in] NumberOfBlocks
2197 The number of transfer data blocks.
2199 @return The device status of UDMA operation. If the operation is
2200 successful, return EFI_SUCCESS.
2202 TODO: EFI_UNSUPPORTED - add return value to function comment
2203 TODO: EFI_DEVICE_ERROR - add return value to function comment
2204 TODO: EFI_DEVICE_ERROR - add return value to function comment
2208 IN IDE_BLK_IO_DEV
*IdeDev
,
2209 IN VOID
*DataBuffer
,
2210 IN EFI_LBA StartLba
,
2211 IN UINTN NumberOfBlocks
2214 return DoAtaUdma (IdeDev
, DataBuffer
, StartLba
, NumberOfBlocks
, AtaUdmaWriteOp
);
2218 Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
2221 pointer pointing to IDE_BLK_IO_DEV data structure, used
2222 to record all the information of the IDE device.
2224 @param[in] *DataBuffer
2225 A pointer to the source buffer for the data.
2228 The starting logical block address to write to
2229 on the device media.
2231 @param[in] NumberOfBlocks
2232 The number of transfer data blocks.
2235 The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
2236 AtaUdmaWriteOp, AtaUdmaWriteExOp
2238 @return The device status of UDMA operation. If the operation is
2239 successful, return EFI_SUCCESS.
2244 IN IDE_BLK_IO_DEV
*IdeDev
,
2245 IN VOID
*DataBuffer
,
2246 IN EFI_LBA StartLba
,
2247 IN UINTN NumberOfBlocks
,
2248 IN ATA_UDMA_OPERATION UdmaOp
2251 IDE_DMA_PRD
*PrdAddr
;
2252 IDE_DMA_PRD
*UsedPrdAddr
;
2253 IDE_DMA_PRD
*TempPrdAddr
;
2254 UINT8 RegisterValue
;
2256 UINT64 IoPortForBmic
;
2257 UINT64 IoPortForBmis
;
2258 UINT64 IoPortForBmid
;
2262 UINTN ByteAvailable
;
2264 UINTN RemainBlockNum
;
2265 UINT8 DeviceControl
;
2270 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2271 UINTN MaxDmaCommandSectors
;
2272 EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp
;
2277 MaxDmaCommandSectors
= MAX_DMA_COMMAND_SECTORS
;
2278 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2279 AtaCommand
= READ_DMA_CMD
;
2281 case AtaUdmaReadExtOp
:
2282 MaxDmaCommandSectors
= MAX_DMA_EXT_COMMAND_SECTORS
;
2283 PciIoProtocolOp
= EfiPciIoOperationBusMasterWrite
;
2284 AtaCommand
= READ_DMA_EXT_CMD
;
2286 case AtaUdmaWriteOp
:
2287 MaxDmaCommandSectors
= MAX_DMA_COMMAND_SECTORS
;
2288 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2289 AtaCommand
= WRITE_DMA_CMD
;
2291 case AtaUdmaWriteExtOp
:
2292 MaxDmaCommandSectors
= MAX_DMA_EXT_COMMAND_SECTORS
;
2293 PciIoProtocolOp
= EfiPciIoOperationBusMasterRead
;
2294 AtaCommand
= WRITE_DMA_EXT_CMD
;
2297 return EFI_UNSUPPORTED
;
2302 // Channel and device differential
2304 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2307 // Enable interrupt to support UDMA and Select device
2310 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2312 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2314 if (IdePrimary
== IdeDev
->Channel
) {
2315 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2316 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2317 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2319 if (IdeSecondary
== IdeDev
->Channel
) {
2320 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2321 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2322 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2324 return EFI_UNSUPPORTED
;
2328 RemainBlockNum
= NumberOfBlocks
;
2329 while (RemainBlockNum
> 0) {
2331 if (RemainBlockNum
>= MaxDmaCommandSectors
) {
2333 // SectorCount is used to record the number of sectors to be read
2334 // Max 65536 sectors can be transfered at a time.
2336 NumberOfBlocks
= MaxDmaCommandSectors
;
2337 RemainBlockNum
-= MaxDmaCommandSectors
;
2339 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2344 // Calculate the number of PRD table to make sure the memory region
2345 // not cross 64K boundary
2347 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2348 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2353 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2354 Status
= IdeDev
->PciIo
->AllocateBuffer (
2357 EfiBootServicesData
,
2362 if (EFI_ERROR (Status
)) {
2363 return EFI_OUT_OF_RESOURCES
;
2365 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2367 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2369 // To make sure PRD is allocated in one 64K page
2371 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2372 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2374 if ((UINTN
) PrdAddr
& 0x03) {
2375 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2377 UsedPrdAddr
= PrdAddr
;
2382 // Build the PRD table
2384 Status
= IdeDev
->PciIo
->Map (
2392 if (EFI_ERROR (Status
)) {
2393 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2394 return EFI_OUT_OF_RESOURCES
;
2396 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
2397 TempPrdAddr
= UsedPrdAddr
;
2400 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2402 if (ByteCount
<= ByteAvailable
) {
2403 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2404 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2405 TempPrdAddr
->EndOfTable
= 0x8000;
2409 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2410 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2412 ByteCount
-= ByteAvailable
;
2413 PrdBuffer
+= ByteAvailable
;
2418 // Set the base address to BMID register
2420 IdeDev
->PciIo
->Io
.Write (
2422 EfiPciIoWidthUint32
,
2423 EFI_PCI_IO_PASS_THROUGH_BAR
,
2430 // Set BMIC register to identify the operation direction
2432 IdeDev
->PciIo
->Io
.Read (
2435 EFI_PCI_IO_PASS_THROUGH_BAR
,
2441 if (UdmaOp
== AtaUdmaReadExtOp
|| UdmaOp
== AtaUdmaReadOp
) {
2442 RegisterValue
|= BMIC_nREAD
;
2444 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
2447 IdeDev
->PciIo
->Io
.Write (
2450 EFI_PCI_IO_PASS_THROUGH_BAR
,
2457 // Read BMIS register and clear ERROR and INTR bit
2459 IdeDev
->PciIo
->Io
.Read (
2462 EFI_PCI_IO_PASS_THROUGH_BAR
,
2468 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2470 IdeDev
->PciIo
->Io
.Write (
2473 EFI_PCI_IO_PASS_THROUGH_BAR
,
2479 if (UdmaOp
== AtaUdmaWriteExtOp
|| UdmaOp
== AtaUdmaReadExtOp
) {
2480 Status
= AtaCommandIssueExt (
2485 (UINT16
) NumberOfBlocks
,
2489 Status
= AtaCommandIssue (
2494 (UINT16
) NumberOfBlocks
,
2499 if (EFI_ERROR (Status
)) {
2500 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2501 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2502 return EFI_DEVICE_ERROR
;
2506 // Set START bit of BMIC register
2508 IdeDev
->PciIo
->Io
.Read (
2511 EFI_PCI_IO_PASS_THROUGH_BAR
,
2517 RegisterValue
|= BMIC_START
;
2519 IdeDev
->PciIo
->Io
.Write (
2522 EFI_PCI_IO_PASS_THROUGH_BAR
,
2529 // Check the INTERRUPT and ERROR bit of BMIS
2530 // Max transfer number of sectors for one command is 65536(32Mbyte),
2531 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
2532 // So set the variable Count to 2000, for about 2 second timeout time.
2537 IdeDev
->PciIo
->Io
.Read (
2540 EFI_PCI_IO_PASS_THROUGH_BAR
,
2545 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
2546 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
2548 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
2550 IdeDev
->PciIo
->Io
.Read (
2553 EFI_PCI_IO_PASS_THROUGH_BAR
,
2559 RegisterValue
&= ~((UINT8
)BMIC_START
);
2561 IdeDev
->PciIo
->Io
.Write (
2564 EFI_PCI_IO_PASS_THROUGH_BAR
,
2569 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2570 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2571 return EFI_DEVICE_ERROR
;
2580 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2581 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2583 // Read Status Register of IDE device to clear interrupt
2585 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
2587 // Clear START bit of BMIC register
2589 IdeDev
->PciIo
->Io
.Read (
2592 EFI_PCI_IO_PASS_THROUGH_BAR
,
2598 RegisterValue
&= ~((UINT8
) BMIC_START
);
2600 IdeDev
->PciIo
->Io
.Write (
2603 EFI_PCI_IO_PASS_THROUGH_BAR
,
2609 if (RegisterValue
& BMIS_ERROR
) {
2610 return EFI_DEVICE_ERROR
;
2613 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2614 StartLba
+= NumberOfBlocks
;
2618 // Disable interrupt of Select device
2620 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
2621 DeviceControl
|= IEN_L
;
2622 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);