From 9690325d1e8b1602dac5091a1bab8e1076954900 Mon Sep 17 00:00:00 2001 From: erictian Date: Fri, 4 Jan 2013 06:03:52 +0000 Subject: [PATCH] MdeModulePkg/AtaBus&ScsiBus: Dynamically calculate how long shall we wait for the finish of a read/write operation according to the actual transfer length Signed-off-by: Feng Tian Reviewed-by: Elvin Li git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14028 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Ata/AtaBusDxe/AtaPassThruExecute.c | 31 +++++++++- MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 62 ++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c index d44359cfcf..2c79f46ed9 100644 --- a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c +++ b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c @@ -524,7 +524,36 @@ TransferAtaDevice ( Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite]; Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT; - Packet->Timeout = ATA_TIMEOUT; + // + // |------------------------|-----------------|------------------------|-----------------| + // | ATA PIO Transfer Mode | Transfer Rate | ATA DMA Transfer Mode | Transfer Rate | + // |------------------------|-----------------|------------------------|-----------------| + // | PIO Mode 0 | 3.3Mbytes/sec | Single-word DMA Mode 0 | 2.1Mbytes/sec | + // |------------------------|-----------------|------------------------|-----------------| + // | PIO Mode 1 | 5.2Mbytes/sec | Single-word DMA Mode 1 | 4.2Mbytes/sec | + // |------------------------|-----------------|------------------------|-----------------| + // | PIO Mode 2 | 8.3Mbytes/sec | Single-word DMA Mode 2 | 8.4Mbytes/sec | + // |------------------------|-----------------|------------------------|-----------------| + // | PIO Mode 3 | 11.1Mbytes/sec | Multi-word DMA Mode 0 | 4.2Mbytes/sec | + // |------------------------|-----------------|------------------------|-----------------| + // | PIO Mode 4 | 16.6Mbytes/sec | Multi-word DMA Mode 1 | 13.3Mbytes/sec | + // |------------------------|-----------------|------------------------|-----------------| + // + // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to + // calculate the possible maximum timeout value for each read/write operation. + // + if (AtaDevice->UdmaValid) { + // + // Calculate the maximum timeout value for DMA read/write operation. + // + Packet->Timeout = EFI_TIMER_PERIOD_SECONDS ((TransferLength * AtaDevice->BlockMedia.BlockSize) / 2100000 + 1); + } else { + // + // Calculate the maximum timeout value for PIO read/write operation + // + Packet->Timeout = EFI_TIMER_PERIOD_SECONDS ((TransferLength * AtaDevice->BlockMedia.BlockSize) / 3300000 + 1); + } + return AtaDevicePassThru (AtaDevice, TaskPacket, Event); } diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c index 324964a81c..c6d96caeb8 100644 --- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c +++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c @@ -1815,7 +1815,36 @@ ScsiDiskReadSectors ( } ByteCount = SectorCount * BlockSize; - Timeout = EFI_TIMER_PERIOD_SECONDS (2); + // + // |------------------------|-----------------|------------------|-----------------| + // | ATA Transfer Mode | Transfer Rate | SCSI Interface | Transfer Rate | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 0 | 3.3Mbytes/sec | SCSI-1 | 5Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 1 | 5.2Mbytes/sec | Fast SCSI | 10Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 2 | 8.3Mbytes/sec | Fast-Wide SCSI | 20Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 3 | 11.1Mbytes/sec | Ultra SCSI | 20Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 4 | 16.6Mbytes/sec | Ultra Wide SCSI | 40Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 0 | 2.1Mbytes/sec | Ultra2 SCSI | 40Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 1 | 4.2Mbytes/sec | Ultra2 Wide SCSI | 80Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 2 | 8.4Mbytes/sec | Ultra3 SCSI | 160Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Multi-word DMA Mode 0 | 4.2Mbytes/sec | Ultra-320 SCSI | 320Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Multi-word DMA Mode 1 | 13.3Mbytes/sec | Ultra-640 SCSI | 640Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // + // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use + // the lowest transfer rate to calculate the possible maximum timeout value for each operation. + // From the above table, we could know 2.1Mbytes per second is lowest one. + // + Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 1); MaxRetry = 2; for (Index = 0; Index < MaxRetry; Index++) { @@ -1937,7 +1966,36 @@ ScsiDiskWriteSectors ( } ByteCount = SectorCount * BlockSize; - Timeout = EFI_TIMER_PERIOD_SECONDS (2); + // + // |------------------------|-----------------|------------------|-----------------| + // | ATA Transfer Mode | Transfer Rate | SCSI Interface | Transfer Rate | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 0 | 3.3Mbytes/sec | SCSI-1 | 5Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 1 | 5.2Mbytes/sec | Fast SCSI | 10Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 2 | 8.3Mbytes/sec | Fast-Wide SCSI | 20Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 3 | 11.1Mbytes/sec | Ultra SCSI | 20Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | PIO Mode 4 | 16.6Mbytes/sec | Ultra Wide SCSI | 40Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 0 | 2.1Mbytes/sec | Ultra2 SCSI | 40Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 1 | 4.2Mbytes/sec | Ultra2 Wide SCSI | 80Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Single-word DMA Mode 2 | 8.4Mbytes/sec | Ultra3 SCSI | 160Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Multi-word DMA Mode 0 | 4.2Mbytes/sec | Ultra-320 SCSI | 320Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // | Multi-word DMA Mode 1 | 13.3Mbytes/sec | Ultra-640 SCSI | 640Mbytes/sec | + // |------------------------|-----------------|------------------|-----------------| + // + // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use + // the lowest transfer rate to calculate the possible maximum timeout value for each operation. + // From the above table, we could know 2.1Mbytes per second is lowest one. + // + Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 1); MaxRetry = 2; for (Index = 0; Index < MaxRetry; Index++) { if (!ScsiDiskDevice->Cdb16Byte) { -- 2.39.2