diff options
author | xli24 <xli24@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-03-07 09:34:54 +0000 |
---|---|---|
committer | xli24 <xli24@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-03-07 09:34:54 +0000 |
commit | 64b41a0710cb8bea96daca72c6339e6b19e54c89 (patch) | |
tree | e3234cd690120d5943f1afc0c7809f8824034bd2 /EdkModulePkg/Bus | |
parent | dba086cc525ec3ac1d4f5a7c9aed2df9dd46c874 (diff) | |
download | edk2-64b41a0710cb8bea96daca72c6339e6b19e54c89.zip edk2-64b41a0710cb8bea96daca72c6339e6b19e54c89.tar.gz edk2-64b41a0710cb8bea96daca72c6339e6b19e54c89.tar.bz2 |
Fix the issue of Linux cannot boot and reset on IPF.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2423 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Bus')
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c | 1211 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h | 36 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c | 6 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h | 2 | ||||
-rw-r--r-- | EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h | 7 |
5 files changed, 1061 insertions, 201 deletions
diff --git a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c index 44e7347..aea126b 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c @@ -1075,23 +1075,20 @@ 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
//
- if (IdeBlkIoDevice->UdmaMode.Valid) {
- Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- } else {
+ Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
} else {
//
// For ATA-3 compatible device, use ATA-3 read block mechanism
//
- if (IdeBlkIoDevice->UdmaMode.Valid) {
- Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- } else {
+ Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
}
@@ -1199,23 +1196,20 @@ 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
//
- if (IdeBlkIoDevice->UdmaMode.Valid) {
- Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- } else {
+ Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
} else {
//
// For ATA-3 compatible device, use ATA-3 write block mechanism
//
- if (IdeBlkIoDevice->UdmaMode.Valid) {
- Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
- } else {
+ Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
}
}
@@ -2113,7 +2107,339 @@ AtaUdmaReadExt ( IN UINTN NumberOfBlocks
)
{
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadExtOp);
+ 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;
}
/**
@@ -2146,7 +2472,338 @@ AtaUdmaRead ( IN UINTN NumberOfBlocks
)
{
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaReadOp);
+ 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;
}
/**
@@ -2179,7 +2836,336 @@ AtaUdmaWriteExt ( IN UINTN NumberOfBlocks
)
{
- return DoAtaUdma (IdeDev, DataBuffer, StartLba, NumberOfBlocks, AtaUdmaWriteExtOp);
+ 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;
}
/**
@@ -2216,92 +3202,26 @@ AtaUdmaWrite ( IN UINTN NumberOfBlocks
)
{
- 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;
- }
+ 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
@@ -2309,7 +3229,7 @@ DoAtaUdma ( Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
//
- // Enable interrupt to support UDMA and Select device
+ // Enable interrupt to support UDMA
//
DeviceControl = 0;
IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
@@ -2333,13 +3253,13 @@ DoAtaUdma ( RemainBlockNum = NumberOfBlocks;
while (RemainBlockNum > 0) {
- if (RemainBlockNum >= MaxDmaCommandSectors) {
+ if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {
//
// SectorCount is used to record the number of sectors to be read
- // Max 65536 sectors can be transfered at a time.
+ // Max 256 sectors can be transfered at a time.
//
- NumberOfBlocks = MaxDmaCommandSectors;
- RemainBlockNum -= MaxDmaCommandSectors;
+ NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;
+ RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;
} else {
NumberOfBlocks = (UINT16) RemainBlockNum;
RemainBlockNum = 0;
@@ -2357,19 +3277,20 @@ DoAtaUdma ( //
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
//
@@ -2387,18 +3308,18 @@ DoAtaUdma ( // Build the PRD table
//
Status = IdeDev->PciIo->Map (
- IdeDev->PciIo,
- PciIoProtocolOp,
- DataBuffer,
- &ByteCount,
+ IdeDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ DataBuffer,
+ &ByteCount,
&DeviceAddress,
&Map
);
if (EFI_ERROR (Status)) {
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
return EFI_OUT_OF_RESOURCES;
- }
- PrdBuffer = (VOID *) ((UINTN) DeviceAddress);
+ }
+ PrdBuffer = (UINT8 *) ((UINTN) DeviceAddress);
TempPrdAddr = UsedPrdAddr;
while (TRUE) {
@@ -2442,12 +3363,10 @@ DoAtaUdma ( 1,
&RegisterValue
);
-
- if (UdmaOp == AtaUdmaReadExtOp || UdmaOp == AtaUdmaReadOp) {
- RegisterValue |= BMIC_nREAD;
- } else {
- RegisterValue &= ~((UINT8) BMIC_nREAD);
- }
+ //
+ // 0000 1000
+ //
+ RegisterValue &= ~((UINT8) BMIC_nREAD);
IdeDev->PciIo->Io.Write (
IdeDev->PciIo,
@@ -2481,26 +3400,17 @@ DoAtaUdma ( &RegisterValue
);
- if (UdmaOp == AtaUdmaWriteExtOp || UdmaOp == AtaUdmaReadExtOp) {
- Status = AtaCommandIssueExt (
- IdeDev,
- AtaCommand,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
- } else {
- Status = AtaCommandIssue (
- IdeDev,
- AtaCommand,
- Device,
- 0,
- (UINT16) NumberOfBlocks,
- StartLba
- );
- }
-
+ //
+ // Issue WRITE DMA command
+ //
+ Status = AtaCommandIssue (
+ IdeDev,
+ WRITE_DMA_CMD,
+ Device,
+ 0,
+ (UINT16) NumberOfBlocks,
+ StartLba
+ );
if (EFI_ERROR (Status)) {
IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
@@ -2584,6 +3494,7 @@ DoAtaUdma ( IdeDev->PciIo->FreeBuffer (IdeDev->PciIo, PageCount, MemPage);
IdeDev->PciIo->Unmap (IdeDev->PciIo, Map);
+
//
// Read Status Register of IDE device to clear interrupt
//
@@ -2611,10 +3522,6 @@ DoAtaUdma ( &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 f382279..b83a82a 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/ide.h @@ -1098,42 +1098,6 @@ 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 73b302c..0e7d43e 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.c @@ -629,11 +629,7 @@ 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 78c79d7..52c1f26 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idebus.h @@ -65,7 +65,7 @@ typedef struct { INQUIRY_DATA *pInquiryData;
EFI_IDENTIFY_DATA *pIdData;
ATA_PIO_MODE PioMode;
- EFI_ATA_MODE UdmaMode;
+ ATA_UDMA_MODE UDma_Mode;
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 0c38311..ec088dc 100644 --- a/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h +++ b/EdkModulePkg/Bus/Pci/IdeBus/Dxe/idedata.h @@ -86,13 +86,6 @@ typedef enum { SenseOtherSense
} SENSE_RESULT;
-typedef enum {
- AtaUdmaReadOp,
- AtaUdmaReadExtOp,
- AtaUdmaWriteOp,
- AtaUdmaWriteExtOp
-} ATA_UDMA_OPERATION;
-
//
// IDE Registers
//
|