-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- ata.c\r
- \r
-Abstract: \r
- \r
-Revision History\r
-\r
- 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
- update - ATAIdentity() func\r
- update - AtaBlockIoReadBlocks() func\r
- update - AtaBlockIoWriteBlocks() func\r
- add - AtaAtapi6Identify() func\r
- add - AtaReadSectorsExt() func\r
- add - AtaWriteSectorsExt() func\r
- add - AtaPioDataInExt() func\r
- add - AtaPioDataOutExt() func\r
- \r
---*/\r
+/** @file\r
+ Copyright (c) 2006, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ @par Revision Reference:\r
+ 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including\r
+ update - ATAIdentity() func\r
+ update - AtaBlockIoReadBlocks() func\r
+ update - AtaBlockIoWriteBlocks() func\r
+ add - AtaAtapi6Identify() func\r
+ add - AtaReadSectorsExt() func\r
+ add - AtaWriteSectorsExt() func\r
+ add - AtaPioDataInExt() func\r
+ add - AtaPioDataOutExt() func\r
+\r
+**/\r
\r
#include "idebus.h"\r
\r
IN UINT16 SectorCount\r
);\r
\r
-EFI_STATUS\r
-ATAIdentify (\r
- IN IDE_BLK_IO_DEV *IdeDev\r
- )\r
-/*++\r
- Name:\r
- ATAIdentify\r
-\r
-\r
- Purpose: \r
- This function is called by DiscoverIdeDevice() during its device\r
- identification. It sends out the ATA Identify Command to the \r
- specified device. Only ATA device responses to this command. If \r
- the command succeeds, it returns the Identify data structure which \r
- contains information about the device. This function extracts the \r
- information it needs to fill the IDE_BLK_IO_DEV data structure, \r
- including device type, media block size, media capacity, and etc.\r
+/**\r
+ Sends out an ATA Identify Command to the specified device.\r
\r
+ This function is called by DiscoverIdeDevice() during its device\r
+ identification. It sends out the ATA Identify Command to the\r
+ specified device. Only ATA device responses to this command. If\r
+ the command succeeds, it returns the Identify data structure which\r
+ contains information about the device. This function extracts the\r
+ information it needs to fill the IDE_BLK_IO_DEV data structure,\r
+ including device type, media block size, media capacity, and etc.\r
\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
\r
+ @retval EFI_SUCCESS Identify ATA device successfully.\r
\r
- Returns: \r
- EFI_SUCCESS\r
- Identify ATA device successfully.\r
+ @retval EFI_DEVICE_ERROR ATA Identify Device Command failed or\r
+ device is not ATA device.\r
\r
- EFI_DEVICE_ERROR\r
- ATA Identify Device Command failed or device is not \r
- ATA device.\r
+ @note\r
+ parameter IdeDev will be updated in this function.\r
\r
-\r
- Notes:\r
- parameter IdeDev will be updated in this function.\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
+**/\r
+EFI_STATUS\r
+ATAIdentify (\r
+ IN IDE_BLK_IO_DEV *IdeDev\r
+ )\r
{\r
EFI_STATUS Status;\r
EFI_IDENTIFY_DATA *AtaIdentifyPointer;\r
}\r
\r
\r
+/**\r
+ This function is called by ATAIdentify() to identity whether this disk\r
+ supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS The disk specified by IdeDev is a Atapi6 supported one\r
+ and 48-bit addressing must be used\r
+\r
+ @retval EFI_UNSUPPORTED The disk dosn't not support Atapi6 or it supports but\r
+ the capacity is below 120G, 48bit addressing is not\r
+ needed\r
+\r
+ @note\r
+ This function must be called after DEVICE_IDENTITY command has been\r
+ successfully returned\r
+\r
+**/\r
EFI_STATUS\r
AtaAtapi6Identify (\r
IN IDE_BLK_IO_DEV *IdeDev\r
)\r
-/*++\r
- Name:\r
- \r
- AtaAtapi6Identify\r
-\r
- Purpose: \r
- \r
- This function is called by ATAIdentify() to identity whether this disk\r
- supports ATA/ATAPI6 48bit addressing, ie support >120G capacity\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- Returns: \r
- \r
- EFI_SUCCESS - The disk specified by IdeDev is a Atapi6 supported one\r
- and 48-bit addressing must be used\r
-\r
- EFI_UNSUPPORTED - The disk dosn't not support Atapi6 or it supports but\r
- the capacity is below 120G, 48bit addressing is not \r
- needed\r
- \r
- Notes:\r
-\r
- This function must be called after DEVICE_IDENTITY command has been \r
- successfully returned\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
{\r
UINT8 Index;\r
EFI_LBA TmpLba;\r
return EFI_UNSUPPORTED;\r
}\r
\r
+/**\r
+ This function is called by ATAIdentify() or ATAPIIdentify()\r
+ to print device's module name.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+**/\r
VOID\r
PrintAtaModuleName (\r
IN IDE_BLK_IO_DEV *IdeDev\r
)\r
-/*++\r
- Name:\r
- PrintAtaModuleName\r
-\r
-\r
- Purpose: \r
- This function is called by ATAIdentify() or ATAPIIdentify()\r
- to print device's module name. \r
-\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- Returns: \r
- no returns.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
{\r
if (IdeDev->pIdData == NULL) {\r
return ;\r
IdeDev->ModelName[40] = 0x00;\r
}\r
\r
-EFI_STATUS\r
-AtaPioDataIn (\r
- IN IDE_BLK_IO_DEV *IdeDev,\r
- IN VOID *Buffer,\r
- IN UINT32 ByteCount,\r
- IN UINT8 AtaCommand,\r
- IN UINT8 Head,\r
- IN UINT8 SectorCount,\r
- IN UINT8 SectorNumber,\r
- IN UINT8 CylinderLsb,\r
- IN UINT8 CylinderMsb\r
- )\r
-/*++\r
- Name:\r
- AtaPioDataIn\r
-\r
-\r
- Purpose: \r
- This function is used to send out ATA commands conforms to the \r
- PIO Data In Protocol.\r
-\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data In Protocol.\r
\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
\r
- VOID IN *Buffer\r
- buffer contained data transferred from device to host.\r
+ @param[in] *Buffer\r
+ buffer contained data transferred from device to host.\r
\r
- UINT32 IN ByteCount\r
- data size in byte unit of the buffer.\r
+ @param[in] ByteCount\r
+ data size in byte unit of the buffer.\r
\r
- UINT8 IN AtaCommand\r
- value of the Command Register\r
+ @param[in] AtaCommand\r
+ value of the Command Register\r
\r
- UINT8 IN Head\r
- value of the Head/Device Register\r
+ @param[in] Head\r
+ value of the Head/Device Register\r
\r
- UINT8 IN SectorCount\r
- value of the Sector Count Register\r
+ @param[in] SectorCount\r
+ value of the Sector Count Register\r
\r
- UINT8 IN SectorNumber\r
- value of the Sector Number Register\r
+ @param[in] SectorNumber\r
+ value of the Sector Number Register\r
\r
- UINT8 IN CylinderLsb\r
- value of the low byte of the Cylinder Register\r
+ @param[in] CylinderLsb\r
+ value of the low byte of the Cylinder Register\r
\r
- UINT8 IN CylinderMsb\r
- value of the high byte of the Cylinder Register\r
+ @param[in] CylinderMsb\r
+ value of the high byte of the Cylinder Register\r
\r
+ @retval EFI_SUCCESS send out the ATA command and device send required\r
+ data successfully.\r
\r
- Returns: \r
- EFI_SUCCESS\r
- send out the ATA command and device send required\r
- data successfully.\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
\r
- EFI_DEVICE_ERROR\r
- command sent failed.\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: ByteCount - add argument and description to function comment\r
-// TODO: AtaCommand - add argument and description to function comment\r
-// TODO: Head - add argument and description to function comment\r
-// TODO: SectorCount - add argument and description to function comment\r
-// TODO: SectorNumber - add argument and description to function comment\r
-// TODO: CylinderLsb - add argument and description to function comment\r
-// TODO: CylinderMsb - add argument and description to function comment\r
+**/\r
+EFI_STATUS\r
+AtaPioDataIn (\r
+ IN IDE_BLK_IO_DEV *IdeDev,\r
+ IN VOID *Buffer,\r
+ IN UINT32 ByteCount,\r
+ IN UINT8 AtaCommand,\r
+ IN UINT8 Head,\r
+ IN UINT8 SectorCount,\r
+ IN UINT8 SectorNumber,\r
+ IN UINT8 CylinderLsb,\r
+ IN UINT8 CylinderMsb\r
+ )\r
{\r
UINTN WordCount;\r
UINTN Increment;\r
return CheckErrorStatus (IdeDev);\r
}\r
\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data Out Protocol.\r
+\r
+ @param *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param *Buffer buffer contained data transferred from host to device.\r
+ @param ByteCount data size in byte unit of the buffer.\r
+ @param AtaCommand value of the Command Register\r
+ @param Head value of the Head/Device Register\r
+ @param SectorCount value of the Sector Count Register\r
+ @param SectorNumber value of the Sector Number Register\r
+ @param CylinderLsb value of the low byte of the Cylinder Register\r
+ @param CylinderMsb value of the high byte of the Cylinder Register\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device received required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
EFI_STATUS\r
AtaPioDataOut (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN UINT8 CylinderLsb,\r
IN UINT8 CylinderMsb\r
)\r
-/*++\r
- Name:\r
- AtaPioDataOut\r
-\r
-\r
- Purpose: \r
- This function is used to send out ATA commands conforms to the \r
- PIO Data Out Protocol.\r
-\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *Buffer\r
- buffer contained data transferred from host to device.\r
-\r
- UINT32 IN ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- UINT8 IN AtaCommand\r
- value of the Command Register\r
-\r
- UINT8 IN Head\r
- value of the Head/Device Register\r
-\r
- UINT8 IN SectorCount\r
- value of the Sector Count Register\r
-\r
- UINT8 IN SectorNumber\r
- value of the Sector Number Register\r
-\r
- UINT8 IN CylinderLsb\r
- value of the low byte of the Cylinder Register\r
-\r
- UINT8 IN CylinderMsb\r
- value of the high byte of the Cylinder Register\r
-\r
-\r
- Returns: \r
- EFI_SUCCESS\r
- send out the ATA command and device received required\r
- data successfully.\r
-\r
- EFI_DEVICE_ERROR\r
- command sent failed. \r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: ByteCount - add argument and description to function comment\r
-// TODO: AtaCommand - add argument and description to function comment\r
-// TODO: Head - add argument and description to function comment\r
-// TODO: SectorCount - add argument and description to function comment\r
-// TODO: SectorNumber - add argument and description to function comment\r
-// TODO: CylinderLsb - add argument and description to function comment\r
-// TODO: CylinderMsb - add argument and description to function comment\r
{\r
UINTN WordCount;\r
UINTN Increment;\r
WordCount = 0;\r
\r
while (WordCount < ByteCount / 2) {\r
- \r
+\r
//\r
// DRQReady2-- read Alternate Status Register to determine the DRQ bit\r
// data transfer can be performed only when DRQ is ready.\r
//\r
// perform a series of write without check DRQ ready\r
//\r
- \r
+\r
IDEWritePortWMultiple (\r
IdeDev->PciIo,\r
IdeDev->IoPort->Data,\r
return CheckErrorStatus (IdeDev);\r
}\r
\r
+/**\r
+ This function is used to analyze the Status Register and print out\r
+ some debug information and if there is ERR bit set in the Status\r
+ Register, the Error Register's value is also be parsed and print out.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS No err information in the Status Register.\r
+ @retval EFI_DEVICE_ERROR Any err information in the Status Register.\r
+\r
+**/\r
EFI_STATUS\r
CheckErrorStatus (\r
IN IDE_BLK_IO_DEV *IdeDev\r
)\r
-/*++\r
- Name:\r
- CheckErrorStatus\r
-\r
-\r
- Purpose: \r
- This function is used to analyze the Status Register and print out \r
- some debug information and if there is ERR bit set in the Status\r
- Register, the Error Register's value is also be parsed and print out.\r
-\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- Returns: \r
- EFI_SUCCESS\r
- No err information in the Status Register.\r
-\r
- EFI_DEVICE_ERROR\r
- Any err information in the Status Register.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
{\r
UINT8 StatusRegister;\r
\r
\r
StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
\r
if (StatusRegister & DWF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
- StatusRegister)\r
- );\r
- }\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & CORR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
- StatusRegister)\r
- );\r
- }\r
+ if (StatusRegister & CORR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & ERR) {\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if (StatusRegister & ERR) {\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
\r
- if (ErrorRegister & BBK_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & BBK_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & UNC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & UNC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & MC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & MC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & ABRT_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Abort\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & ABRT_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Abort\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & TK0NF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & TK0NF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & AMNF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & AMNF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+ }\r
\r
- }\r
- );\r
+ DEBUG_CODE_END ();\r
\r
if ((StatusRegister & (ERR | DWF | CORR)) == 0) {\r
return EFI_SUCCESS;\r
\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the destination buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to read from\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataIn() function.\r
+\r
+**/\r
EFI_STATUS\r
AtaReadSectors (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA Lba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- AtaReadSectors\r
-\r
-\r
- Purpose: \r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit.\r
-\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the destination buffer for the data. \r
-\r
- EFI_LBA IN Lba\r
- The starting logical block address to read from \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
- return status is fully dependent on the return status\r
- of AtaPioDataIn() function.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: Lba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
{\r
EFI_STATUS Status;\r
UINTN BlocksRemaining;\r
//\r
AtaCommand = READ_SECTORS_CMD;\r
\r
- \r
+\r
BlocksRemaining = NumberOfBlocks;\r
\r
Lba32 = (UINT32) Lba;\r
Status = EFI_SUCCESS;\r
\r
while (BlocksRemaining > 0) {\r
- \r
+\r
//\r
// in ATA-3 spec, LBA is in 28 bit width\r
//\r
Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
\r
if (BlocksRemaining >= 0x100) {\r
- \r
+\r
//\r
// SectorCount8 is sent to Sector Count register, 0x00 means 256\r
// sectors to be read\r
return Status;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing onto media in block unit.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *BufferData\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to write onto\r
+ the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataOut() function.\r
+\r
+**/\r
EFI_STATUS\r
AtaWriteSectors (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA Lba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- AtaWriteSectors\r
-\r
-\r
- Purpose: \r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing onto media in block unit.\r
-\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *BufferData\r
- A pointer to the source buffer for the data. \r
-\r
- EFI_LBA IN Lba\r
- The starting logical block address to write onto \r
- the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
-\r
- Returns: \r
- return status is fully dependent on the return status\r
- of AtaPioDataOut() function.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: BufferData - add argument and description to function comment\r
-// TODO: Lba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
{\r
EFI_STATUS Status;\r
UINTN BlocksRemaining;\r
Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);\r
\r
if (BlocksRemaining >= 0x100) {\r
- \r
+\r
//\r
// SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors\r
// to be written\r
return Status;\r
}\r
\r
+/**\r
+ This function is used to implement the Soft Reset on the specified\r
+ device. But, the ATA Soft Reset mechanism is so strong a reset method\r
+ that it will force resetting on both devices connected to the\r
+ same cable.\r
+\r
+ It is called by IdeBlkIoReset(), a interface function of Block\r
+ I/O protocol.\r
+\r
+ This function can also be used by the ATAPI device to perform reset when\r
+ ATAPI Reset command is failed.\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @retval EFI_SUCCESS Soft reset completes successfully.\r
+ @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
+\r
+ @note\r
+ The registers initial values after ATA soft reset are different\r
+ to the ATA device and ATAPI device.\r
+\r
+**/\r
EFI_STATUS\r
AtaSoftReset (\r
IN IDE_BLK_IO_DEV *IdeDev\r
)\r
-/*++\r
- Name:\r
- AtaSoftReset\r
-\r
- Purpose: \r
- This function is used to implement the Soft Reset on the specified\r
- device. But, the ATA Soft Reset mechanism is so strong a reset method \r
- that it will force resetting on both devices connected to the \r
- same cable.\r
- It is called by IdeBlkIoReset(), a interface function of Block\r
- I/O protocol.\r
- This function can also be used by the ATAPI device to perform reset when\r
- ATAPI Reset command is failed.\r
- \r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
- Returns: \r
- EFI_SUCCESS\r
- Soft reset completes successfully.\r
-\r
- EFI_DEVICE_ERROR\r
- Any step during the reset process is failed.\r
- Notes:\r
- The registers initial values after ATA soft reset are different\r
- to the ATA device and ATAPI device.\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
{\r
\r
UINT8 DeviceControl;\r
\r
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
\r
+ //\r
+ // SRST should assert for at least 5 us, we use 10 us for\r
+ // better compatibility\r
+ //\r
gBS->Stall (10);\r
\r
//\r
DeviceControl = 0;\r
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
\r
+ //\r
+ // Wait for at least 2 ms to check BSY status, we use 10 ms\r
+ // for better compatibility\r
+ //\r
+ gBS->Stall(10000);\r
//\r
// slave device needs at most 31s to clear BSY\r
//\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-AtaBlkIoReadBlocks (\r
- IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
- IN UINT32 MediaId,\r
- IN EFI_LBA LBA,\r
- IN UINTN BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-/*++\r
- Name:\r
- AtaBlkIoReadBlocks\r
-\r
-\r
- Purpose: \r
- This function is the ATA implementation for ReadBlocks in the\r
- Block I/O Protocol interface.\r
+/**\r
+ This function is the ATA implementation for ReadBlocks in the\r
+ Block I/O Protocol interface.\r
\r
+ @param[in] *IdeBlkIoDevice\r
+ Indicates the calling context.\r
\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeBlkIoDevice\r
- Indicates the calling context.\r
+ @param[in] MediaId\r
+ The media id that the read request is for.\r
\r
- UINT32 IN MediaId\r
- The media id that the read request is for.\r
+ @param[in] LBA\r
+ The starting logical block address to read from\r
+ on the device.\r
\r
- EFI_LBA IN LBA\r
- The starting logical block address to read from \r
- on the device.\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
\r
- UINTN IN BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
+ @param[out] *Buffer\r
+ A pointer to the destination buffer for the data.\r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is read into.\r
\r
- VOID OUT *Buffer\r
- A pointer to the destination buffer for the data. \r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is read into.\r
+ @retval EFI_SUCCESS Read Blocks successfully.\r
+ @retval EFI_DEVICE_ERROR Read Blocks failed.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
\r
- Returns: \r
- EFI_SUCCESS \r
- Read Blocks successfully.\r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
\r
- EFI_DEVICE_ERROR\r
- Read Blocks failed.\r
+ @retval EFI_INVALID_PARAMETER\r
+ The read request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
\r
- EFI_NO_MEDIA\r
- There is no media in the device.\r
+ @note\r
+ If Read Block error because of device error, this function will call\r
+ AtaSoftReset() function to reset device.\r
\r
- EFI_MEDIA_CHANGE\r
- The MediaId is not for the current media.\r
-\r
- EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the \r
- intrinsic block size of the device.\r
-\r
- EFI_INVALID_PARAMETER\r
- The read request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
- Notes:\r
- If Read Block error because of device error, this function will call\r
- AtaSoftReset() function to reset device.\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeBlkIoDevice - add argument and description to function comment\r
-// TODO: MediaId - add argument and description to function comment\r
-// TODO: LBA - add argument and description to function comment\r
-// TODO: BufferSize - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_MEDIA_CHANGED - add return value to function comment\r
+**/\r
+EFI_STATUS\r
+AtaBlkIoReadBlocks (\r
+ IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA LBA,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
{\r
EFI_BLOCK_IO_MEDIA *Media;\r
UINTN BlockSize;\r
} else {\r
//\r
// For ATA-3 compatible device, use ATA-3 read block mechanism\r
- // Notice DMA operation can only handle 32bit address\r
//\r
- if ((UINTN) Buffer <= 0xFFFFFFFF) {\r
- Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- }\r
-\r
- if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {\r
+ Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
+ if (EFI_ERROR (Status)) {\r
Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
}\r
}\r
\r
}\r
\r
+/**\r
+ This function is the ATA implementation for WriteBlocks in the\r
+ Block I/O Protocol interface.\r
+\r
+ @param[in] *IdeBlkIoDevice\r
+ Indicates the calling context.\r
+\r
+ @param[in] MediaId\r
+ The media id that the write request is for.\r
+\r
+ @param[in] LBA\r
+ The starting logical block address to write onto\r
+ the device.\r
+\r
+ @param[in] BufferSize\r
+ The size of the Buffer in bytes. This must be a\r
+ multiple of the intrinsic block size of the device.\r
+\r
+ @param[out] *Buffer\r
+ A pointer to the source buffer for the data.\r
+ The caller is responsible for either having implicit\r
+ or explicit ownership of the memory that data is\r
+ written from.\r
+\r
+ @retval EFI_SUCCESS Write Blocks successfully.\r
+ @retval EFI_DEVICE_ERROR Write Blocks failed.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGE The MediaId is not for the current media.\r
+\r
+ @retval EFI_BAD_BUFFER_SIZE\r
+ The BufferSize parameter is not a multiple of the\r
+ intrinsic block size of the device.\r
+\r
+ @retval EFI_INVALID_PARAMETER\r
+ The write request contains LBAs that are not valid,\r
+ or the data buffer is not valid.\r
+\r
+ @note\r
+ If Write Block error because of device error, this function will call\r
+ AtaSoftReset() function to reset device.\r
+\r
+**/\r
EFI_STATUS\r
AtaBlkIoWriteBlocks (\r
IN IDE_BLK_IO_DEV *IdeBlkIoDevice,\r
IN UINTN BufferSize,\r
OUT VOID *Buffer\r
)\r
-/*++\r
- Name:\r
- AtaBlkIoWriteBlocks\r
-\r
-\r
- Purpose: \r
- This function is the ATA implementation for WriteBlocks in the\r
- Block I/O Protocol interface.\r
-\r
- Parameters:\r
- IDE_BLK_IO_DEV IN *IdeBlkIoDevice\r
- Indicates the calling context.\r
-\r
- UINT32 IN MediaId\r
- The media id that the write request is for.\r
-\r
- EFI_LBA IN LBA\r
- The starting logical block address to write onto \r
- the device.\r
-\r
- UINTN IN BufferSize\r
- The size of the Buffer in bytes. This must be a\r
- multiple of the intrinsic block size of the device.\r
-\r
- VOID OUT *Buffer\r
- A pointer to the source buffer for the data. \r
- The caller is responsible for either having implicit\r
- or explicit ownership of the memory that data is \r
- written from.\r
-\r
-\r
- Returns: \r
- EFI_SUCCESS \r
- Write Blocks successfully.\r
-\r
- EFI_DEVICE_ERROR\r
- Write Blocks failed.\r
-\r
- EFI_NO_MEDIA\r
- There is no media in the device.\r
-\r
- EFI_MEDIA_CHANGE\r
- The MediaId is not for the current media.\r
-\r
- EFI_BAD_BUFFER_SIZE\r
- The BufferSize parameter is not a multiple of the \r
- intrinsic block size of the device.\r
-\r
- EFI_INVALID_PARAMETER\r
- The write request contains LBAs that are not valid,\r
- or the data buffer is not valid.\r
-\r
- Notes:\r
- If Write Block error because of device error, this function will call\r
- AtaSoftReset() function to reset device.\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeBlkIoDevice - add argument and description to function comment\r
-// TODO: MediaId - add argument and description to function comment\r
-// TODO: LBA - add argument and description to function comment\r
-// TODO: BufferSize - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: EFI_MEDIA_CHANGED - add return value to function comment\r
{\r
\r
EFI_BLOCK_IO_MEDIA *Media;\r
// For ATA-3 compatible device, use ATA-3 write block mechanism\r
//\r
Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
- if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {\r
+ if (EFI_ERROR (Status)) {\r
Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);\r
}\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return return status is fully dependent on the return status\r
+ of AtaPioDataInExt() function.\r
+\r
+**/\r
EFI_STATUS\r
AtaReadSectorsExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaReadSectorsExt\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the destination buffer for the data. \r
-\r
- EFI_LBA IN StartLba\r
- The starting logical block address to read from \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
- \r
- return status is fully dependent on the return status\r
- of AtaPioDataInExt() function.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
{\r
EFI_STATUS Status;\r
UINTN BlocksRemaining;\r
return Status;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing onto media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] Lba\r
+ The starting logical block address to write onto\r
+ the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return status is fully dependent on the return status\r
+ of AtaPioDataOutExt() function.\r
+\r
+**/\r
EFI_STATUS\r
AtaWriteSectorsExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaWriteSectorsExt\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing onto media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the source buffer for the data. \r
-\r
- EFI_LBA IN Lba\r
- The starting logical block address to write onto \r
- the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
- \r
- return status is fully dependent on the return status\r
- of AtaPioDataOutExt() function.\r
-\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
{\r
EFI_STATUS Status;\r
EFI_LBA Lba64;\r
return Status;\r
}\r
\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data In Protocol, supporting ATA/ATAPI-6 standard\r
+\r
+ Comparing with ATA-3 data in protocol, we have two differents here:<BR>\r
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+ wait will frequently fail... cause writing function return error)\r
+\r
+ 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+ slow down writing performance by 100 times!)\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in,out] *Buffer buffer contained data transferred from device to host.\r
+ @param[in] ByteCount data size in byte unit of the buffer.\r
+ @param[in] AtaCommand value of the Command Register\r
+ @param[in] StartLba the start LBA of this transaction\r
+ @param[in] SectorCount the count of sectors to be transfered\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device send required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
EFI_STATUS\r
AtaPioDataInExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINT16 SectorCount\r
)\r
-/*++\r
- Name:\r
- \r
- AtaPioDataInExt\r
-\r
- Purpose: \r
- \r
- This function is used to send out ATA commands conforms to the \r
- PIO Data In Protocol, supporting ATA/ATAPI-6 standard\r
-\r
- Comparing with ATA-3 data in protocol, we have two differents here:\r
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
- wait will frequently fail... cause writing function return error)\r
- \r
- 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly \r
- slow down writing performance by 100 times!)\r
-\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN OUT *Buffer\r
- buffer contained data transferred from device to host.\r
-\r
- UINT32 IN ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- UINT8 IN AtaCommand\r
- value of the Command Register\r
-\r
- EFI_LBA IN StartLba\r
- the start LBA of this transaction\r
- \r
- UINT16 IN SectorCount\r
- the count of sectors to be transfered\r
-\r
- Returns: \r
- \r
- EFI_SUCCESS\r
- send out the ATA command and device send required\r
- data successfully.\r
-\r
- EFI_DEVICE_ERROR\r
- command sent failed.\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: ByteCount - add argument and description to function comment\r
-// TODO: AtaCommand - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: SectorCount - add argument and description to function comment\r
{\r
UINT8 DevSel;\r
UINT8 SectorCount8;\r
// According to PIO data in protocol, host can perform a series of reads to\r
// the data register after each time device set DRQ ready;\r
//\r
- \r
+\r
//\r
// 256 words\r
//\r
return CheckErrorStatus (IdeDev);\r
}\r
\r
+/**\r
+ This function is used to send out ATA commands conforms to the\r
+ PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
+\r
+ Comparing with ATA-3 data out protocol, we have two differents here:<BR>\r
+ 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
+ wait will frequently fail... cause writing function return error)\r
+\r
+ 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly\r
+ slow down writing performance by 100 times!)\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *Buffer buffer contained data transferred from host to device.\r
+ @param[in] ByteCount data size in byte unit of the buffer.\r
+ @param[in] AtaCommand value of the Command Register\r
+ @param[in] StartLba the start LBA of this transaction\r
+ @param[in] SectorCount the count of sectors to be transfered\r
+\r
+ @retval EFI_SUCCESS send out the ATA command and device receive required\r
+ data successfully.\r
+\r
+ @retval EFI_DEVICE_ERROR command sent failed.\r
+\r
+**/\r
EFI_STATUS\r
AtaPioDataOutExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINT16 SectorCount\r
)\r
-/*++\r
- Name:\r
- \r
- AtaPioDataOutExt\r
-\r
- Purpose: \r
- \r
- This function is used to send out ATA commands conforms to the \r
- PIO Data Out Protocol, supporting ATA/ATAPI-6 standard\r
-\r
- Comparing with ATA-3 data out protocol, we have two differents here:\r
- 1. Do NOT wait for DRQ clear before sending command into IDE device.(the\r
- wait will frequently fail... cause writing function return error)\r
- \r
- 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly \r
- slow down writing performance by 100 times!)\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *Buffer\r
- buffer contained data transferred from host to device.\r
-\r
- UINT32 IN ByteCount\r
- data size in byte unit of the buffer.\r
-\r
- UINT8 IN AtaCommand\r
- value of the Command Register\r
-\r
- EFI_LBA IN StartLba\r
- the start LBA of this transaction\r
- \r
- UINT16 IN SectorCount\r
- the count of sectors to be transfered\r
-\r
- Returns: \r
- \r
- EFI_SUCCESS\r
- send out the ATA command and device receive required\r
- data successfully.\r
-\r
- EFI_DEVICE_ERROR\r
- command sent failed.\r
- Notes:\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: Buffer - add argument and description to function comment\r
-// TODO: ByteCount - add argument and description to function comment\r
-// TODO: AtaCommand - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: SectorCount - add argument and description to function comment\r
{\r
UINT8 DevSel;\r
UINT8 SectorCount8;\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
- \r
+\r
//\r
// Fill feature register if needed\r
//\r
}\r
\r
\r
+/**\r
+ Enable SMART of the disk if supported\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure,used\r
+ to record all the information of the IDE device.\r
+\r
+**/\r
VOID\r
AtaSMARTSupport (\r
IN IDE_BLK_IO_DEV *IdeDev\r
)\r
-/*++\r
- Name: \r
- AtaSMARTSupport\r
-\r
- Purpose: \r
-\r
- Enable SMART of the disk if supported\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure,used\r
- to record all the information of the IDE device.\r
-\r
- Returns: \r
- \r
- NONE\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
{\r
EFI_STATUS Status;\r
BOOLEAN SMARTSupported;\r
return ;\r
}\r
\r
+/**\r
+ Send ATA Ext command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaAddress The LBA address in 48-bit mode\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_DEVICE_ERROR Error executing commands on this device\r
+\r
+**/\r
EFI_STATUS\r
AtaCommandIssueExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN UINT16 SectorCount,\r
IN EFI_LBA LbaAddress\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Send ATA Ext command into device with NON_DATA protocol\r
-\r
-Arguments:\r
-\r
- IdeDev - Standard IDE device private data structure\r
- AtaCommand - The ATA command to be sent\r
- Device - The value in Device register\r
- Feature - The value in Feature register\r
- SectorCount - The value in SectorCount register \r
- LbaAddress - The LBA address in 48-bit mode\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Reading succeed\r
- EFI_DEVICE_ERROR - Error executing commands on this device \r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
UINT8 SectorCount8;\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Send ATA Ext command into device with NON_DATA protocol\r
+\r
+ @param IdeDev Standard IDE device private data structure\r
+ @param AtaCommand The ATA command to be sent\r
+ @param Device The value in Device register\r
+ @param Feature The value in Feature register\r
+ @param SectorCount The value in SectorCount register\r
+ @param LbaAddress The LBA address in 48-bit mode\r
+\r
+ @retval EFI_SUCCESS Reading succeed\r
+ @retval EFI_DEVICE_ERROR Error executing commands on this device\r
+\r
+**/\r
EFI_STATUS\r
AtaCommandIssue (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN UINT16 SectorCount,\r
IN EFI_LBA LbaAddress\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Send ATA Ext command into device with NON_DATA protocol\r
-\r
-Arguments:\r
-\r
- IdeDev - Standard IDE device private data structure\r
- AtaCommand - The ATA command to be sent\r
- Device - The value in Device register\r
- Feature - The value in Feature register\r
- SectorCount - The value in SectorCount register \r
- LbaAddress - The LBA address in 48-bit mode\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Reading succeed\r
- EFI_DEVICE_ERROR - Error executing commands on this device \r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
UINT8 SectorCount8;\r
//\r
// Fill the start LBA registers, which are also two-byte FIFO\r
//\r
- \r
+\r
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);\r
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);\r
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
EFI_STATUS\r
AtaUdmaReadExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaUdmaReadExt\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the destination buffer for the data. \r
-\r
- EFI_LBA IN StartLba\r
- The starting logical block address to read from \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
-\r
- The device status of UDMA operation. If the operation is \r
- successful, return EFI_SUCCESS.\r
-\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
{\r
- IDE_DMA_PRD *PrdAddr;\r
- IDE_DMA_PRD *UsedPrdAddr;\r
- IDE_DMA_PRD *TempPrdAddr;\r
- UINT8 RegisterValue;\r
- UINT8 Device;\r
- UINT64 IoPortForBmic;\r
- UINT64 IoPortForBmis;\r
- UINT64 IoPortForBmid;\r
- EFI_STATUS Status;\r
- UINTN PrdTableNum;\r
- UINTN ByteCount;\r
- UINTN ByteAvailable;\r
- UINT8 *PrdBuffer;\r
- UINTN RemainBlockNum;\r
- UINT8 DeviceControl;\r
+ IDE_DMA_PRD *PrdAddr;\r
+ IDE_DMA_PRD *UsedPrdAddr;\r
+ IDE_DMA_PRD *TempPrdAddr;\r
+ UINT8 RegisterValue;\r
+ UINT8 Device;\r
+ UINT64 IoPortForBmic;\r
+ UINT64 IoPortForBmis;\r
+ UINT64 IoPortForBmid;\r
+ EFI_STATUS Status;\r
+ UINTN PrdTableNum;\r
+ UINTN ByteCount;\r
+ UINTN ByteAvailable;\r
+ UINT8 *PrdBuffer;\r
+ UINTN RemainBlockNum;\r
+ UINT8 DeviceControl;\r
+ UINT32 Count;\r
+ UINTN PageCount;\r
+ VOID *Map;\r
+ VOID *MemPage;\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
\r
//\r
// Channel and device differential. Select device.\r
//\r
// Build PRD table\r
//\r
- PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));\r
+ PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+ Status = IdeDev->PciIo->AllocateBuffer (\r
+ IdeDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ PageCount,\r
+ &MemPage,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
+\r
+ PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
\r
//\r
// To make sure PRD is allocated in one 64K page\r
//\r
// Build the PRD table\r
//\r
- PrdBuffer = DataBuffer;\r
+ Status = IdeDev->PciIo->Map (\r
+ IdeDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ DataBuffer,\r
+ &ByteCount,\r
+ &DeviceAddress,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PrdBuffer = (VOID *) ((UINTN) DeviceAddress);\r
TempPrdAddr = UsedPrdAddr;\r
while (TRUE) {\r
\r
PrdBuffer += ByteAvailable;\r
TempPrdAddr++;\r
}\r
- \r
+\r
//\r
// Set the base address to BMID register\r
//\r
// Issue READ DMA EXT command\r
//\r
Status = AtaCommandIssueExt (\r
- IdeDev,\r
- READ_DMA_EXT_CMD,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
+ IdeDev,\r
+ READ_DMA_EXT_CMD,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (PrdAddr);\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
\r
\r
//\r
// Check the INTERRUPT and ERROR bit of BMIS\r
+ // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+ // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+ // So set the variable Count to 2000, for about 2 second timeout time.\r
//\r
+ Count = 2000;\r
while (TRUE) {\r
\r
IdeDev->PciIo->Io.Read (\r
1,\r
&RegisterValue\r
);\r
- if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {\r
- if (RegisterValue & BMIS_ERROR) {\r
- gBS->FreePool (PrdAddr);\r
+ if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
+ if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
+ //\r
+ // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8)BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
break;\r
}\r
\r
gBS->Stall (1000);\r
+ Count --;\r
}\r
\r
- gBS->FreePool (PrdAddr);\r
-\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
//\r
- // Set START bit of BMIC register\r
+ // Read Status Register of IDE device to clear interrupt\r
+ //\r
+ RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // Clear START bit of BMIC register\r
//\r
IdeDev->PciIo->Io.Read (\r
IdeDev->PciIo,\r
StartLba += NumberOfBlocks;\r
}\r
\r
+ //\r
+ // Disable interrupt of Select device\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+ DeviceControl |= IEN_L;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoReadBlocks() to perform\r
+ reading from media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the destination buffer for the data.\r
+ @param[in] StartLba The starting logical block address to read from\r
+ on the device media.\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
EFI_STATUS\r
AtaUdmaRead (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaUdmaRead\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoReadBlocks() to perform\r
- reading from media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the destination buffer for the data. \r
-\r
- EFI_LBA IN StartLba\r
- The starting logical block address to read from \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
-\r
- The device status of UDMA operation. If the operation is \r
- successful, return EFI_SUCCESS.\r
-\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
{\r
- IDE_DMA_PRD *PrdAddr;\r
- IDE_DMA_PRD *UsedPrdAddr;\r
- IDE_DMA_PRD *TempPrdAddr;\r
- UINT8 RegisterValue;\r
- UINT8 Device;\r
- UINT64 IoPortForBmic;\r
- UINT64 IoPortForBmis;\r
- UINT64 IoPortForBmid;\r
- EFI_STATUS Status;\r
- UINTN PrdTableNum;\r
- UINTN ByteCount;\r
- UINTN ByteAvailable;\r
- UINT8 *PrdBuffer;\r
- UINTN RemainBlockNum;\r
- UINT8 DeviceControl;\r
+ IDE_DMA_PRD *PrdAddr;\r
+ IDE_DMA_PRD *UsedPrdAddr;\r
+ IDE_DMA_PRD *TempPrdAddr;\r
+ UINT8 RegisterValue;\r
+ UINT8 Device;\r
+ UINT64 IoPortForBmic;\r
+ UINT64 IoPortForBmis;\r
+ UINT64 IoPortForBmid;\r
+ EFI_STATUS Status;\r
+ UINTN PrdTableNum;\r
+ UINTN ByteCount;\r
+ UINTN ByteAvailable;\r
+ UINT8 *PrdBuffer;\r
+ UINTN RemainBlockNum;\r
+ UINT8 DeviceControl;\r
+ UINT32 Count;\r
+ UINTN PageCount;\r
+ VOID *Map;\r
+ VOID *MemPage;\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
\r
//\r
// Channel and device differential\r
//\r
// Build PRD table\r
//\r
- PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));\r
+ PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+ Status = IdeDev->PciIo->AllocateBuffer (\r
+ IdeDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ PageCount,\r
+ &MemPage,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
+\r
+ PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
//\r
// To make sure PRD is allocated in one 64K page\r
//\r
//\r
// Build the PRD table\r
//\r
- PrdBuffer = DataBuffer;\r
+ Status = IdeDev->PciIo->Map (\r
+ IdeDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ DataBuffer,\r
+ &ByteCount,\r
+ &DeviceAddress,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);\r
TempPrdAddr = UsedPrdAddr;\r
while (TRUE) {\r
\r
// Issue READ DMA command\r
//\r
Status = AtaCommandIssue (\r
- IdeDev,\r
- READ_DMA_CMD,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
+ IdeDev,\r
+ READ_DMA_CMD,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (PrdAddr);\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
\r
\r
//\r
// Check the INTERRUPT and ERROR bit of BMIS\r
+ // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+ // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+ // So set the variable Count to 2000, for about 2 second timeout time.\r
//\r
+ Count = 2000;\r
while (TRUE) {\r
\r
IdeDev->PciIo->Io.Read (\r
1,\r
&RegisterValue\r
);\r
- if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {\r
- if (RegisterValue & BMIS_ERROR) {\r
- gBS->FreePool (PrdAddr);\r
+ if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
+ if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
+ //\r
+ // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8)BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
break;\r
}\r
\r
gBS->Stall (1000);\r
+ Count --;\r
}\r
\r
- gBS->FreePool (PrdAddr);\r
-\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
//\r
- // Set START bit of BMIC register\r
+ // Read Status Register of IDE device to clear interrupt\r
+ //\r
+ RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // Clear START bit of BMIC register\r
//\r
IdeDev->PciIo->Io.Read (\r
IdeDev->PciIo,\r
StartLba += NumberOfBlocks;\r
}\r
\r
+ //\r
+ // Disable interrupt of Select device\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+ DeviceControl |= IEN_L;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing to media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
EFI_STATUS\r
AtaUdmaWriteExt (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaUdmaWriteExt\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing to media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the source buffer for the data. \r
-\r
- EFI_LBA IN StartLba\r
- The starting logical block address to write to \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
-\r
- The device status of UDMA operation. If the operation is \r
- successful, return EFI_SUCCESS.\r
-\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
{\r
- IDE_DMA_PRD *PrdAddr;\r
- IDE_DMA_PRD *UsedPrdAddr;\r
- IDE_DMA_PRD *TempPrdAddr;\r
- UINT8 RegisterValue;\r
- UINT8 Device;\r
- UINT64 IoPortForBmic;\r
- UINT64 IoPortForBmis;\r
- UINT64 IoPortForBmid;\r
- EFI_STATUS Status;\r
- UINTN PrdTableNum;\r
- UINTN ByteCount;\r
- UINTN ByteAvailable;\r
- UINT8 *PrdBuffer;\r
- UINTN RemainBlockNum;\r
- UINT8 DeviceControl;\r
+ IDE_DMA_PRD *PrdAddr;\r
+ IDE_DMA_PRD *UsedPrdAddr;\r
+ IDE_DMA_PRD *TempPrdAddr;\r
+ UINT8 RegisterValue;\r
+ UINT8 Device;\r
+ UINT64 IoPortForBmic;\r
+ UINT64 IoPortForBmis;\r
+ UINT64 IoPortForBmid;\r
+ EFI_STATUS Status;\r
+ UINTN PrdTableNum;\r
+ UINTN ByteCount;\r
+ UINTN ByteAvailable;\r
+ UINT8 *PrdBuffer;\r
+ UINTN RemainBlockNum;\r
+ UINT8 DeviceControl;\r
+ UINT32 Count;\r
+ UINTN PageCount;\r
+ VOID *Map;\r
+ VOID *MemPage;\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
\r
//\r
// Channel and device differential\r
//\r
// Build PRD table\r
//\r
- PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));\r
+ PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+ Status = IdeDev->PciIo->AllocateBuffer (\r
+ IdeDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ PageCount,\r
+ &MemPage,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
+\r
+ PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
//\r
// To make sure PRD is allocated in one 64K page\r
//\r
//\r
// Build the PRD table\r
//\r
- PrdBuffer = DataBuffer;\r
+ Status = IdeDev->PciIo->Map (\r
+ IdeDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ DataBuffer,\r
+ &ByteCount,\r
+ &DeviceAddress,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);\r
TempPrdAddr = UsedPrdAddr;\r
while (TRUE) {\r
\r
PrdBuffer += ByteAvailable;\r
TempPrdAddr++;\r
}\r
- \r
+\r
//\r
// Set the base address to BMID register\r
//\r
// Issue WRITE DMA EXT command\r
//\r
Status = AtaCommandIssueExt (\r
- IdeDev,\r
- WRITE_DMA_EXT_CMD,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
+ IdeDev,\r
+ WRITE_DMA_EXT_CMD,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (PrdAddr);\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
\r
\r
//\r
// Check the INTERRUPT and ERROR bit of BMIS\r
+ // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+ // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+ // So set the variable Count to 2000, for about 2 second timeout time.\r
//\r
+ Count = 2000;\r
while (TRUE) {\r
\r
IdeDev->PciIo->Io.Read (\r
1,\r
&RegisterValue\r
);\r
- if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {\r
- if (RegisterValue & BMIS_ERROR) {\r
- gBS->FreePool (PrdAddr);\r
+ if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
+ if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
+ //\r
+ // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8)BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
break;\r
}\r
\r
gBS->Stall (1000);\r
+ Count --;\r
}\r
\r
- gBS->FreePool (PrdAddr);\r
-\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
//\r
- // Set START bit of BMIC register\r
+ // Read Status Register of IDE device to clear interrupt\r
+ //\r
+ RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // Clear START bit of BMIC register\r
//\r
IdeDev->PciIo->Io.Read (\r
IdeDev->PciIo,\r
StartLba += NumberOfBlocks;\r
}\r
\r
+ //\r
+ // Disable interrupt of Select device\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+ DeviceControl |= IEN_L;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function is called by the AtaBlkIoWriteBlocks() to perform\r
+ writing to media in block unit. The function has been enhanced to\r
+ support >120GB access and transfer at most 65536 blocks per command\r
+\r
+ @param[in] *IdeDev\r
+ pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+ to record all the information of the IDE device.\r
+\r
+ @param[in] *DataBuffer\r
+ A pointer to the source buffer for the data.\r
+\r
+ @param[in] StartLba\r
+ The starting logical block address to write to\r
+ on the device media.\r
+\r
+ @param[in] NumberOfBlocks\r
+ The number of transfer data blocks.\r
+\r
+ @return The device status of UDMA operation. If the operation is\r
+ successful, return EFI_SUCCESS.\r
+\r
+ TODO: EFI_UNSUPPORTED - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+ TODO: EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
EFI_STATUS\r
AtaUdmaWrite (\r
IN IDE_BLK_IO_DEV *IdeDev,\r
IN EFI_LBA StartLba,\r
IN UINTN NumberOfBlocks\r
)\r
-/*++\r
- Name:\r
- \r
- AtaUdmaWrite\r
-\r
- Purpose: \r
- \r
- This function is called by the AtaBlkIoWriteBlocks() to perform\r
- writing to media in block unit. The function has been enhanced to \r
- support >120GB access and transfer at most 65536 blocks per command\r
-\r
- Parameters:\r
- \r
- IDE_BLK_IO_DEV IN *IdeDev\r
- pointer pointing to IDE_BLK_IO_DEV data structure, used\r
- to record all the information of the IDE device.\r
-\r
- VOID IN *DataBuffer\r
- A pointer to the source buffer for the data. \r
-\r
- EFI_LBA IN StartLba\r
- The starting logical block address to write to \r
- on the device media.\r
-\r
- UINTN IN NumberOfBlocks\r
- The number of transfer data blocks.\r
-\r
- Returns: \r
-\r
- The device status of UDMA operation. If the operation is \r
- successful, return EFI_SUCCESS.\r
-\r
---*/\r
-// TODO: function comment is missing 'Routine Description:'\r
-// TODO: function comment is missing 'Arguments:'\r
-// TODO: IdeDev - add argument and description to function comment\r
-// TODO: DataBuffer - add argument and description to function comment\r
-// TODO: StartLba - add argument and description to function comment\r
-// TODO: NumberOfBlocks - add argument and description to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
{\r
- IDE_DMA_PRD *PrdAddr;\r
- IDE_DMA_PRD *UsedPrdAddr;\r
- IDE_DMA_PRD *TempPrdAddr;\r
- UINT8 RegisterValue;\r
- UINT8 Device;\r
- UINT64 IoPortForBmic;\r
- UINT64 IoPortForBmis;\r
- UINT64 IoPortForBmid;\r
- EFI_STATUS Status;\r
- UINTN PrdTableNum;\r
- UINTN ByteCount;\r
- UINTN ByteAvailable;\r
- UINT8 *PrdBuffer;\r
- UINTN RemainBlockNum;\r
- UINT8 DeviceControl;\r
+ IDE_DMA_PRD *PrdAddr;\r
+ IDE_DMA_PRD *UsedPrdAddr;\r
+ IDE_DMA_PRD *TempPrdAddr;\r
+ UINT8 RegisterValue;\r
+ UINT8 Device;\r
+ UINT64 IoPortForBmic;\r
+ UINT64 IoPortForBmis;\r
+ UINT64 IoPortForBmid;\r
+ EFI_STATUS Status;\r
+ UINTN PrdTableNum;\r
+ UINTN ByteCount;\r
+ UINTN ByteAvailable;\r
+ UINT8 *PrdBuffer;\r
+ UINTN RemainBlockNum;\r
+ UINT8 DeviceControl;\r
+ UINT32 Count;\r
+ UINTN PageCount;\r
+ VOID *Map;\r
+ VOID *MemPage;\r
+ EFI_PHYSICAL_ADDRESS DeviceAddress;\r
\r
//\r
// Channel and device differential\r
//\r
// Build PRD table\r
//\r
- PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));\r
+ PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));\r
+ Status = IdeDev->PciIo->AllocateBuffer (\r
+ IdeDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ PageCount,\r
+ &MemPage,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));\r
+\r
+ PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);\r
\r
//\r
// To make sure PRD is allocated in one 64K page\r
//\r
// Build the PRD table\r
//\r
- PrdBuffer = DataBuffer;\r
+ Status = IdeDev->PciIo->Map (\r
+ IdeDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ DataBuffer,\r
+ &ByteCount,\r
+ &DeviceAddress,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);\r
TempPrdAddr = UsedPrdAddr;\r
while (TRUE) {\r
\r
PrdBuffer += ByteAvailable;\r
TempPrdAddr++;\r
}\r
- \r
+\r
//\r
// Set the base address to BMID register\r
//\r
// Issue WRITE DMA command\r
//\r
Status = AtaCommandIssue (\r
- IdeDev,\r
- WRITE_DMA_CMD,\r
- Device,\r
- 0,\r
- (UINT16) NumberOfBlocks,\r
- StartLba\r
- );\r
+ IdeDev,\r
+ WRITE_DMA_CMD,\r
+ Device,\r
+ 0,\r
+ (UINT16) NumberOfBlocks,\r
+ StartLba\r
+ );\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (PrdAddr);\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
\r
\r
//\r
// Check the INTERRUPT and ERROR bit of BMIS\r
+ // Max transfer number of sectors for one command is 65536(32Mbyte),\r
+ // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
+ // So set the variable Count to 2000, for about 2 second timeout time.\r
//\r
+ Count = 2000;\r
while (TRUE) {\r
\r
IdeDev->PciIo->Io.Read (\r
1,\r
&RegisterValue\r
);\r
- if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {\r
- if (RegisterValue & BMIS_ERROR) {\r
- gBS->FreePool (PrdAddr);\r
+ if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {\r
+ if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {\r
+ //\r
+ // Clear START bit of BMIC register before return EFI_DEVICE_ERROR\r
+ //\r
+ IdeDev->PciIo->Io.Read (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+\r
+ RegisterValue &= ~((UINT8)BMIC_START);\r
+\r
+ IdeDev->PciIo->Io.Write (\r
+ IdeDev->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ EFI_PCI_IO_PASS_THROUGH_BAR,\r
+ IoPortForBmic,\r
+ 1,\r
+ &RegisterValue\r
+ );\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
return EFI_DEVICE_ERROR;\r
}\r
break;\r
}\r
\r
gBS->Stall (1000);\r
+ Count --;\r
}\r
\r
- gBS->FreePool (PrdAddr);\r
+ IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);\r
+ IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);\r
\r
//\r
- // Set START bit of BMIC register\r
+ // Read Status Register of IDE device to clear interrupt\r
+ //\r
+ RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);\r
+ //\r
+ // Clear START bit of BMIC register\r
//\r
IdeDev->PciIo->Io.Read (\r
IdeDev->PciIo,\r
StartLba += NumberOfBlocks;\r
}\r
\r
+ //\r
+ // Disable interrupt of Select device\r
+ //\r
+ IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);\r
+ DeviceControl |= IEN_L;\r
+ IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);\r
+\r
return EFI_SUCCESS;\r
}\r