summaryrefslogtreecommitdiff
path: root/EdkModulePkg
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-03-09 09:04:53 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-03-09 09:04:53 +0000
commit27061085e5a9c5cf2dc9a6781fd6795989c4f790 (patch)
tree12e07a97804e2a06e763299e388b57daf0abb64b /EdkModulePkg
parent17fb73c8e164fd9a91cef8408c9c2dcdb95a6d3c (diff)
downloadedk2-platforms-27061085e5a9c5cf2dc9a6781fd6795989c4f790.tar.xz
The latest IPF boot failure is found and is not caused by this fixing, so check-in the fixing again.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2434 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg')
-rw-r--r--EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c1213
-rw-r--r--EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h38
-rw-r--r--EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c8
-rw-r--r--EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h4
-rw-r--r--EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h9
5 files changed, 206 insertions, 1066 deletions
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
index aea126b3e6..382c0691ba 100644
--- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
+++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
@@ -1,5 +1,5 @@
/** @file
- Copyright (c) 2006, Intel Corporation
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1075,20 +1075,23 @@ AtaBlkIoReadBlocks (
return EFI_INVALID_PARAMETER;
}
+ Status = EFI_SUCCESS;
if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
//
// For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
//
- Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- if (EFI_ERROR (Status)) {
+ if (IdeBlkIoDevice->UdmaMode.Valid) {
+ Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ } else {
Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
} else {
//
// For ATA-3 compatible device, use ATA-3 read block mechanism
//
- Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- if (EFI_ERROR (Status)) {
+ if (IdeBlkIoDevice->UdmaMode.Valid) {
+ Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ } else {
Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
}
@@ -1196,20 +1199,23 @@ AtaBlkIoWriteBlocks (
return EFI_INVALID_PARAMETER;
}
+ Status = EFI_SUCCESS;
if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
//
// For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
//
- Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- if (EFI_ERROR (Status)) {
+ if (IdeBlkIoDevice->UdmaMode.Valid) {
+ Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ } else {
Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
} else {
//
// For ATA-3 compatible device, use ATA-3 write block mechanism
//
- Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- if (EFI_ERROR (Status)) {
+ if (IdeBlkIoDevice->UdmaMode.Valid) {
+ Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ } else {
Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
}
@@ -2107,339 +2113,7 @@ AtaUdmaReadExt (
IN UINTN NumberOfBlocks
)
{
- IDE_DMA_PRD *PrdAddr;
- IDE_DMA_PRD *UsedPrdAddr;
- IDE_DMA_PRD *TempPrdAddr;
- UINT8 RegisterValue;
- UINT8 Device;
- UINT64 IoPortForBmic;
- UINT64 IoPortForBmis;
- UINT64 IoPortForBmid;
- EFI_STATUS Status;
- UINTN PrdTableNum;
- UINTN ByteCount;
- UINTN ByteAvailable;
- UINT8 *PrdBuffer;
- UINTN RemainBlockNum;
- UINT8 DeviceControl;
- UINT32 Count;
- UINTN PageCount;
- VOID *Map;
- VOID *MemPage;
- EFI_PHYSICAL_ADDRESS DeviceAddress;
-
- //
- // Channel and device differential. Select device.
- //
- Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
-
- //
- // Enable interrupt to support UDMA and Select device
- //
- DeviceControl = 0;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
-
- if (IdePrimary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
- } else {
- if (IdeSecondary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
- } else {
- return EFI_UNSUPPORTED;
- }
- }
-
- RemainBlockNum = NumberOfBlocks;
- while (RemainBlockNum > 0) {
-
- if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {
- //
- // SectorCount is used to record the number of sectors to be read
- // Max 65536 sectors can be transfered at a time.
- //
- NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;
- RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;
- } else {
- NumberOfBlocks = (UINT16) RemainBlockNum;
- RemainBlockNum = 0;
- }
-
- //
- // Calculate the number of PRD table to make sure the memory region
- // not cross 64K boundary
- //
- ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- PrdTableNum = ((ByteCount >> 16) + 1) + 1;
-
- //
- // Build PRD table
- //
- PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));
- Status = IdeDev->PciIo->AllocateBuffer (
- IdeDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- PageCount,
- &MemPage,
- 0
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));
-
- PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);
-
- //
- // To make sure PRD is allocated in one 64K page
- //
- if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
- } else {
- if ((UINTN) PrdAddr & 0x03) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
- } else {
- UsedPrdAddr = PrdAddr;
- }
- }
-
- //
- // Build the PRD table
- //
- Status = IdeDev->PciIo->Map (
- IdeDev->PciIo,
- EfiPciIoOperationBusMasterWrite,
- DataBuffer,
- &ByteCount,
- &DeviceAddress,
- &Map
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- return EFI_OUT_OF_RESOURCES;
- }
- PrdBuffer = (VOID *) ((UINTN) DeviceAddress);
- TempPrdAddr = UsedPrdAddr;
- while (TRUE) {
-
- ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
-
- if (ByteCount <= ByteAvailable) {
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteCount;
- TempPrdAddr->EndOfTable = 0x8000;
- break;
- }
-
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
-
- ByteCount -= ByteAvailable;
- PrdBuffer += ByteAvailable;
- TempPrdAddr++;
- }
-
- //
- // Set the base address to BMID register
- //
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint32,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmid,
- 1,
- &UsedPrdAddr
- );
-
- //
- // Set BMIC register to identify the operation direction
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIC_nREAD;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Read BMIS register and clear ERROR and INTR bit
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIS_INTERRUPT | BMIS_ERROR;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- //
- // Issue READ DMA EXT command
- //
- Status = AtaCommandIssueExt (
- IdeDev,
- READ_DMA_EXT_CMD,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Set START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIC_START;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Check the INTERRUPT and ERROR bit of BMIS
- // Max transfer number of sectors for one command is 65536(32Mbyte),
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
- // So set the variable Count to 2000, for about 2 second timeout time.
- //
- Count = 2000;
- while (TRUE) {
-
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
- if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
- if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
- //
- // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8)BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
- break;
- }
-
- gBS->Stall (1000);
- Count --;
- }
-
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- //
- // Read Status Register of IDE device to clear interrupt
- //
- RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
- //
- // Clear START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8) BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- if (RegisterValue & BMIS_ERROR) {
- return EFI_DEVICE_ERROR;
- }
-
- DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- StartLba += NumberOfBlocks;
- }
-
- //
- // Disable interrupt of Select device
- //
- IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);
- DeviceControl |= IEN_L;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- return EFI_SUCCESS;
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);
}
/**
@@ -2472,338 +2146,7 @@ AtaUdmaRead (
IN UINTN NumberOfBlocks
)
{
- IDE_DMA_PRD *PrdAddr;
- IDE_DMA_PRD *UsedPrdAddr;
- IDE_DMA_PRD *TempPrdAddr;
- UINT8 RegisterValue;
- UINT8 Device;
- UINT64 IoPortForBmic;
- UINT64 IoPortForBmis;
- UINT64 IoPortForBmid;
- EFI_STATUS Status;
- UINTN PrdTableNum;
- UINTN ByteCount;
- UINTN ByteAvailable;
- UINT8 *PrdBuffer;
- UINTN RemainBlockNum;
- UINT8 DeviceControl;
- UINT32 Count;
- UINTN PageCount;
- VOID *Map;
- VOID *MemPage;
- EFI_PHYSICAL_ADDRESS DeviceAddress;
-
- //
- // Channel and device differential
- //
- Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
-
- //
- // Enable interrupt to support UDMA and Select device
- //
- DeviceControl = 0;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
-
- if (IdePrimary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
- } else {
- if (IdeSecondary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
- } else {
- return EFI_UNSUPPORTED;
- }
- }
-
- RemainBlockNum = NumberOfBlocks;
- while (RemainBlockNum > 0) {
-
- if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {
- //
- // SectorCount is used to record the number of sectors to be read
- // Max 256 sectors can be transfered at a time.
- //
- NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;
- RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;
- } else {
- NumberOfBlocks = (UINT16) RemainBlockNum;
- RemainBlockNum = 0;
- }
-
- //
- // Calculate the number of PRD table to make sure the memory region
- // not cross 64K boundary
- //
- ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- PrdTableNum = ((ByteCount >> 16) + 1) + 1;
-
- //
- // Build PRD table
- //
- PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));
- Status = IdeDev->PciIo->AllocateBuffer (
- IdeDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- PageCount,
- &MemPage,
- 0
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));
-
- PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);
- //
- // To make sure PRD is allocated in one 64K page
- //
- if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
- } else {
- if ((UINTN) PrdAddr & 0x03) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
- } else {
- UsedPrdAddr = PrdAddr;
- }
- }
-
- //
- // Build the PRD table
- //
- Status = IdeDev->PciIo->Map (
- IdeDev->PciIo,
- EfiPciIoOperationBusMasterWrite,
- DataBuffer,
- &ByteCount,
- &DeviceAddress,
- &Map
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- return EFI_OUT_OF_RESOURCES;
- }
- PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);
- TempPrdAddr = UsedPrdAddr;
- while (TRUE) {
-
- ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
-
- if (ByteCount <= ByteAvailable) {
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteCount;
- TempPrdAddr->EndOfTable = 0x8000;
- break;
- }
-
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
-
- ByteCount -= ByteAvailable;
- PrdBuffer += ByteAvailable;
- TempPrdAddr++;
- }
-
- //
- // Set the base address to BMID register
- //
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint32,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmid,
- 1,
- &UsedPrdAddr
- );
-
- //
- // Set BMIC register to identify the operation direction
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIC_nREAD;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Read BMIS register and clear ERROR and INTR bit
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- //
- // Issue READ DMA command
- //
- Status = AtaCommandIssue (
- IdeDev,
- READ_DMA_CMD,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Set START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIC_START;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Check the INTERRUPT and ERROR bit of BMIS
- // Max transfer number of sectors for one command is 65536(32Mbyte),
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
- // So set the variable Count to 2000, for about 2 second timeout time.
- //
- Count = 2000;
- while (TRUE) {
-
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
- if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
- if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
- //
- // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8)BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
- break;
- }
-
- gBS->Stall (1000);
- Count --;
- }
-
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- //
- // Read Status Register of IDE device to clear interrupt
- //
- RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
- //
- // Clear START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8) BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- if (RegisterValue & BMIS_ERROR) {
- return EFI_DEVICE_ERROR;
- }
-
- DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- StartLba += NumberOfBlocks;
- }
-
- //
- // Disable interrupt of Select device
- //
- IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);
- DeviceControl |= IEN_L;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- return EFI_SUCCESS;
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);
}
/**
@@ -2836,336 +2179,7 @@ AtaUdmaWriteExt (
IN UINTN NumberOfBlocks
)
{
- IDE_DMA_PRD *PrdAddr;
- IDE_DMA_PRD *UsedPrdAddr;
- IDE_DMA_PRD *TempPrdAddr;
- UINT8 RegisterValue;
- UINT8 Device;
- UINT64 IoPortForBmic;
- UINT64 IoPortForBmis;
- UINT64 IoPortForBmid;
- EFI_STATUS Status;
- UINTN PrdTableNum;
- UINTN ByteCount;
- UINTN ByteAvailable;
- UINT8 *PrdBuffer;
- UINTN RemainBlockNum;
- UINT8 DeviceControl;
- UINT32 Count;
- UINTN PageCount;
- VOID *Map;
- VOID *MemPage;
- EFI_PHYSICAL_ADDRESS DeviceAddress;
-
- //
- // Channel and device differential
- //
- Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
-
- //
- // Enable interrupt to support UDMA and Select device
- //
- DeviceControl = 0;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
-
- if (IdePrimary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
- } else {
- if (IdeSecondary == IdeDev->Channel) {
- IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
- IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
- IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
- } else {
- return EFI_UNSUPPORTED;
- }
- }
-
- RemainBlockNum = NumberOfBlocks;
- while (RemainBlockNum > 0) {
-
- if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {
- //
- // SectorCount is used to record the number of sectors to be read
- // Max 65536 sectors can be transfered at a time.
- //
- NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;
- RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;
- } else {
- NumberOfBlocks = (UINT16) RemainBlockNum;
- RemainBlockNum = 0;
- }
-
- //
- // Calculate the number of PRD table to make sure the memory region
- // not cross 64K boundary
- //
- ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- PrdTableNum = ((ByteCount >> 16) + 1) + 1;
-
- //
- // Build PRD table
- //
- PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));
- Status = IdeDev->PciIo->AllocateBuffer (
- IdeDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- PageCount,
- &MemPage,
- 0
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));
-
- PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);
- //
- // To make sure PRD is allocated in one 64K page
- //
- if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
- } else {
- if ((UINTN) PrdAddr & 0x03) {
- UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
- } else {
- UsedPrdAddr = PrdAddr;
- }
- }
-
- //
- // Build the PRD table
- //
- Status = IdeDev->PciIo->Map (
- IdeDev->PciIo,
- EfiPciIoOperationBusMasterRead,
- DataBuffer,
- &ByteCount,
- &DeviceAddress,
- &Map
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- return EFI_OUT_OF_RESOURCES;
- }
- PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);
- TempPrdAddr = UsedPrdAddr;
- while (TRUE) {
-
- ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
-
- if (ByteCount <= ByteAvailable) {
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteCount;
- TempPrdAddr->EndOfTable = 0x8000;
- break;
- }
-
- TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
- TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
-
- ByteCount -= ByteAvailable;
- PrdBuffer += ByteAvailable;
- TempPrdAddr++;
- }
-
- //
- // Set the base address to BMID register
- //
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint32,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmid,
- 1,
- &UsedPrdAddr
- );
-
- //
- // Set BMIC register to identify the operation direction
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
- //
- // 0000 1000
- //
- RegisterValue &= ~((UINT8) BMIC_nREAD);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Read BMIS register and clear ERROR and INTR bit
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
-
- //
- // Issue WRITE DMA EXT command
- //
- Status = AtaCommandIssueExt (
- IdeDev,
- WRITE_DMA_EXT_CMD,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
- if (EFI_ERROR (Status)) {
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Set START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue |= BMIC_START;
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- //
- // Check the INTERRUPT and ERROR bit of BMIS
- // Max transfer number of sectors for one command is 65536(32Mbyte),
- // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).
- // So set the variable Count to 2000, for about 2 second timeout time.
- //
- Count = 2000;
- while (TRUE) {
-
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmis,
- 1,
- &RegisterValue
- );
- if ((RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) || (Count == 0)) {
- if ((RegisterValue & BMIS_ERROR) || (Count == 0)) {
- //
- // Clear START bit of BMIC register before return EFI_DEVICE_ERROR
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8)BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- return EFI_DEVICE_ERROR;
- }
- break;
- }
-
- gBS->Stall (1000);
- Count --;
- }
-
- IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
- IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
- //
- // Read Status Register of IDE device to clear interrupt
- //
- RegisterValue = IDEReadPortB(IdeDev->PciIo,IdeDev->IoPort->Reg.Status);
- //
- // Clear START bit of BMIC register
- //
- IdeDev->PciIo->Io.Read (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- RegisterValue &= ~((UINT8) BMIC_START);
-
- IdeDev->PciIo->Io.Write (
- IdeDev->PciIo,
- EfiPciIoWidthUint8,
- EFI_PCI_IO_PASS_THROUGH_BAR,
- IoPortForBmic,
- 1,
- &RegisterValue
- );
-
- DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
- StartLba += NumberOfBlocks;
- }
-
- //
- // Disable interrupt of Select device
- //
- IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl);
- DeviceControl |= IEN_L;
- IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
-
- return EFI_SUCCESS;
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);
}
/**
@@ -3202,26 +2216,92 @@ AtaUdmaWrite (
IN UINTN NumberOfBlocks
)
{
- IDE_DMA_PRD *PrdAddr;
- IDE_DMA_PRD *UsedPrdAddr;
- IDE_DMA_PRD *TempPrdAddr;
- UINT8 RegisterValue;
- UINT8 Device;
- UINT64 IoPortForBmic;
- UINT64 IoPortForBmis;
- UINT64 IoPortForBmid;
- EFI_STATUS Status;
- UINTN PrdTableNum;
- UINTN ByteCount;
- UINTN ByteAvailable;
- UINT8 *PrdBuffer;
- UINTN RemainBlockNum;
- UINT8 DeviceControl;
- UINT32 Count;
- UINTN PageCount;
- VOID *Map;
- VOID *MemPage;
- EFI_PHYSICAL_ADDRESS DeviceAddress;
+ return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteOp);
+}
+
+/**
+ Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
+
+ @param[in] *IdeDev
+ pointer pointing to IDE_BLK_IO_DEV data structure, used
+ to record all the information of the IDE device.
+
+ @param[in] *DataBuffer
+ A pointer to the source buffer for the data.
+
+ @param[in] StartLba
+ The starting logical block address to write to
+ on the device media.
+
+ @param[in] NumberOfBlocks
+ The number of transfer data blocks.
+
+ @param[in] UdmaOp
+ The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
+ AtaUdmaWriteOp, AtaUdmaWriteExOp
+
+ @return The device status of UDMA operation. If the operation is
+ successful, return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+DoAtaUdma (
+ IN IDE_BLK_IO_DEV *IdeDev,
+ IN VOID *DataBuffer,
+ IN EFI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN ATA_UDMA_OPERATION UdmaOp
+ )
+{
+ IDE_DMA_PRD *PrdAddr;
+ IDE_DMA_PRD *UsedPrdAddr;
+ IDE_DMA_PRD *TempPrdAddr;
+ UINT8 RegisterValue;
+ UINT8 Device;
+ UINT64 IoPortForBmic;
+ UINT64 IoPortForBmis;
+ UINT64 IoPortForBmid;
+ EFI_STATUS Status;
+ UINTN PrdTableNum;
+ UINTN ByteCount;
+ UINTN ByteAvailable;
+ UINT8 *PrdBuffer;
+ UINTN RemainBlockNum;
+ UINT8 DeviceControl;
+ UINT32 Count;
+ UINTN PageCount;
+ VOID *Map;
+ VOID *MemPage;
+ EFI_PHYSICAL_ADDRESS DeviceAddress;
+ UINTN MaxDmaCommandSectors;
+ EFI_PCI_IO_PROTOCOL_OPERATION PciIoProtocolOp;
+ UINT8 AtaCommand;
+
+ switch (UdmaOp) {
+ case AtaUdmaReadOp:
+ MaxDmaCommandSectors = MAX_DMA_COMMAND_SECTORS;
+ PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;
+ AtaCommand = READ_DMA_CMD;
+ break;
+ case AtaUdmaReadExtOp:
+ MaxDmaCommandSectors = MAX_DMA_EXT_COMMAND_SECTORS;
+ PciIoProtocolOp = EfiPciIoOperationBusMasterWrite;
+ AtaCommand = READ_DMA_EXT_CMD;
+ break;
+ case AtaUdmaWriteOp:
+ MaxDmaCommandSectors = MAX_DMA_COMMAND_SECTORS;
+ PciIoProtocolOp = EfiPciIoOperationBusMasterRead;
+ AtaCommand = WRITE_DMA_CMD;
+ break;
+ case AtaUdmaWriteExtOp:
+ MaxDmaCommandSectors = MAX_DMA_EXT_COMMAND_SECTORS;
+ PciIoProtocolOp = EfiPciIoOperationBusMasterRead;
+ AtaCommand = WRITE_DMA_EXT_CMD;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ break;
+ }
//
// Channel and device differential
@@ -3229,7 +2309,7 @@ AtaUdmaWrite (
Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
//
- // Enable interrupt to support UDMA
+ // Enable interrupt to support UDMA and Select device
//
DeviceControl = 0;
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
@@ -3253,13 +2333,13 @@ AtaUdmaWrite (
RemainBlockNum = NumberOfBlocks;
while (RemainBlockNum > 0) {
- if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {
+ if (RemainBlockNum >= MaxDmaCommandSectors) {
//
// SectorCount is used to record the number of sectors to be read
- // Max 256 sectors can be transfered at a time.
+ // Max 65536 sectors can be transfered at a time.
//
- NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;
- RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;
+ NumberOfBlocks = MaxDmaCommandSectors;
+ RemainBlockNum -= MaxDmaCommandSectors;
} else {
NumberOfBlocks = (UINT16) RemainBlockNum;
RemainBlockNum = 0;
@@ -3277,20 +2357,19 @@ AtaUdmaWrite (
//
PageCount = EFI_SIZE_TO_PAGES (2 * PrdTableNum * sizeof (IDE_DMA_PRD));
Status = IdeDev->PciIo->AllocateBuffer (
- IdeDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- PageCount,
- &MemPage,
- 0
- );
+ IdeDev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ PageCount,
+ &MemPage,
+ 0
+ );
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
ZeroMem ((VOID *) ((UINTN) MemPage), EFI_PAGES_TO_SIZE (PageCount));
-
+
PrdAddr = (IDE_DMA_PRD *) ((UINTN) MemPage);
-
//
// To make sure PRD is allocated in one 64K page
//
@@ -3308,18 +2387,18 @@ AtaUdmaWrite (
// Build the PRD table
//
Status = IdeDev->PciIo->Map (
- IdeDev->PciIo,
- EfiPciIoOperationBusMasterRead,
- DataBuffer,
- &ByteCount,
+ IdeDev->PciIo,
+ PciIoProtocolOp,
+ DataBuffer,
+ &ByteCount,
&DeviceAddress,
&Map
);
if (EFI_ERROR (Status)) {
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
return EFI_OUT_OF_RESOURCES;
- }
- PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);
+ }
+ PrdBuffer = (VOID *) ((UINTN) DeviceAddress);
TempPrdAddr = UsedPrdAddr;
while (TRUE) {
@@ -3363,10 +2442,12 @@ AtaUdmaWrite (
1,
&RegisterValue
);
- //
- // 0000 1000
- //
- RegisterValue &= ~((UINT8) BMIC_nREAD);
+
+ if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {
+ RegisterValue |= BMIC_nREAD;
+ } else {
+ RegisterValue &= ~((UINT8) BMIC_nREAD);
+ }
IdeDev->PciIo->Io.Write (
IdeDev->PciIo,
@@ -3400,17 +2481,26 @@ AtaUdmaWrite (
&RegisterValue
);
- //
- // Issue WRITE DMA command
- //
- Status = AtaCommandIssue (
- IdeDev,
- WRITE_DMA_CMD,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
+ if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {
+ Status = AtaCommandIssueExt (
+ IdeDev,
+ AtaCommand,
+ Device,
+ 0,
+ (UINT16) NumberOfBlocks,
+ StartLba
+ );
+ } else {
+ Status = AtaCommandIssue (
+ IdeDev,
+ AtaCommand,
+ Device,
+ 0,
+ (UINT16) NumberOfBlocks,
+ StartLba
+ );
+ }
+
if (EFI_ERROR (Status)) {
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
@@ -3494,7 +2584,6 @@ AtaUdmaWrite (
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
-
//
// Read Status Register of IDE device to clear interrupt
//
@@ -3522,6 +2611,10 @@ AtaUdmaWrite (
&RegisterValue
);
+ if (RegisterValue & BMIS_ERROR) {
+ return EFI_DEVICE_ERROR;
+ }
+
DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
StartLba += NumberOfBlocks;
}
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h
index b83a82a9fb..ec1f9e07a0 100644
--- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h
+++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h
@@ -2,7 +2,7 @@
Header file for IDE Bus Driver, containing the helper functions'
entire prototype.
- Copyright (c) 2006, Intel Corporation
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1098,6 +1098,42 @@ AtaUdmaWriteExt (
;
/**
+ Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
+
+ @param[in] *IdeDev
+ pointer pointing to IDE_BLK_IO_DEV data structure, used
+ to record all the information of the IDE device.
+
+ @param[in] *DataBuffer
+ A pointer to the source buffer for the data.
+
+ @param[in] StartLba
+ The starting logical block address to write to
+ on the device media.
+
+ @param[in] NumberOfBlocks
+ The number of transfer data blocks.
+
+ @param[in] UdmaOp
+ The perform operations could be AtaUdmaReadOp, AtaUdmaReadExOp,
+ AtaUdmaWriteOp, AtaUdmaWriteExOp
+
+ @return The device status of UDMA operation. If the operation is
+ successful, return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+DoAtaUdma (
+ IN IDE_BLK_IO_DEV *IdeDev,
+ IN VOID *DataBuffer,
+ IN EFI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN ATA_UDMA_OPERATION UdmaOp
+ )
+;
+
+
+/**
TODO: Add function description
@param IdeDev TODO: add argument description
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
index 0e7d43eeb9..42d71b5c22 100644
--- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
+++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c
@@ -1,5 +1,5 @@
/** @file
- Copyright (c) 2006, Intel Corporation
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -629,7 +629,11 @@ IDEBusDriverBindingStart (
IdeBlkIoDevicePtr = NULL;
continue;
}
-
+ //
+ // Record Udma Mode
+ //
+ IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
+ IdeBlkIoDevicePtr->UdmaMode.Mode = SupportedModes->UdmaMode.Mode;
EnableInterrupt (IdeBlkIoDevicePtr);
} else if (SupportedModes->MultiWordDmaMode.Valid) {
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h
index 52c1f266b1..0b680bd6e6 100644
--- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h
+++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h
@@ -1,7 +1,7 @@
/** @file
Header file for IDE Bus Driver.
- Copyright (c) 2006, Intel Corporation
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -65,7 +65,7 @@ typedef struct {
INQUIRY_DATA *pInquiryData;
EFI_IDENTIFY_DATA *pIdData;
ATA_PIO_MODE PioMode;
- ATA_UDMA_MODE UDma_Mode;
+ EFI_ATA_MODE UdmaMode;
CHAR8 ModelName[41];
REQUEST_SENSE_DATA *SenseData;
UINT8 SenseDataNumber;
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h
index ec088dcfa6..277e74fcc0 100644
--- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h
+++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h
@@ -1,7 +1,7 @@
/** @file
Header file for IDE Bus Driver's Data Structures
- Copyright (c) 2006, Intel Corporation
+ Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -86,6 +86,13 @@ typedef enum {
SenseOtherSense
} SENSE_RESULT;
+typedef enum {
+ AtaUdmaReadOp,
+ AtaUdmaReadExtOp,
+ AtaUdmaWriteOp,
+ AtaUdmaWriteExtOp
+} ATA_UDMA_OPERATION;
+
//
// IDE Registers
//