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 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1080 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1082 Status
= AtaUdmaReadExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1083 if (EFI_ERROR (Status
)) {
1084 Status
= AtaReadSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1088 // For ATA-3 compatible device, use ATA-3 read block mechanism
1090 Status
= AtaUdmaRead (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1091 if (EFI_ERROR (Status
)) {
1092 Status
= AtaReadSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1096 if (EFI_ERROR (Status
)) {
1097 AtaSoftReset (IdeBlkIoDevice
);
1098 return EFI_DEVICE_ERROR
;
1106 This function is the ATA implementation for WriteBlocks in the
1107 Block I/O Protocol interface.
1109 @param[in] *IdeBlkIoDevice
1110 Indicates the calling context.
1113 The media id that the write request is for.
1116 The starting logical block address to write onto
1119 @param[in] BufferSize
1120 The size of the Buffer in bytes. This must be a
1121 multiple of the intrinsic block size of the device.
1124 A pointer to the source buffer for the data.
1125 The caller is responsible for either having implicit
1126 or explicit ownership of the memory that data is
1129 @retval EFI_SUCCESS Write Blocks successfully.
1130 @retval EFI_DEVICE_ERROR Write Blocks failed.
1131 @retval EFI_NO_MEDIA There is no media in the device.
1132 @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.
1134 @retval EFI_BAD_BUFFER_SIZE
1135 The BufferSize parameter is not a multiple of the
1136 intrinsic block size of the device.
1138 @retval EFI_INVALID_PARAMETER
1139 The write request contains LBAs that are not valid,
1140 or the data buffer is not valid.
1143 If Write Block error because of device error, this function will call
1144 AtaSoftReset() function to reset device.
1148 AtaBlkIoWriteBlocks (
1149 IN IDE_BLK_IO_DEV
*IdeBlkIoDevice
,
1152 IN UINTN BufferSize
,
1157 EFI_BLOCK_IO_MEDIA
*Media
;
1159 UINTN NumberOfBlocks
;
1162 if (Buffer
== NULL
) {
1163 return EFI_INVALID_PARAMETER
;
1166 if (BufferSize
== 0) {
1170 Status
= EFI_SUCCESS
;
1173 // Get the intrinsic block size
1175 Media
= IdeBlkIoDevice
->BlkIo
.Media
;
1176 BlockSize
= Media
->BlockSize
;
1177 NumberOfBlocks
= BufferSize
/ BlockSize
;
1179 if (MediaId
!= Media
->MediaId
) {
1180 return EFI_MEDIA_CHANGED
;
1183 if (BufferSize
% BlockSize
!= 0) {
1184 return EFI_BAD_BUFFER_SIZE
;
1187 if (LBA
> Media
->LastBlock
) {
1188 return EFI_INVALID_PARAMETER
;
1191 if ((LBA
+ NumberOfBlocks
- 1) > Media
->LastBlock
) {
1192 return EFI_INVALID_PARAMETER
;
1195 if ((Media
->IoAlign
> 1) && (((UINTN
) Buffer
& (Media
->IoAlign
- 1)) != 0)) {
1196 return EFI_INVALID_PARAMETER
;
1199 if (IdeBlkIoDevice
->Type
== Ide48bitAddressingHardDisk
) {
1201 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1203 Status
= AtaUdmaWriteExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1204 if (EFI_ERROR (Status
)) {
1205 Status
= AtaWriteSectorsExt (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1209 // For ATA-3 compatible device, use ATA-3 write block mechanism
1211 Status
= AtaUdmaWrite (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1212 if (EFI_ERROR (Status
)) {
1213 Status
= AtaWriteSectors (IdeBlkIoDevice
, Buffer
, LBA
, NumberOfBlocks
);
1217 if (EFI_ERROR (Status
)) {
1218 AtaSoftReset (IdeBlkIoDevice
);
1219 return EFI_DEVICE_ERROR
;
1226 This function is called by the AtaBlkIoReadBlocks() to perform
1227 reading from media in block unit. The function has been enhanced to
1228 support >120GB access and transfer at most 65536 blocks per command
1231 pointer pointing to IDE_BLK_IO_DEV data structure, used
1232 to record all the information of the IDE device.
1234 @param[in] *DataBuffer A pointer to the destination buffer for the data.
1235 @param[in] StartLba The starting logical block address to read from
1236 on the device media.
1237 @param[in] NumberOfBlocks The number of transfer data blocks.
1239 @return return status is fully dependent on the return status
1240 of AtaPioDataInExt() function.
1245 IN IDE_BLK_IO_DEV
*IdeDev
,
1246 IN VOID
*DataBuffer
,
1247 IN EFI_LBA StartLba
,
1248 IN UINTN NumberOfBlocks
1252 UINTN BlocksRemaining
;
1260 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1262 AtaCommand
= READ_SECTORS_EXT_CMD
;
1263 Buffer
= DataBuffer
;
1264 BlocksRemaining
= NumberOfBlocks
;
1266 Status
= EFI_SUCCESS
;
1268 while (BlocksRemaining
> 0) {
1270 if (BlocksRemaining
>= 0x10000) {
1272 // SectorCount is used to record the number of sectors to be read
1273 // Max 65536 sectors can be transfered at a time.
1275 SectorCount
= 0xffff;
1277 SectorCount
= (UINT16
) BlocksRemaining
;
1281 // ByteCount is the number of bytes that will be read
1283 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1286 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1288 Status
= AtaPioDataInExt (
1296 if (EFI_ERROR (Status
)) {
1300 Lba64
+= SectorCount
;
1301 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1302 BlocksRemaining
-= SectorCount
;
1309 This function is called by the AtaBlkIoWriteBlocks() to perform
1310 writing onto media in block unit. The function has been enhanced to
1311 support >120GB access and transfer at most 65536 blocks per command
1314 pointer pointing to IDE_BLK_IO_DEV data structure,used
1315 to record all the information of the IDE device.
1317 @param[in] *DataBuffer
1318 A pointer to the source buffer for the data.
1321 The starting logical block address to write onto
1324 @param[in] NumberOfBlocks
1325 The number of transfer data blocks.
1327 @return status is fully dependent on the return status
1328 of AtaPioDataOutExt() function.
1332 AtaWriteSectorsExt (
1333 IN IDE_BLK_IO_DEV
*IdeDev
,
1334 IN VOID
*DataBuffer
,
1335 IN EFI_LBA StartLba
,
1336 IN UINTN NumberOfBlocks
1341 UINTN BlocksRemaining
;
1348 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1350 AtaCommand
= WRITE_SECTORS_EXT_CMD
;
1352 Buffer
= DataBuffer
;
1353 BlocksRemaining
= NumberOfBlocks
;
1355 Status
= EFI_SUCCESS
;
1357 while (BlocksRemaining
> 0) {
1359 if (BlocksRemaining
>= 0x10000) {
1361 // SectorCount is used to record the number of sectors to be written.
1362 // Max 65536 sectors can be transfered at a time.
1364 SectorCount
= 0xffff;
1366 SectorCount
= (UINT16
) BlocksRemaining
;
1370 // ByteCount is the number of bytes that will be written
1372 ByteCount
= SectorCount
* (IdeDev
->BlkIo
.Media
->BlockSize
);
1375 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1377 Status
= AtaPioDataOutExt (
1385 if (EFI_ERROR (Status
)) {
1389 Lba64
+= SectorCount
;
1390 Buffer
= ((UINT8
*) Buffer
+ ByteCount
);
1391 BlocksRemaining
-= SectorCount
;
1398 This function is used to send out ATA commands conforms to the
1399 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1401 Comparing with ATA-3 data in protocol, we have two differents here:<BR>
1402 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1403 wait will frequently fail... cause writing function return error)
1405 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1406 slow down writing performance by 100 times!)
1408 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
1409 to record all the information of the IDE device.
1411 @param[in,out] *Buffer buffer contained data transferred from device to host.
1412 @param[in] ByteCount data size in byte unit of the buffer.
1413 @param[in] AtaCommand value of the Command Register
1414 @param[in] StartLba the start LBA of this transaction
1415 @param[in] SectorCount the count of sectors to be transfered
1417 @retval EFI_SUCCESS send out the ATA command and device send required
1420 @retval EFI_DEVICE_ERROR command sent failed.
1425 IN IDE_BLK_IO_DEV
*IdeDev
,
1426 IN OUT VOID
*Buffer
,
1427 IN UINT32 ByteCount
,
1428 IN UINT8 AtaCommand
,
1429 IN EFI_LBA StartLba
,
1430 IN UINT16 SectorCount
1443 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1444 if (EFI_ERROR (Status
)) {
1445 return EFI_DEVICE_ERROR
;
1449 // Select device, set bit6 as 1 to indicate LBA mode is used
1451 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1455 IdeDev
->IoPort
->Head
,
1460 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1462 if ( (IdeDev
->Type
== IdeHardDisk
) ||
1463 (IdeDev
->Type
== Ide48bitAddressingHardDisk
)) {
1465 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1466 if (EFI_ERROR (Status
)) {
1467 return EFI_DEVICE_ERROR
;
1472 // Fill feature register if needed
1474 if (AtaCommand
== SET_FEATURES_CMD
) {
1475 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1479 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1481 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1482 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1484 SectorCount8
= (UINT8
) SectorCount
;
1485 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1488 // Fill the start LBA registers, which are also two-byte FIFO
1490 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1491 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1492 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1493 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1494 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1495 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1497 LbaLow
= (UINT8
) StartLba
;
1498 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1499 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1500 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1501 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1502 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1505 // Send command via Command Register, invoking the processing of this command
1507 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1509 Buffer16
= (UINT16
*) Buffer
;
1512 // According to PIO data in protocol, host can perform a series of reads to
1513 // the data register after each time device set DRQ ready;
1522 // used to record bytes of currently transfered data
1526 while (WordCount
< ByteCount
/ 2) {
1528 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1530 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1531 if (EFI_ERROR (Status
)) {
1532 return EFI_DEVICE_ERROR
;
1535 Status
= CheckErrorStatus (IdeDev
);
1536 if (EFI_ERROR (Status
)) {
1537 return EFI_DEVICE_ERROR
;
1541 // Get the byte count for one series of read
1543 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1544 Increment
= ByteCount
/ 2 - WordCount
;
1547 IDEReadPortWMultiple (
1549 IdeDev
->IoPort
->Data
,
1554 WordCount
+= Increment
;
1555 Buffer16
+= Increment
;
1559 return CheckErrorStatus (IdeDev
);
1563 This function is used to send out ATA commands conforms to the
1564 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1566 Comparing with ATA-3 data out protocol, we have two differents here:<BR>
1567 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1568 wait will frequently fail... cause writing function return error)
1570 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1571 slow down writing performance by 100 times!)
1574 pointer pointing to IDE_BLK_IO_DEV data structure, used
1575 to record all the information of the IDE device.
1577 @param[in] *Buffer buffer contained data transferred from host to device.
1578 @param[in] ByteCount data size in byte unit of the buffer.
1579 @param[in] AtaCommand value of the Command Register
1580 @param[in] StartLba the start LBA of this transaction
1581 @param[in] SectorCount the count of sectors to be transfered
1583 @retval EFI_SUCCESS send out the ATA command and device receive required
1586 @retval EFI_DEVICE_ERROR command sent failed.
1591 IN IDE_BLK_IO_DEV
*IdeDev
,
1593 IN UINT32 ByteCount
,
1594 IN UINT8 AtaCommand
,
1595 IN EFI_LBA StartLba
,
1596 IN UINT16 SectorCount
1609 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1610 if (EFI_ERROR (Status
)) {
1611 return EFI_DEVICE_ERROR
;
1615 // Select device. Set bit6 as 1 to indicate LBA mode is used
1617 DevSel
= (UINT8
) (IdeDev
->Device
<< 4);
1621 IdeDev
->IoPort
->Head
,
1626 // Wait for DRDY singnal asserting.
1628 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1629 if (EFI_ERROR (Status
)) {
1630 return EFI_DEVICE_ERROR
;
1634 // Fill feature register if needed
1636 if (AtaCommand
== SET_FEATURES_CMD
) {
1637 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, 0x03);
1641 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1643 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1644 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1646 SectorCount8
= (UINT8
) SectorCount
;
1647 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1650 // Fill the start LBA registers, which are also two-byte FIFO
1652 LbaLow
= (UINT8
) RShiftU64 (StartLba
, 24);
1653 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 32);
1654 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 40);
1655 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1656 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1657 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1659 LbaLow
= (UINT8
) StartLba
;
1660 LbaMid
= (UINT8
) RShiftU64 (StartLba
, 8);
1661 LbaHigh
= (UINT8
) RShiftU64 (StartLba
, 16);
1662 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1663 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1664 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1667 // Send command via Command Register, invoking the processing of this command
1669 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1671 Buffer16
= (UINT16
*) Buffer
;
1674 // According to PIO Data Out protocol, host can perform a series of writes to
1675 // the data register after each time device set DRQ ready;
1680 // used to record bytes of currently transfered data
1684 while (WordCount
< ByteCount
/ 2) {
1686 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1688 Status
= DRQReady2 (IdeDev
, ATATIMEOUT
);
1689 if (EFI_ERROR (Status
)) {
1690 return EFI_DEVICE_ERROR
;
1693 Status
= CheckErrorStatus (IdeDev
);
1694 if (EFI_ERROR (Status
)) {
1695 return EFI_DEVICE_ERROR
;
1699 // Write data into device by one series of writing to data register
1701 if ((WordCount
+ Increment
) > ByteCount
/ 2) {
1702 Increment
= ByteCount
/ 2 - WordCount
;
1705 IDEWritePortWMultiple (
1707 IdeDev
->IoPort
->Data
,
1712 WordCount
+= Increment
;
1713 Buffer16
+= Increment
;
1720 return CheckErrorStatus (IdeDev
);
1725 Enable SMART of the disk if supported
1728 pointer pointing to IDE_BLK_IO_DEV data structure,used
1729 to record all the information of the IDE device.
1734 IN IDE_BLK_IO_DEV
*IdeDev
1738 BOOLEAN SMARTSupported
;
1740 EFI_IDENTIFY_DATA
*TmpAtaIdentifyPointer
;
1746 // Detect if the device supports S.M.A.R.T.
1748 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_83
& 0xc000) != 0x4000) {
1750 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
1754 if ((IdeDev
->pIdData
->AtaData
.command_set_supported_82
& 0x0001) != 0x0001) {
1756 // S.M.A.R.T is not supported by the device
1758 SMARTSupported
= FALSE
;
1760 SMARTSupported
= TRUE
;
1764 if (!SMARTSupported
) {
1766 // Report nonsupport status code
1768 REPORT_STATUS_CODE (
1769 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1770 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED
)
1774 // Enable this feature
1776 REPORT_STATUS_CODE (
1778 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_ENABLE
)
1781 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
1782 Status
= AtaNonDataCommandIn (
1786 ATA_SMART_ENABLE_OPERATION
,
1793 // Detect if this feature is enabled
1795 TmpAtaIdentifyPointer
= (EFI_IDENTIFY_DATA
*) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA
));
1797 DeviceSelect
= (UINT8
) ((IdeDev
->Device
) << 4);
1798 Status
= AtaPioDataIn (
1800 (VOID
*) TmpAtaIdentifyPointer
,
1801 sizeof (EFI_IDENTIFY_DATA
),
1809 if (EFI_ERROR (Status
)) {
1810 gBS
->FreePool (TmpAtaIdentifyPointer
);
1815 // Check if the feature is enabled
1817 if ((TmpAtaIdentifyPointer
->AtaData
.command_set_feature_enb_85
& 0x0001) == 0x0001) {
1821 AtaNonDataCommandIn (
1825 ATA_SMART_RETURN_STATUS
,
1831 LBAMid
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
);
1832 LBAHigh
= IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
);
1834 if ((LBAMid
== 0x4f) && (LBAHigh
== 0xc2)) {
1836 // The threshold exceeded condition is not detected by the device
1838 REPORT_STATUS_CODE (
1840 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD
)
1843 } else if ((LBAMid
== 0xf4) && (LBAHigh
== 0x2c)) {
1845 // The threshold exceeded condition is detected by the device
1847 REPORT_STATUS_CODE (
1849 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD
)
1855 // Report disabled status code
1857 REPORT_STATUS_CODE (
1858 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1859 (EFI_IO_BUS_ATA_ATAPI
| EFI_IOB_ATA_BUS_SMART_DISABLED
)
1863 gBS
->FreePool (TmpAtaIdentifyPointer
);
1870 Send ATA Ext command into device with NON_DATA protocol
1872 @param IdeDev Standard IDE device private data structure
1873 @param AtaCommand The ATA command to be sent
1874 @param Device The value in Device register
1875 @param Feature The value in Feature register
1876 @param SectorCount The value in SectorCount register
1877 @param LbaAddress The LBA address in 48-bit mode
1879 @retval EFI_SUCCESS Reading succeed
1880 @retval EFI_DEVICE_ERROR Error executing commands on this device
1884 AtaCommandIssueExt (
1885 IN IDE_BLK_IO_DEV
*IdeDev
,
1886 IN UINT8 AtaCommand
,
1889 IN UINT16 SectorCount
,
1890 IN EFI_LBA LbaAddress
1900 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
1901 if (EFI_ERROR (Status
)) {
1902 return EFI_DEVICE_ERROR
;
1906 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
1910 IdeDev
->IoPort
->Head
,
1911 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
1915 // ATA commands for ATA device must be issued when DRDY is set
1917 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
1918 if (EFI_ERROR (Status
)) {
1919 return EFI_DEVICE_ERROR
;
1923 // Pass parameter into device register block
1925 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
1928 // Fill the feature register, which is a two-byte FIFO. Need write twice.
1930 Feature8
= (UINT8
) (Feature
>> 8);
1931 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1933 Feature8
= (UINT8
) Feature
;
1934 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
1937 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1939 SectorCount8
= (UINT8
) (SectorCount
>> 8);
1940 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1942 SectorCount8
= (UINT8
) SectorCount
;
1943 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
1946 // Fill the start LBA registers, which are also two-byte FIFO
1948 LbaLow
= (UINT8
) RShiftU64 (LbaAddress
, 24);
1949 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1950 LbaLow
= (UINT8
) LbaAddress
;
1951 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, LbaLow
);
1953 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 32);
1954 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1955 LbaMid
= (UINT8
) RShiftU64 (LbaAddress
, 8);
1956 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, LbaMid
);
1958 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 40);
1959 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1960 LbaHigh
= (UINT8
) RShiftU64 (LbaAddress
, 16);
1961 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, LbaHigh
);
1964 // Work around for Segate 160G disk writing
1969 // Send command via Command Register
1971 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
1974 // Stall at least 400ns
1982 Send ATA Ext command into device with NON_DATA protocol
1984 @param IdeDev Standard IDE device private data structure
1985 @param AtaCommand The ATA command to be sent
1986 @param Device The value in Device register
1987 @param Feature The value in Feature register
1988 @param SectorCount The value in SectorCount register
1989 @param LbaAddress The LBA address in 48-bit mode
1991 @retval EFI_SUCCESS Reading succeed
1992 @retval EFI_DEVICE_ERROR Error executing commands on this device
1997 IN IDE_BLK_IO_DEV
*IdeDev
,
1998 IN UINT8 AtaCommand
,
2001 IN UINT16 SectorCount
,
2002 IN EFI_LBA LbaAddress
2013 Status
= WaitForBSYClear (IdeDev
, ATATIMEOUT
);
2014 if (EFI_ERROR (Status
)) {
2015 return EFI_DEVICE_ERROR
;
2019 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2023 IdeDev
->IoPort
->Head
,
2024 (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0)
2028 // ATA commands for ATA device must be issued when DRDY is set
2030 Status
= DRDYReady (IdeDev
, ATATIMEOUT
);
2031 if (EFI_ERROR (Status
)) {
2032 return EFI_DEVICE_ERROR
;
2035 Lba0
= (UINT8
) LbaAddress
;
2036 Lba1
= (UINT8
) RShiftU64 (LbaAddress
, 8);
2037 Lba2
= (UINT8
) RShiftU64 (LbaAddress
, 16);
2038 Lba3
= (UINT8
) RShiftU64 (LbaAddress
, 24);
2039 Device
= (UINT8
) (Device
| Lba3
);
2042 // Pass parameter into device register block
2044 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2047 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2049 Feature8
= (UINT8
) Feature
;
2050 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg1
.Feature
, Feature8
);
2053 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2055 SectorCount8
= (UINT8
) SectorCount
;
2056 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorCount
, SectorCount8
);
2059 // Fill the start LBA registers, which are also two-byte FIFO
2062 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->SectorNumber
, Lba0
);
2063 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderLsb
, Lba1
);
2064 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->CylinderMsb
, Lba2
);
2067 // Send command via Command Register
2069 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Reg
.Command
, AtaCommand
);
2072 // Stall at least 400ns
2080 This function is called by the AtaBlkIoReadBlocks() to perform
2081 reading from media in block unit. The function has been enhanced to
2082 support >120GB access and transfer at most 65536 blocks per command
2084 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2085 to record all the information of the IDE device.
2087 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2089 @param[in] StartLba The starting logical block address to read from
2090 on the device media.
2092 @param[in] NumberOfBlocks The number of transfer data blocks.
2094 @return The device status of UDMA operation. If the operation is
2095 successful, return EFI_SUCCESS.
2097 TODO: EFI_UNSUPPORTED - add return value to function comment
2098 TODO: EFI_DEVICE_ERROR - 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
2104 IN IDE_BLK_IO_DEV
*IdeDev
,
2105 IN VOID
*DataBuffer
,
2106 IN EFI_LBA StartLba
,
2107 IN UINTN NumberOfBlocks
2110 IDE_DMA_PRD
*PrdAddr
;
2111 IDE_DMA_PRD
*UsedPrdAddr
;
2112 IDE_DMA_PRD
*TempPrdAddr
;
2113 UINT8 RegisterValue
;
2115 UINT64 IoPortForBmic
;
2116 UINT64 IoPortForBmis
;
2117 UINT64 IoPortForBmid
;
2121 UINTN ByteAvailable
;
2123 UINTN RemainBlockNum
;
2124 UINT8 DeviceControl
;
2129 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2132 // Channel and device differential. Select device.
2134 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2137 // Enable interrupt to support UDMA and Select device
2140 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2142 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2144 if (IdePrimary
== IdeDev
->Channel
) {
2145 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2146 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2147 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2149 if (IdeSecondary
== IdeDev
->Channel
) {
2150 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2151 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2152 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2154 return EFI_UNSUPPORTED
;
2158 RemainBlockNum
= NumberOfBlocks
;
2159 while (RemainBlockNum
> 0) {
2161 if (RemainBlockNum
>= MAX_DMA_EXT_COMMAND_SECTORS
) {
2163 // SectorCount is used to record the number of sectors to be read
2164 // Max 65536 sectors can be transfered at a time.
2166 NumberOfBlocks
= MAX_DMA_EXT_COMMAND_SECTORS
;
2167 RemainBlockNum
-= MAX_DMA_EXT_COMMAND_SECTORS
;
2169 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2174 // Calculate the number of PRD table to make sure the memory region
2175 // not cross 64K boundary
2177 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2178 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2183 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2184 Status
= IdeDev
->PciIo
->AllocateBuffer (
2187 EfiBootServicesData
,
2192 if (EFI_ERROR (Status
)) {
2193 return EFI_OUT_OF_RESOURCES
;
2195 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2197 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2200 // To make sure PRD is allocated in one 64K page
2202 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2203 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2205 if ((UINTN
) PrdAddr
& 0x03) {
2206 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2208 UsedPrdAddr
= PrdAddr
;
2213 // Build the PRD table
2215 Status
= IdeDev
->PciIo
->Map (
2217 EfiPciIoOperationBusMasterWrite
,
2223 if (EFI_ERROR (Status
)) {
2224 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2225 return EFI_OUT_OF_RESOURCES
;
2227 PrdBuffer
= (VOID
*) ((UINTN
) DeviceAddress
);
2228 TempPrdAddr
= UsedPrdAddr
;
2231 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2233 if (ByteCount
<= ByteAvailable
) {
2234 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2235 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2236 TempPrdAddr
->EndOfTable
= 0x8000;
2240 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2241 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2243 ByteCount
-= ByteAvailable
;
2244 PrdBuffer
+= ByteAvailable
;
2249 // Set the base address to BMID register
2251 IdeDev
->PciIo
->Io
.Write (
2253 EfiPciIoWidthUint32
,
2254 EFI_PCI_IO_PASS_THROUGH_BAR
,
2261 // Set BMIC register to identify the operation direction
2263 IdeDev
->PciIo
->Io
.Read (
2266 EFI_PCI_IO_PASS_THROUGH_BAR
,
2272 RegisterValue
|= BMIC_nREAD
;
2274 IdeDev
->PciIo
->Io
.Write (
2277 EFI_PCI_IO_PASS_THROUGH_BAR
,
2284 // Read BMIS register and clear ERROR and INTR bit
2286 IdeDev
->PciIo
->Io
.Read (
2289 EFI_PCI_IO_PASS_THROUGH_BAR
,
2295 RegisterValue
|= BMIS_INTERRUPT
| BMIS_ERROR
;
2297 IdeDev
->PciIo
->Io
.Write (
2300 EFI_PCI_IO_PASS_THROUGH_BAR
,
2307 // Issue READ DMA EXT command
2309 Status
= AtaCommandIssueExt (
2314 (UINT16
) NumberOfBlocks
,
2317 if (EFI_ERROR (Status
)) {
2318 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2319 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2320 return EFI_DEVICE_ERROR
;
2324 // Set START bit of BMIC register
2326 IdeDev
->PciIo
->Io
.Read (
2329 EFI_PCI_IO_PASS_THROUGH_BAR
,
2335 RegisterValue
|= BMIC_START
;
2337 IdeDev
->PciIo
->Io
.Write (
2340 EFI_PCI_IO_PASS_THROUGH_BAR
,
2347 // Check the INTERRUPT and ERROR bit of BMIS
2348 // Max transfer number of sectors for one command is 65536(32Mbyte),
2349 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
2350 // So set the variable Count to 2000, for about 2 second timeout time.
2355 IdeDev
->PciIo
->Io
.Read (
2358 EFI_PCI_IO_PASS_THROUGH_BAR
,
2363 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
2364 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
2366 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
2368 IdeDev
->PciIo
->Io
.Read (
2371 EFI_PCI_IO_PASS_THROUGH_BAR
,
2377 RegisterValue
&= ~((UINT8
)BMIC_START
);
2379 IdeDev
->PciIo
->Io
.Write (
2382 EFI_PCI_IO_PASS_THROUGH_BAR
,
2387 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2388 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2389 return EFI_DEVICE_ERROR
;
2398 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2399 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2401 // Read Status Register of IDE device to clear interrupt
2403 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
2405 // Clear START bit of BMIC register
2407 IdeDev
->PciIo
->Io
.Read (
2410 EFI_PCI_IO_PASS_THROUGH_BAR
,
2416 RegisterValue
&= ~((UINT8
) BMIC_START
);
2418 IdeDev
->PciIo
->Io
.Write (
2421 EFI_PCI_IO_PASS_THROUGH_BAR
,
2427 if (RegisterValue
& BMIS_ERROR
) {
2428 return EFI_DEVICE_ERROR
;
2431 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2432 StartLba
+= NumberOfBlocks
;
2436 // Disable interrupt of Select device
2438 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
2439 DeviceControl
|= IEN_L
;
2440 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2446 This function is called by the AtaBlkIoReadBlocks() to perform
2447 reading from media in block unit. The function has been enhanced to
2448 support >120GB access and transfer at most 65536 blocks per command
2451 pointer pointing to IDE_BLK_IO_DEV data structure, used
2452 to record all the information of the IDE device.
2454 @param[in] *DataBuffer A pointer to the destination buffer for the data.
2455 @param[in] StartLba The starting logical block address to read from
2456 on the device media.
2457 @param[in] NumberOfBlocks The number of transfer data blocks.
2459 @return The device status of UDMA operation. If the operation is
2460 successful, return EFI_SUCCESS.
2462 TODO: EFI_UNSUPPORTED - add return value to function comment
2463 TODO: EFI_DEVICE_ERROR - add return value to function comment
2464 TODO: EFI_DEVICE_ERROR - add return value to function comment
2465 TODO: EFI_DEVICE_ERROR - add return value to function comment
2469 IN IDE_BLK_IO_DEV
*IdeDev
,
2470 IN VOID
*DataBuffer
,
2471 IN EFI_LBA StartLba
,
2472 IN UINTN NumberOfBlocks
2475 IDE_DMA_PRD
*PrdAddr
;
2476 IDE_DMA_PRD
*UsedPrdAddr
;
2477 IDE_DMA_PRD
*TempPrdAddr
;
2478 UINT8 RegisterValue
;
2480 UINT64 IoPortForBmic
;
2481 UINT64 IoPortForBmis
;
2482 UINT64 IoPortForBmid
;
2486 UINTN ByteAvailable
;
2488 UINTN RemainBlockNum
;
2489 UINT8 DeviceControl
;
2494 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2497 // Channel and device differential
2499 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2502 // Enable interrupt to support UDMA and Select device
2505 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2507 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2509 if (IdePrimary
== IdeDev
->Channel
) {
2510 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2511 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2512 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2514 if (IdeSecondary
== IdeDev
->Channel
) {
2515 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2516 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2517 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2519 return EFI_UNSUPPORTED
;
2523 RemainBlockNum
= NumberOfBlocks
;
2524 while (RemainBlockNum
> 0) {
2526 if (RemainBlockNum
>= MAX_DMA_COMMAND_SECTORS
) {
2528 // SectorCount is used to record the number of sectors to be read
2529 // Max 256 sectors can be transfered at a time.
2531 NumberOfBlocks
= MAX_DMA_COMMAND_SECTORS
;
2532 RemainBlockNum
-= MAX_DMA_COMMAND_SECTORS
;
2534 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2539 // Calculate the number of PRD table to make sure the memory region
2540 // not cross 64K boundary
2542 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2543 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2548 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2549 Status
= IdeDev
->PciIo
->AllocateBuffer (
2552 EfiBootServicesData
,
2557 if (EFI_ERROR (Status
)) {
2558 return EFI_OUT_OF_RESOURCES
;
2560 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2562 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2564 // To make sure PRD is allocated in one 64K page
2566 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2567 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2569 if ((UINTN
) PrdAddr
& 0x03) {
2570 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2572 UsedPrdAddr
= PrdAddr
;
2577 // Build the PRD table
2579 Status
= IdeDev
->PciIo
->Map (
2581 EfiPciIoOperationBusMasterWrite
,
2587 if (EFI_ERROR (Status
)) {
2588 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2589 return EFI_OUT_OF_RESOURCES
;
2591 PrdBuffer
= (UINT8
*) ((UINTN
) DeviceAddress
);
2592 TempPrdAddr
= UsedPrdAddr
;
2595 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2597 if (ByteCount
<= ByteAvailable
) {
2598 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2599 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2600 TempPrdAddr
->EndOfTable
= 0x8000;
2604 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2605 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2607 ByteCount
-= ByteAvailable
;
2608 PrdBuffer
+= ByteAvailable
;
2613 // Set the base address to BMID register
2615 IdeDev
->PciIo
->Io
.Write (
2617 EfiPciIoWidthUint32
,
2618 EFI_PCI_IO_PASS_THROUGH_BAR
,
2625 // Set BMIC register to identify the operation direction
2627 IdeDev
->PciIo
->Io
.Read (
2630 EFI_PCI_IO_PASS_THROUGH_BAR
,
2636 RegisterValue
|= BMIC_nREAD
;
2638 IdeDev
->PciIo
->Io
.Write (
2641 EFI_PCI_IO_PASS_THROUGH_BAR
,
2648 // Read BMIS register and clear ERROR and INTR bit
2650 IdeDev
->PciIo
->Io
.Read (
2653 EFI_PCI_IO_PASS_THROUGH_BAR
,
2659 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
2661 IdeDev
->PciIo
->Io
.Write (
2664 EFI_PCI_IO_PASS_THROUGH_BAR
,
2671 // Issue READ DMA command
2673 Status
= AtaCommandIssue (
2678 (UINT16
) NumberOfBlocks
,
2681 if (EFI_ERROR (Status
)) {
2682 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2683 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2684 return EFI_DEVICE_ERROR
;
2688 // Set START bit of BMIC register
2690 IdeDev
->PciIo
->Io
.Read (
2693 EFI_PCI_IO_PASS_THROUGH_BAR
,
2699 RegisterValue
|= BMIC_START
;
2701 IdeDev
->PciIo
->Io
.Write (
2704 EFI_PCI_IO_PASS_THROUGH_BAR
,
2711 // Check the INTERRUPT and ERROR bit of BMIS
2712 // Max transfer number of sectors for one command is 65536(32Mbyte),
2713 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
2714 // So set the variable Count to 2000, for about 2 second timeout time.
2719 IdeDev
->PciIo
->Io
.Read (
2722 EFI_PCI_IO_PASS_THROUGH_BAR
,
2727 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
2728 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
2730 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
2732 IdeDev
->PciIo
->Io
.Read (
2735 EFI_PCI_IO_PASS_THROUGH_BAR
,
2741 RegisterValue
&= ~((UINT8
)BMIC_START
);
2743 IdeDev
->PciIo
->Io
.Write (
2746 EFI_PCI_IO_PASS_THROUGH_BAR
,
2751 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2752 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2753 return EFI_DEVICE_ERROR
;
2762 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2763 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
2765 // Read Status Register of IDE device to clear interrupt
2767 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
2769 // Clear START bit of BMIC register
2771 IdeDev
->PciIo
->Io
.Read (
2774 EFI_PCI_IO_PASS_THROUGH_BAR
,
2780 RegisterValue
&= ~((UINT8
) BMIC_START
);
2782 IdeDev
->PciIo
->Io
.Write (
2785 EFI_PCI_IO_PASS_THROUGH_BAR
,
2791 if (RegisterValue
& BMIS_ERROR
) {
2792 return EFI_DEVICE_ERROR
;
2795 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2796 StartLba
+= NumberOfBlocks
;
2800 // Disable interrupt of Select device
2802 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
2803 DeviceControl
|= IEN_L
;
2804 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2810 This function is called by the AtaBlkIoWriteBlocks() to perform
2811 writing to media in block unit. The function has been enhanced to
2812 support >120GB access and transfer at most 65536 blocks per command
2814 @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
2815 to record all the information of the IDE device.
2817 @param[in] *DataBuffer A pointer to the source buffer for the data.
2819 @param[in] StartLba The starting logical block address to write to
2820 on the device media.
2822 @param[in] NumberOfBlocks The number of transfer data blocks.
2824 @return The device status of UDMA operation. If the operation is
2825 successful, return EFI_SUCCESS.
2827 TODO: EFI_UNSUPPORTED - add return value to function comment
2828 TODO: EFI_DEVICE_ERROR - add return value to function comment
2829 TODO: EFI_DEVICE_ERROR - add return value to function comment
2833 IN IDE_BLK_IO_DEV
*IdeDev
,
2834 IN VOID
*DataBuffer
,
2835 IN EFI_LBA StartLba
,
2836 IN UINTN NumberOfBlocks
2839 IDE_DMA_PRD
*PrdAddr
;
2840 IDE_DMA_PRD
*UsedPrdAddr
;
2841 IDE_DMA_PRD
*TempPrdAddr
;
2842 UINT8 RegisterValue
;
2844 UINT64 IoPortForBmic
;
2845 UINT64 IoPortForBmis
;
2846 UINT64 IoPortForBmid
;
2850 UINTN ByteAvailable
;
2852 UINTN RemainBlockNum
;
2853 UINT8 DeviceControl
;
2858 EFI_PHYSICAL_ADDRESS DeviceAddress
;
2861 // Channel and device differential
2863 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
2866 // Enable interrupt to support UDMA and Select device
2869 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
2871 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
2873 if (IdePrimary
== IdeDev
->Channel
) {
2874 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
2875 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
2876 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
2878 if (IdeSecondary
== IdeDev
->Channel
) {
2879 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
2880 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
2881 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
2883 return EFI_UNSUPPORTED
;
2887 RemainBlockNum
= NumberOfBlocks
;
2888 while (RemainBlockNum
> 0) {
2890 if (RemainBlockNum
>= MAX_DMA_EXT_COMMAND_SECTORS
) {
2892 // SectorCount is used to record the number of sectors to be read
2893 // Max 65536 sectors can be transfered at a time.
2895 NumberOfBlocks
= MAX_DMA_EXT_COMMAND_SECTORS
;
2896 RemainBlockNum
-= MAX_DMA_EXT_COMMAND_SECTORS
;
2898 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
2903 // Calculate the number of PRD table to make sure the memory region
2904 // not cross 64K boundary
2906 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
2907 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
2912 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
2913 Status
= IdeDev
->PciIo
->AllocateBuffer (
2916 EfiBootServicesData
,
2921 if (EFI_ERROR (Status
)) {
2922 return EFI_OUT_OF_RESOURCES
;
2924 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
2926 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
2928 // To make sure PRD is allocated in one 64K page
2930 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
2931 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
2933 if ((UINTN
) PrdAddr
& 0x03) {
2934 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
2936 UsedPrdAddr
= PrdAddr
;
2941 // Build the PRD table
2943 Status
= IdeDev
->PciIo
->Map (
2945 EfiPciIoOperationBusMasterRead
,
2951 if (EFI_ERROR (Status
)) {
2952 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
2953 return EFI_OUT_OF_RESOURCES
;
2955 PrdBuffer
= (UINT8
*) ((UINTN
) DeviceAddress
);
2956 TempPrdAddr
= UsedPrdAddr
;
2959 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
2961 if (ByteCount
<= ByteAvailable
) {
2962 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2963 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
2964 TempPrdAddr
->EndOfTable
= 0x8000;
2968 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
2969 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
2971 ByteCount
-= ByteAvailable
;
2972 PrdBuffer
+= ByteAvailable
;
2977 // Set the base address to BMID register
2979 IdeDev
->PciIo
->Io
.Write (
2981 EfiPciIoWidthUint32
,
2982 EFI_PCI_IO_PASS_THROUGH_BAR
,
2989 // Set BMIC register to identify the operation direction
2991 IdeDev
->PciIo
->Io
.Read (
2994 EFI_PCI_IO_PASS_THROUGH_BAR
,
3002 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
3004 IdeDev
->PciIo
->Io
.Write (
3007 EFI_PCI_IO_PASS_THROUGH_BAR
,
3014 // Read BMIS register and clear ERROR and INTR bit
3016 IdeDev
->PciIo
->Io
.Read (
3019 EFI_PCI_IO_PASS_THROUGH_BAR
,
3025 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
3027 IdeDev
->PciIo
->Io
.Write (
3030 EFI_PCI_IO_PASS_THROUGH_BAR
,
3037 // Issue WRITE DMA EXT command
3039 Status
= AtaCommandIssueExt (
3044 (UINT16
) NumberOfBlocks
,
3047 if (EFI_ERROR (Status
)) {
3048 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3049 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3050 return EFI_DEVICE_ERROR
;
3054 // Set START bit of BMIC register
3056 IdeDev
->PciIo
->Io
.Read (
3059 EFI_PCI_IO_PASS_THROUGH_BAR
,
3065 RegisterValue
|= BMIC_START
;
3067 IdeDev
->PciIo
->Io
.Write (
3070 EFI_PCI_IO_PASS_THROUGH_BAR
,
3077 // Check the INTERRUPT and ERROR bit of BMIS
3078 // Max transfer number of sectors for one command is 65536(32Mbyte),
3079 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
3080 // So set the variable Count to 2000, for about 2 second timeout time.
3085 IdeDev
->PciIo
->Io
.Read (
3088 EFI_PCI_IO_PASS_THROUGH_BAR
,
3093 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
3094 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
3096 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
3098 IdeDev
->PciIo
->Io
.Read (
3101 EFI_PCI_IO_PASS_THROUGH_BAR
,
3107 RegisterValue
&= ~((UINT8
)BMIC_START
);
3109 IdeDev
->PciIo
->Io
.Write (
3112 EFI_PCI_IO_PASS_THROUGH_BAR
,
3117 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3118 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3119 return EFI_DEVICE_ERROR
;
3128 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3129 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3131 // Read Status Register of IDE device to clear interrupt
3133 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
3135 // Clear START bit of BMIC register
3137 IdeDev
->PciIo
->Io
.Read (
3140 EFI_PCI_IO_PASS_THROUGH_BAR
,
3146 RegisterValue
&= ~((UINT8
) BMIC_START
);
3148 IdeDev
->PciIo
->Io
.Write (
3151 EFI_PCI_IO_PASS_THROUGH_BAR
,
3157 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
3158 StartLba
+= NumberOfBlocks
;
3162 // Disable interrupt of Select device
3164 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
3165 DeviceControl
|= IEN_L
;
3166 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
3172 This function is called by the AtaBlkIoWriteBlocks() to perform
3173 writing to media in block unit. The function has been enhanced to
3174 support >120GB access and transfer at most 65536 blocks per command
3177 pointer pointing to IDE_BLK_IO_DEV data structure, used
3178 to record all the information of the IDE device.
3180 @param[in] *DataBuffer
3181 A pointer to the source buffer for the data.
3184 The starting logical block address to write to
3185 on the device media.
3187 @param[in] NumberOfBlocks
3188 The number of transfer data blocks.
3190 @return The device status of UDMA operation. If the operation is
3191 successful, return EFI_SUCCESS.
3193 TODO: EFI_UNSUPPORTED - add return value to function comment
3194 TODO: EFI_DEVICE_ERROR - add return value to function comment
3195 TODO: EFI_DEVICE_ERROR - add return value to function comment
3199 IN IDE_BLK_IO_DEV
*IdeDev
,
3200 IN VOID
*DataBuffer
,
3201 IN EFI_LBA StartLba
,
3202 IN UINTN NumberOfBlocks
3205 IDE_DMA_PRD
*PrdAddr
;
3206 IDE_DMA_PRD
*UsedPrdAddr
;
3207 IDE_DMA_PRD
*TempPrdAddr
;
3208 UINT8 RegisterValue
;
3210 UINT64 IoPortForBmic
;
3211 UINT64 IoPortForBmis
;
3212 UINT64 IoPortForBmid
;
3216 UINTN ByteAvailable
;
3218 UINTN RemainBlockNum
;
3219 UINT8 DeviceControl
;
3224 EFI_PHYSICAL_ADDRESS DeviceAddress
;
3227 // Channel and device differential
3229 Device
= (UINT8
) ((IdeDev
->Device
<< 4) | 0xe0);
3232 // Enable interrupt to support UDMA
3235 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);
3237 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Head
, Device
);
3239 if (IdePrimary
== IdeDev
->Channel
) {
3240 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICP_OFFSET
;
3241 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISP_OFFSET
;
3242 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDP_OFFSET
;
3244 if (IdeSecondary
== IdeDev
->Channel
) {
3245 IoPortForBmic
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMICS_OFFSET
;
3246 IoPortForBmis
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMISS_OFFSET
;
3247 IoPortForBmid
= IdeDev
->IoPort
->BusMasterBaseAddr
+ BMIDS_OFFSET
;
3249 return EFI_UNSUPPORTED
;
3253 RemainBlockNum
= NumberOfBlocks
;
3254 while (RemainBlockNum
> 0) {
3256 if (RemainBlockNum
>= MAX_DMA_COMMAND_SECTORS
) {
3258 // SectorCount is used to record the number of sectors to be read
3259 // Max 256 sectors can be transfered at a time.
3261 NumberOfBlocks
= MAX_DMA_COMMAND_SECTORS
;
3262 RemainBlockNum
-= MAX_DMA_COMMAND_SECTORS
;
3264 NumberOfBlocks
= (UINT16
) RemainBlockNum
;
3269 // Calculate the number of PRD table to make sure the memory region
3270 // not cross 64K boundary
3272 ByteCount
= NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
3273 PrdTableNum
= ((ByteCount
>> 16) + 1) + 1;
3278 PageCount
= EFI_SIZE_TO_PAGES (2 * PrdTableNum
* sizeof (IDE_DMA_PRD
));
3279 Status
= IdeDev
->PciIo
->AllocateBuffer (
3282 EfiBootServicesData
,
3287 if (EFI_ERROR (Status
)) {
3288 return EFI_OUT_OF_RESOURCES
;
3290 ZeroMem ((VOID
*) ((UINTN
) MemPage
), EFI_PAGES_TO_SIZE (PageCount
));
3292 PrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) MemPage
);
3295 // To make sure PRD is allocated in one 64K page
3297 if (((UINTN
) PrdAddr
& 0x0FFFF) > (((UINTN
) PrdAddr
+ PrdTableNum
* sizeof (IDE_DMA_PRD
) - 1) & 0x0FFFF)) {
3298 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x10000) & 0xFFFF0000);
3300 if ((UINTN
) PrdAddr
& 0x03) {
3301 UsedPrdAddr
= (IDE_DMA_PRD
*) ((UINTN
) ((UINT8
*) PrdAddr
+ 0x04) & 0xFFFFFFFC);
3303 UsedPrdAddr
= PrdAddr
;
3308 // Build the PRD table
3310 Status
= IdeDev
->PciIo
->Map (
3312 EfiPciIoOperationBusMasterRead
,
3318 if (EFI_ERROR (Status
)) {
3319 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3320 return EFI_OUT_OF_RESOURCES
;
3322 PrdBuffer
= (UINT8
*) ((UINTN
) DeviceAddress
);
3323 TempPrdAddr
= UsedPrdAddr
;
3326 ByteAvailable
= 0x10000 - ((UINTN
) PrdBuffer
& 0xFFFF);
3328 if (ByteCount
<= ByteAvailable
) {
3329 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
3330 TempPrdAddr
->ByteCount
= (UINT16
) ByteCount
;
3331 TempPrdAddr
->EndOfTable
= 0x8000;
3335 TempPrdAddr
->RegionBaseAddr
= (UINT32
) ((UINTN
) PrdBuffer
);
3336 TempPrdAddr
->ByteCount
= (UINT16
) ByteAvailable
;
3338 ByteCount
-= ByteAvailable
;
3339 PrdBuffer
+= ByteAvailable
;
3344 // Set the base address to BMID register
3346 IdeDev
->PciIo
->Io
.Write (
3348 EfiPciIoWidthUint32
,
3349 EFI_PCI_IO_PASS_THROUGH_BAR
,
3356 // Set BMIC register to identify the operation direction
3358 IdeDev
->PciIo
->Io
.Read (
3361 EFI_PCI_IO_PASS_THROUGH_BAR
,
3369 RegisterValue
&= ~((UINT8
) BMIC_nREAD
);
3371 IdeDev
->PciIo
->Io
.Write (
3374 EFI_PCI_IO_PASS_THROUGH_BAR
,
3381 // Read BMIS register and clear ERROR and INTR bit
3383 IdeDev
->PciIo
->Io
.Read (
3386 EFI_PCI_IO_PASS_THROUGH_BAR
,
3392 RegisterValue
|= (BMIS_INTERRUPT
| BMIS_ERROR
);
3394 IdeDev
->PciIo
->Io
.Write (
3397 EFI_PCI_IO_PASS_THROUGH_BAR
,
3404 // Issue WRITE DMA command
3406 Status
= AtaCommandIssue (
3411 (UINT16
) NumberOfBlocks
,
3414 if (EFI_ERROR (Status
)) {
3415 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3416 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3417 return EFI_DEVICE_ERROR
;
3421 // Set START bit of BMIC register
3423 IdeDev
->PciIo
->Io
.Read (
3426 EFI_PCI_IO_PASS_THROUGH_BAR
,
3432 RegisterValue
|= BMIC_START
;
3434 IdeDev
->PciIo
->Io
.Write (
3437 EFI_PCI_IO_PASS_THROUGH_BAR
,
3444 // Check the INTERRUPT and ERROR bit of BMIS
3445 // Max transfer number of sectors for one command is 65536(32Mbyte),
3446 // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
3447 // So set the variable Count to 2000, for about 2 second timeout time.
3452 IdeDev
->PciIo
->Io
.Read (
3455 EFI_PCI_IO_PASS_THROUGH_BAR
,
3460 if ((RegisterValue
& (BMIS_INTERRUPT
| BMIS_ERROR
)) || (Count
== 0)) {
3461 if ((RegisterValue
& BMIS_ERROR
) || (Count
== 0)) {
3463 // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
3465 IdeDev
->PciIo
->Io
.Read (
3468 EFI_PCI_IO_PASS_THROUGH_BAR
,
3474 RegisterValue
&= ~((UINT8
)BMIC_START
);
3476 IdeDev
->PciIo
->Io
.Write (
3479 EFI_PCI_IO_PASS_THROUGH_BAR
,
3484 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3485 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3486 return EFI_DEVICE_ERROR
;
3495 IdeDev
->PciIo
->FreeBuffer (IdeDev
->PciIo
, PageCount
, MemPage
);
3496 IdeDev
->PciIo
->Unmap (IdeDev
->PciIo
, Map
);
3499 // Read Status Register of IDE device to clear interrupt
3501 RegisterValue
= IDEReadPortB(IdeDev
->PciIo
,IdeDev
->IoPort
->Reg
.Status
);
3503 // Clear START bit of BMIC register
3505 IdeDev
->PciIo
->Io
.Read (
3508 EFI_PCI_IO_PASS_THROUGH_BAR
,
3514 RegisterValue
&= ~((UINT8
) BMIC_START
);
3516 IdeDev
->PciIo
->Io
.Write (
3519 EFI_PCI_IO_PASS_THROUGH_BAR
,
3525 DataBuffer
= (UINT8
*) DataBuffer
+ NumberOfBlocks
* IdeDev
->BlkIo
.Media
->BlockSize
;
3526 StartLba
+= NumberOfBlocks
;
3530 // Disable interrupt of Select device
3532 IDEReadPortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
);
3533 DeviceControl
|= IEN_L
;
3534 IDEWritePortB (IdeDev
->PciIo
, IdeDev
->IoPort
->Alt
.DeviceControl
, DeviceControl
);