Fix a bug in DebugPort driver's Unload() that leaves the DriverBinding/ComponentName(2) installed.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15087 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM
|
ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM
|
||||||
INTERRUPT CONTEXT
|
INTERRUPT CONTEXT
|
||||||
|
|
||||||
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -33,7 +33,6 @@ DEBUGPORT_DEVICE mDebugPortDevice = {
|
|||||||
DEBUGPORT_DEVICE_SIGNATURE,
|
DEBUGPORT_DEVICE_SIGNATURE,
|
||||||
(EFI_HANDLE) 0,
|
(EFI_HANDLE) 0,
|
||||||
(EFI_HANDLE) 0,
|
(EFI_HANDLE) 0,
|
||||||
(VOID *) NULL,
|
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *) NULL,
|
(EFI_DEVICE_PATH_PROTOCOL *) NULL,
|
||||||
{
|
{
|
||||||
DebugPortReset,
|
DebugPortReset,
|
||||||
@ -57,72 +56,52 @@ DEBUGPORT_DEVICE mDebugPortDevice = {
|
|||||||
Records requested settings in DebugPort device structure.
|
Records requested settings in DebugPort device structure.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
EFI_DEVICE_PATH_PROTOCOL *
|
||||||
GetDebugPortVariable (
|
GetDebugPortVariable (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN DataSize;
|
UINTN DataSize;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DebugPortVariable;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
DataSize = 0;
|
GetVariable2 (EFI_DEBUGPORT_VARIABLE_NAME, &gEfiDebugPortVariableGuid, &DebugPortVariable, &DataSize);
|
||||||
|
if (DebugPortVariable == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Status = gRT->GetVariable (
|
DevicePath = DebugPortVariable;
|
||||||
(CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
|
while (!IsDevicePathEnd (DevicePath) && !IS_UART_DEVICEPATH (DevicePath)) {
|
||||||
&gEfiDebugPortVariableGuid,
|
DevicePath = NextDevicePathNode (DevicePath);
|
||||||
NULL,
|
}
|
||||||
&DataSize,
|
|
||||||
mDebugPortDevice.DebugPortVariable
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
if (IsDevicePathEnd (DevicePath)) {
|
||||||
if (mDebugPortDevice.DebugPortVariable != NULL) {
|
FreePool (DebugPortVariable);
|
||||||
FreePool (mDebugPortDevice.DebugPortVariable);
|
return NULL;
|
||||||
}
|
} else {
|
||||||
|
CopyMem (
|
||||||
mDebugPortDevice.DebugPortVariable = AllocatePool (DataSize);
|
&mDebugPortDevice.BaudRate,
|
||||||
if (mDebugPortDevice.DebugPortVariable != NULL) {
|
&((UART_DEVICE_PATH *) DevicePath)->BaudRate,
|
||||||
gRT->GetVariable (
|
sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)
|
||||||
(CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
|
);
|
||||||
&gEfiDebugPortVariableGuid,
|
mDebugPortDevice.ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
|
||||||
NULL,
|
mDebugPortDevice.Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
|
||||||
&DataSize,
|
CopyMem (
|
||||||
mDebugPortDevice.DebugPortVariable
|
&mDebugPortDevice.Parity,
|
||||||
);
|
&((UART_DEVICE_PATH *) DevicePath)->Parity,
|
||||||
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) mDebugPortDevice.DebugPortVariable;
|
sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
|
||||||
while (!IsDevicePathEnd (DevicePath) && !IS_UART_DEVICEPATH (DevicePath)) {
|
);
|
||||||
DevicePath = NextDevicePathNode (DevicePath);
|
CopyMem (
|
||||||
}
|
&mDebugPortDevice.DataBits,
|
||||||
|
&((UART_DEVICE_PATH *) DevicePath)->DataBits,
|
||||||
if (IsDevicePathEnd (DevicePath)) {
|
sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
|
||||||
FreePool (mDebugPortDevice.DebugPortVariable);
|
);
|
||||||
mDebugPortDevice.DebugPortVariable = NULL;
|
CopyMem (
|
||||||
} else {
|
&mDebugPortDevice.StopBits,
|
||||||
CopyMem (
|
&((UART_DEVICE_PATH *) DevicePath)->StopBits,
|
||||||
&mDebugPortDevice.BaudRate,
|
sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)
|
||||||
&((UART_DEVICE_PATH *) DevicePath)->BaudRate,
|
);
|
||||||
sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)
|
return DebugPortVariable;
|
||||||
);
|
|
||||||
mDebugPortDevice.ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
|
|
||||||
mDebugPortDevice.Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
|
|
||||||
CopyMem (
|
|
||||||
&mDebugPortDevice.Parity,
|
|
||||||
&((UART_DEVICE_PATH *) DevicePath)->Parity,
|
|
||||||
sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
|
|
||||||
);
|
|
||||||
CopyMem (
|
|
||||||
&mDebugPortDevice.DataBits,
|
|
||||||
&((UART_DEVICE_PATH *) DevicePath)->DataBits,
|
|
||||||
sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
|
|
||||||
);
|
|
||||||
CopyMem (
|
|
||||||
&mDebugPortDevice.StopBits,
|
|
||||||
&((UART_DEVICE_PATH *) DevicePath)->StopBits,
|
|
||||||
sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,8 +175,8 @@ DebugPortSupported (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *Dp1;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *Dp2;
|
EFI_DEVICE_PATH_PROTOCOL *DebugPortVariable;
|
||||||
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
||||||
EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;
|
EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;
|
||||||
EFI_HANDLE TempHandle;
|
EFI_HANDLE TempHandle;
|
||||||
@ -212,25 +191,19 @@ DebugPortSupported (
|
|||||||
//
|
//
|
||||||
// Read DebugPort variable to determine debug port selection and parameters
|
// Read DebugPort variable to determine debug port selection and parameters
|
||||||
//
|
//
|
||||||
GetDebugPortVariable ();
|
DebugPortVariable = GetDebugPortVariable ();
|
||||||
|
|
||||||
if (mDebugPortDevice.DebugPortVariable != NULL) {
|
if (DebugPortVariable != NULL) {
|
||||||
//
|
//
|
||||||
// There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
|
// There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
|
||||||
// the closest matching handle matches the controller handle, and if it does,
|
// the closest matching handle matches the controller handle, and if it does,
|
||||||
// check to see that the remaining device path has the DebugPort GUIDed messaging
|
// check to see that the remaining device path has the DebugPort GUIDed messaging
|
||||||
// device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
|
// device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
|
||||||
//
|
//
|
||||||
Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) mDebugPortDevice.DebugPortVariable);
|
DevicePath = DebugPortVariable;
|
||||||
if (Dp1 == NULL) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dp2 = Dp1;
|
|
||||||
|
|
||||||
Status = gBS->LocateDevicePath (
|
Status = gBS->LocateDevicePath (
|
||||||
&gEfiSerialIoProtocolGuid,
|
&gEfiSerialIoProtocolGuid,
|
||||||
&Dp2,
|
&DevicePath,
|
||||||
&TempHandle
|
&TempHandle
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -239,18 +212,18 @@ DebugPortSupported (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Status == EFI_SUCCESS &&
|
if (Status == EFI_SUCCESS &&
|
||||||
(Dp2->Type != MESSAGING_DEVICE_PATH ||
|
(DevicePath->Type != MESSAGING_DEVICE_PATH ||
|
||||||
Dp2->SubType != MSG_VENDOR_DP ||
|
DevicePath->SubType != MSG_VENDOR_DP ||
|
||||||
*((UINT16 *) Dp2->Length) != sizeof (DEBUGPORT_DEVICE_PATH))) {
|
*((UINT16 *) DevicePath->Length) != sizeof (DEBUGPORT_DEVICE_PATH))) {
|
||||||
|
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == EFI_SUCCESS && !CompareGuid (&gEfiDebugPortDevicePathGuid, (GUID *) (Dp2 + 1))) {
|
if (Status == EFI_SUCCESS && !CompareGuid (&gEfiDebugPortDevicePathGuid, (GUID *) (DevicePath + 1))) {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreePool (Dp1);
|
FreePool (DebugPortVariable);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
@ -713,16 +686,60 @@ ImageUnloadHandler (
|
|||||||
EFI_HANDLE ImageHandle
|
EFI_HANDLE ImageHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VOID *ComponentName;
|
||||||
|
VOID *ComponentName2;
|
||||||
|
|
||||||
if (mDebugPortDevice.SerialIoBinding != NULL) {
|
if (mDebugPortDevice.SerialIoBinding != NULL) {
|
||||||
return EFI_ABORTED;
|
return EFI_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clean up allocations
|
// Driver is stopped already.
|
||||||
//
|
//
|
||||||
if (mDebugPortDevice.DebugPortVariable != NULL) {
|
Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentNameProtocolGuid, &ComponentName);
|
||||||
FreePool (mDebugPortDevice.DebugPortVariable);
|
if (EFI_ERROR (Status)) {
|
||||||
|
ComponentName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentName2ProtocolGuid, &ComponentName2);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ComponentName2 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ComponentName == NULL) {
|
||||||
|
if (ComponentName2 == NULL) {
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid, &gDebugPortDriverBinding,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid, &gDebugPortDriverBinding,
|
||||||
|
&gEfiComponentName2ProtocolGuid, ComponentName2,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ComponentName2 == NULL) {
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid, &gDebugPortDriverBinding,
|
||||||
|
&gEfiComponentNameProtocolGuid, ComponentName,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid, &gDebugPortDriverBinding,
|
||||||
|
&gEfiComponentNameProtocolGuid, ComponentName,
|
||||||
|
&gEfiComponentName2ProtocolGuid, ComponentName2,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Definitions and prototypes for DebugPort driver.
|
Definitions and prototypes for DebugPort driver.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -52,7 +52,6 @@ typedef struct {
|
|||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
EFI_HANDLE DriverBindingHandle;
|
EFI_HANDLE DriverBindingHandle;
|
||||||
EFI_HANDLE DebugPortDeviceHandle;
|
EFI_HANDLE DebugPortDeviceHandle;
|
||||||
VOID *DebugPortVariable;
|
|
||||||
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DebugPortDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *DebugPortDevicePath;
|
||||||
EFI_DEBUGPORT_PROTOCOL DebugPortInterface;
|
EFI_DEBUGPORT_PROTOCOL DebugPortInterface;
|
||||||
|
Reference in New Issue
Block a user