MdeModulePkg: Skip to manage usb debug port in EDKII EHCI driver if it's used by usb debug port driver

Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13226 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
erictian 2012-04-28 05:02:54 +00:00
parent 3e0587010e
commit 09943f5ecc
4 changed files with 224 additions and 5 deletions

View File

@ -120,6 +120,7 @@ EhcReset (
USB2_HC_DEV *Ehc;
EFI_TPL OldTpl;
EFI_STATUS Status;
UINT32 DbgCtrlStatus;
OldTpl = gBS->RaiseTPL (EHC_TPL);
Ehc = EHC_FROM_THIS (This);
@ -133,6 +134,14 @@ EhcReset (
//
// Host Controller must be Halt when Reset it
//
if (Ehc->DebugPortNum != 0) {
DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);
if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
Status = EFI_SUCCESS;
goto ON_EXIT;
}
}
if (!EhcIsHalt (Ehc)) {
Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
@ -323,6 +332,7 @@ EhcGetRootHubPortStatus (
UINTN Index;
UINTN MapSize;
EFI_STATUS Status;
UINT32 DbgCtrlStatus;
if (PortStatus == NULL) {
return EFI_INVALID_PARAMETER;
@ -344,6 +354,13 @@ EhcGetRootHubPortStatus (
PortStatus->PortStatus = 0;
PortStatus->PortChangeStatus = 0;
if ((Ehc->DebugPortNum != 0) && (PortNumber == (Ehc->DebugPortNum - 1))) {
DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0);
if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
goto ON_EXIT;
}
}
State = EhcReadOpReg (Ehc, Offset);
//
@ -1390,6 +1407,129 @@ ON_EXIT:
return Status;
}
/**
Get the usb debug port related information.
@param Ehc The EHCI device.
@retval RETURN_SUCCESS Get debug port number, bar and offset successfully.
@retval Others The usb host controller does not supported usb debug port capability.
**/
EFI_STATUS
EhcGetUsbDebugPortInfo (
IN USB2_HC_DEV *Ehc
)
{
EFI_PCI_IO_PROTOCOL *PciIo;
UINT16 PciStatus;
UINT8 CapabilityPtr;
UINT8 CapabilityId;
UINT16 DebugPort;
EFI_STATUS Status;
ASSERT (Ehc->PciIo != NULL);
PciIo = Ehc->PciIo;
//
// Detect if the EHCI host controller support Capaility Pointer.
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
PCI_PRIMARY_STATUS_OFFSET,
sizeof (UINT16),
&PciStatus
);
if (EFI_ERROR (Status)) {
return Status;
}
if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {
//
// The Pci Device Doesn't Support Capability Pointer.
//
return EFI_UNSUPPORTED;
}
//
// Get Pointer To Capability List
//
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
PCI_CAPBILITY_POINTER_OFFSET,
1,
&CapabilityPtr
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Find Capability ID 0xA, Which Is For Debug Port
//
while (CapabilityPtr != 0) {
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
CapabilityPtr,
1,
&CapabilityId
);
if (EFI_ERROR (Status)) {
return Status;
}
if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) {
break;
}
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
CapabilityPtr + 1,
1,
&CapabilityPtr
);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// No Debug Port Capability Found
//
if (CapabilityPtr == 0) {
return EFI_UNSUPPORTED;
}
//
// Get The Base Address Of Debug Port Register In Debug Port Capability Register
//
Status = PciIo->Pci.Read (
Ehc->PciIo,
EfiPciIoWidthUint8,
CapabilityPtr + 2,
sizeof (UINT16),
&DebugPort
);
if (EFI_ERROR (Status)) {
return Status;
}
Ehc->DebugPortOffset = DebugPort & 0x1FFF;
Ehc->DebugPortBarNum = (DebugPort >> 13) - 1;
Ehc->DebugPortNum = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20);
return EFI_SUCCESS;
}
/**
Create and initialize a USB2_HC_DEV.
@ -1456,6 +1596,8 @@ EhcCreateUsb2Hc (
return NULL;
}
EhcGetUsbDebugPortInfo (Ehc);
//
// Create AsyncRequest Polling Timer
//
@ -1541,6 +1683,7 @@ EhcDriverBindingStart (
UINTN EhciBusNumber;
UINTN EhciDeviceNumber;
UINTN EhciFunctionNumber;
UINT32 State;
//
// Open the PciIo Protocol, then enable the USB host controller
@ -1727,7 +1870,13 @@ EhcDriverBindingStart (
if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {
EhcClearLegacySupport (Ehc);
}
if (Ehc->DebugPortNum != 0) {
State = EhcReadDbgRegister(Ehc, 0);
if ((State & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) != (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) {
EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
}
}
Status = EhcInitHC (Ehc);

View File

@ -2,7 +2,7 @@
Provides some data struct used by EHCI controller driver.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
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
@ -70,6 +70,13 @@ typedef struct _USB2_HC_DEV USB2_HC_DEV;
#define EHC_SYNC_POLL_INTERVAL (1 * EHC_1_MILLISECOND)
#define EHC_ASYNC_POLL_INTERVAL (50 * 10000U)
//
// EHCI debug port control status register bit definition
//
#define USB_DEBUG_PORT_IN_USE BIT10
#define USB_DEBUG_PORT_ENABLE BIT28
#define USB_DEBUG_PORT_OWNER BIT30
//
// EHC raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
@ -157,6 +164,13 @@ struct _USB2_HC_DEV {
// Misc
//
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
//
// EHCI debug port info
//
UINT16 DebugPortOffset; // The offset of debug port mmio register
UINT8 DebugPortBarNum; // The bar number of debug port mmio register
UINT8 DebugPortNum; // The port number of usb debug port
};

View File

@ -2,7 +2,7 @@
The EHCI register operation routines.
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
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
@ -53,6 +53,42 @@ EhcReadCapRegister (
return Data;
}
/**
Read EHCI debug port register.
@param Ehc The EHCI device.
@param Offset Debug port register offset.
@return The register content read.
@retval If err, return 0xffff.
**/
UINT32
EhcReadDbgRegister (
IN USB2_HC_DEV *Ehc,
IN UINT32 Offset
)
{
UINT32 Data;
EFI_STATUS Status;
Status = Ehc->PciIo->Mem.Read (
Ehc->PciIo,
EfiPciIoWidthUint32,
Ehc->DebugPortBarNum,
(UINT64) (Ehc->DebugPortOffset + Offset),
1,
&Data
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "EhcReadDbgRegister: Pci Io read error - %r at %d\n", Status, Offset));
Data = 0xFFFF;
}
return Data;
}
/**
Read EHCI Operation register.

View File

@ -2,7 +2,7 @@
This file contains the definination for host controller register operation routines.
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
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
@ -89,6 +89,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
#define EHC_BAR_INDEX 0 // how many bytes away from USB_BASE to 0x10
//
// Debug port capability id
//
#define EHC_DEBUG_PORT_CAP_ID 0x0A
#define EHC_LINK_TERMINATED(Link) (((Link) & 0x01) != 0)
#define EHC_ADDR(High, QhHw32) \
@ -131,6 +136,21 @@ EhcReadCapRegister (
IN UINT32 Offset
);
/**
Read EHCI debug port register.
@param Ehc The EHCI device.
@param Offset Debug port register address.
@return The register content read.
@retval If err, return 0xffff.
**/
UINT32
EhcReadDbgRegister (
IN USB2_HC_DEV *Ehc,
IN UINT32 Offset
);
/**
Read EHCI Operation register.