summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c1
-rw-r--r--MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c31
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c35
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c150
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c62
5 files changed, 182 insertions, 97 deletions
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
index 190ab799f1..2001175fe7 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
@@ -548,7 +548,6 @@ AhciBuildCommand (
CommandList->AhciCmdA = 1;
CommandList->AhciCmdP = 1;
- CommandList->AhciCmdC = (DataLength == 0) ? 1 : 0;
AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
} else {
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/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 787bdc13a0..59891b814a 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -6,9 +6,10 @@
Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device.
Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached
- to the EHCI controller before the UHCI driver attaches to the companion UHCI controller.
- This way avoids the control transfer on a shared port between EHCI and companion host
- controller when UHCI gets attached earlier than EHCI and a USB 2.0 device inserts.
+ to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or
+ OHCI controller. This way avoids the control transfer on a shared port between EHCI
+ and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
+ USB 2.0 device inserts.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -1403,7 +1404,7 @@ EhcDriverBindingSupported (
// Test whether the controller belongs to Ehci type
//
if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)
- || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface !=PCI_IF_UHCI))) {
+ || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI))) {
Status = EFI_UNSUPPORTED;
}
@@ -1690,10 +1691,10 @@ EhcDriverBindingStart (
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN Index;
- UINTN UhciSegmentNumber;
- UINTN UhciBusNumber;
- UINTN UhciDeviceNumber;
- UINTN UhciFunctionNumber;
+ UINTN CompanionSegmentNumber;
+ UINTN CompanionBusNumber;
+ UINTN CompanionDeviceNumber;
+ UINTN CompanionFunctionNumber;
UINTN EhciSegmentNumber;
UINTN EhciBusNumber;
UINTN EhciDeviceNumber;
@@ -1783,19 +1784,19 @@ EhcDriverBindingStart (
goto CLOSE_PCIIO;
}
//
- // determine if the device is UHCI host controller or not. If yes, then find out the
+ // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the
// companion usb ehci host controller and force EHCI driver get attached to it before
- // UHCI driver attaches to UHCI host controller.
+ // UHCI or OHCI driver attaches to UHCI or OHCI host controller.
//
- if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI) &&
+ if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI || UsbClassCReg.ProgInterface == PCI_IF_OHCI) &&
(UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
(UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
Status = PciIo->GetLocation (
PciIo,
- &UhciSegmentNumber,
- &UhciBusNumber,
- &UhciDeviceNumber,
- &UhciFunctionNumber
+ &CompanionSegmentNumber,
+ &CompanionBusNumber,
+ &CompanionDeviceNumber,
+ &CompanionFunctionNumber
);
if (EFI_ERROR (Status)) {
goto CLOSE_PCIIO;
@@ -1853,7 +1854,7 @@ EhcDriverBindingStart (
// Currently, the judgment on the companion usb host controller is through the
// same bus number, which may vary on different platform.
//
- if (EhciBusNumber == UhciBusNumber) {
+ if (EhciBusNumber == CompanionBusNumber) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
@@ -2081,7 +2082,7 @@ EhcDriverBindingStop (
//
// Disable routing of all ports to EHCI controller, so all ports are
- // routed back to the UHCI controller.
+ // routed back to the UHCI or OHCI controller.
//
EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index e03934fa09..b8a1d78a7e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -140,27 +140,27 @@ XhcReset (
)
{
USB_XHCI_INSTANCE *Xhc;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- Xhc = XHC_FROM_THIS (This);
-
- if (Xhc->DevicePath != NULL) {
- //
- // Report Status Code to indicate reset happens
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
- Xhc->DevicePath
- );
- }
-
- OldTpl = gBS->RaiseTPL (XHC_TPL);
-
- switch (Attributes) {
- case EFI_USB_HC_RESET_GLOBAL:
- //
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Xhc = XHC_FROM_THIS (This);
+
+ if (Xhc->DevicePath != NULL) {
+ //
+ // Report Status Code to indicate reset happens
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
+ Xhc->DevicePath
+ );
+ }
+
+ OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+ switch (Attributes) {
+ case EFI_USB_HC_RESET_GLOBAL:
+ //
// Flow through, same behavior as Host Controller Reset
//
case EFI_USB_HC_RESET_HOST_CONTROLLER:
@@ -932,9 +932,9 @@ XhcControlTransfer (
}
Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
if (Xhc->HcCParams.Data.Csz == 0) {
- Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
+ Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
} else {
- Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
+ Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
}
ASSERT_EFI_ERROR (Status);
} else if (DescriptorType == USB_DESC_TYPE_CONFIG) {
@@ -1007,17 +1007,15 @@ XhcControlTransfer (
if ((State & XHC_PORTSC_PS) >> 10 == 0) {
PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED;
}
- } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
+ } else {
//
- // For high speed hub, its bit9~10 presents the attached device speed.
+ // For high or full/low speed hub, its bit9~10 presents the attached device speed.
//
if (XHC_BIT_IS_SET (State, BIT9)) {
PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED;
} else if (XHC_BIT_IS_SET (State, BIT10)) {
PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED;
}
- } else {
- ASSERT (0);
}
//
@@ -1690,15 +1688,15 @@ ON_EXIT:
@return The allocated and initialized USB_XHCI_INSTANCE structure if created,
otherwise NULL.
-**/
-USB_XHCI_INSTANCE*
-XhcCreateUsbHc (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN UINT64 OriginalPciAttributes
- )
-{
- USB_XHCI_INSTANCE *Xhc;
+**/
+USB_XHCI_INSTANCE*
+XhcCreateUsbHc (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINT64 OriginalPciAttributes
+ )
+{
+ USB_XHCI_INSTANCE *Xhc;
EFI_STATUS Status;
UINT32 PageSize;
UINT16 ExtCapReg;
@@ -1711,13 +1709,13 @@ XhcCreateUsbHc (
//
// Initialize private data structure
- //
- Xhc->Signature = XHCI_INSTANCE_SIG;
- Xhc->PciIo = PciIo;
- Xhc->DevicePath = DevicePath;
- Xhc->OriginalPciAttributes = OriginalPciAttributes;
- CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));
-
+ //
+ Xhc->Signature = XHCI_INSTANCE_SIG;
+ Xhc->PciIo = PciIo;
+ Xhc->DevicePath = DevicePath;
+ Xhc->OriginalPciAttributes = OriginalPciAttributes;
+ CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));
+
InitializeListHead (&Xhc->AsyncIntTransfers);
//
@@ -1841,13 +1839,13 @@ XhcDriverBindingStart (
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 Supports;
- UINT64 OriginalPciAttributes;
- BOOLEAN PciAttributesSaved;
- USB_XHCI_INSTANCE *Xhc;
- EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
-
- //
- // Open the PciIo Protocol, then enable the USB host controller
+ UINT64 OriginalPciAttributes;
+ BOOLEAN PciAttributesSaved;
+ USB_XHCI_INSTANCE *Xhc;
+ EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
+
+ //
+ // Open the PciIo Protocol, then enable the USB host controller
//
Status = gBS->OpenProtocol (
Controller,
@@ -1859,25 +1857,25 @@ XhcDriverBindingStart (
);
if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Open Device Path Protocol for on USB host controller
- //
- HcDevicePath = NULL;
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &HcDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- PciAttributesSaved = FALSE;
- //
- // Save original PCI attributes
+ return Status;
+ }
+
+ //
+ // Open Device Path Protocol for on USB host controller
+ //
+ HcDevicePath = NULL;
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &HcDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ PciAttributesSaved = FALSE;
+ //
+ // Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
@@ -1912,13 +1910,13 @@ XhcDriverBindingStart (
goto CLOSE_PCIIO;
}
- //
- // Create then install USB2_HC_PROTOCOL
- //
- Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes);
-
- if (Xhc == NULL) {
- DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n"));
+ //
+ // Create then install USB2_HC_PROTOCOL
+ //
+ Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes);
+
+ if (Xhc == NULL) {
+ DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n"));
return EFI_OUT_OF_RESOURCES;
}
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) {