From c7c02fabf120cc1aeccd0cb0fc7f8671fa1cb25e Mon Sep 17 00:00:00 2001 From: yshang1 Date: Tue, 23 Jan 2007 10:28:32 +0000 Subject: [PATCH] Fixed bug in partition driver: When Block I/O detects the media changed, block driver will reinstall block I/O protocol. If it happened during start() of partition driver, the reinstall protocol would results in the reentrant of the start(). In the patch, we check status of child detection to see whether need clean up the opened block I/O protocol in Start(). Besides, some checking of return status added in usbbus driver to improve robusticiy of the driver. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2288 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c | 20 +++++--- .../Universal/Disk/Partition/Dxe/ElTorito.c | 18 ++++--- .../Universal/Disk/Partition/Dxe/Gpt.c | 17 ++++--- .../Universal/Disk/Partition/Dxe/Mbr.c | 17 ++++--- .../Universal/Disk/Partition/Dxe/Partition.c | 51 +++++++++---------- .../Universal/Disk/Partition/Dxe/Partition.h | 16 ++++-- 6 files changed, 79 insertions(+), 60 deletions(-) diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c index 837a6001dd..029d9cb425 100644 --- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c +++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c @@ -1276,6 +1276,7 @@ UsbDeviceDeConfiguration ( USB_IO_DEVICE *ChildDevice; UINT8 Index; EFI_USB_IO_PROTOCOL *UsbIo; + EFI_STATUS Status; // // Double check UsbIoDevice exists @@ -1365,14 +1366,17 @@ UsbDeviceDeConfiguration ( // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL // installed on this handle // - gBS->UninstallMultipleProtocolInterfaces ( - UsbController->Handle, - &gEfiDevicePathProtocolGuid, - UsbController->DevicePath, - &gEfiUsbIoProtocolGuid, - &UsbController->UsbIo, - NULL - ); + Status = gBS->UninstallMultipleProtocolInterfaces ( + UsbController->Handle, + &gEfiDevicePathProtocolGuid, + UsbController->DevicePath, + &gEfiUsbIoProtocolGuid, + &UsbController->UsbIo, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } if (UsbController->DevicePath != NULL) { gBS->FreePool (UsbController->DevicePath); diff --git a/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c b/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c index b5f292697b..d740d24087 100644 --- a/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c +++ b/EdkModulePkg/Universal/Disk/Partition/Dxe/ElTorito.c @@ -23,7 +23,7 @@ Revision History #include "Partition.h" -BOOLEAN +EFI_STATUS PartitionInstallElToritoChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -44,8 +44,9 @@ Arguments: DevicePath - Parent Device Path Returns: - TRUE - some child handle(s) was added - FALSE - no child handle was added + EFI_SUCCESS - some child handle(s) was added + EFI_MEDIA_CHANGED - Media changed Detected + !EFI_SUCCESS - no child handle was added --*/ { @@ -63,10 +64,10 @@ Returns: CDROM_DEVICE_PATH CdDev; UINT32 SubBlockSize; UINT32 SectorCount; - BOOLEAN Found; + EFI_STATUS Found; UINT32 VolSpaceSize; - Found = FALSE; + Found = EFI_NOT_FOUND; Media = BlockIo->Media; VolSpaceSize = 0; @@ -74,13 +75,13 @@ Returns: // CD_ROM has the fixed block size as 2048 bytes // if (Media->BlockSize != 2048) { - return FALSE; + return EFI_NOT_FOUND; } VolDescriptor = AllocatePool ((UINTN) Media->BlockSize); if (VolDescriptor == NULL) { - return FALSE; + return EFI_NOT_FOUND; } Catalog = (ELTORITO_CATALOG *) VolDescriptor; @@ -114,6 +115,7 @@ Returns: VolDescriptor ); if (EFI_ERROR (Status)) { + Found = Status; break; } // @@ -272,7 +274,7 @@ Returns: FALSE ); if (!EFI_ERROR (Status)) { - Found = TRUE; + Found = EFI_SUCCESS; } } } diff --git a/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c b/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c index 12ec97612d..42411806f6 100644 --- a/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c +++ b/EdkModulePkg/Universal/Disk/Partition/Dxe/Gpt.c @@ -75,7 +75,7 @@ PartitionSetCrc ( IN OUT EFI_TABLE_HEADER *Hdr ); -BOOLEAN +EFI_STATUS PartitionInstallGptChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -96,8 +96,9 @@ Arguments: DevicePath - Parent Device Path Returns: - TRUE - Valid GPT disk - FALSE - Not a valid GPT disk + EFI_SUCCESS - Valid GPT disk + EFI_MEDIA_CHANGED - Media changed Detected + !EFI_SUCCESS - Not a valid GPT disk --*/ { @@ -110,7 +111,7 @@ Returns: EFI_PARTITION_ENTRY *PartEntry; EFI_PARTITION_ENTRY_STATUS *PEntryStatus; UINTN Index; - BOOLEAN GptValid; + EFI_STATUS GptValid; HARDDRIVE_DEVICE_PATH HdDev; ProtectiveMbr = NULL; @@ -125,14 +126,14 @@ Returns: DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize)); DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock)); - GptValid = FALSE; + GptValid = EFI_NOT_FOUND; // // Allocate a buffer for the Protective MBR // ProtectiveMbr = AllocatePool (BlockSize); if (ProtectiveMbr == NULL) { - return FALSE; + return EFI_NOT_FOUND; } // @@ -146,6 +147,7 @@ Returns: ProtectiveMbr ); if (EFI_ERROR (Status)) { + GptValid = Status; goto Done; } // @@ -224,6 +226,7 @@ Returns: PartEntry ); if (EFI_ERROR (Status)) { + GptValid = Status; DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n")); goto Done; } @@ -246,7 +249,7 @@ Returns: // // If we got this far the GPT layout of the disk is valid and we should return true // - GptValid = TRUE; + GptValid = EFI_SUCCESS; // // Create child device handles diff --git a/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c b/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c index c0cd23c5bb..ce6b0d5353 100644 --- a/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c +++ b/EdkModulePkg/Universal/Disk/Partition/Dxe/Mbr.c @@ -108,7 +108,7 @@ Returns: return MbrValid; } -BOOLEAN +EFI_STATUS PartitionInstallMbrChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -129,8 +129,9 @@ Arguments: DevicePath - Parent Device Path Returns: - EFI_SUCCESS - If a child handle was added - other - A child handle was not added + EFI_SUCCESS - If a child handle was added + EFI_MEDIA_CHANGED - Media changed Detected + !EFI_SUCCESS - Not found MBR partition. --*/ { @@ -140,13 +141,13 @@ Returns: UINTN Index; HARDDRIVE_DEVICE_PATH HdDev; HARDDRIVE_DEVICE_PATH ParentHdDev; - BOOLEAN Found; + EFI_STATUS Found; UINT32 PartitionNumber; EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode; Mbr = NULL; - Found = FALSE; + Found = EFI_NOT_FOUND; Mbr = AllocatePool (BlockIo->Media->BlockSize); if (Mbr == NULL) { @@ -161,6 +162,7 @@ Returns: Mbr ); if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) { + Found = Status; goto Done; } // @@ -237,7 +239,7 @@ Returns: ); if (!EFI_ERROR (Status)) { - Found = TRUE; + Found = EFI_SUCCESS; } } } else { @@ -257,6 +259,7 @@ Returns: Mbr ); if (EFI_ERROR (Status)) { + Found = Status; goto Done; } @@ -295,7 +298,7 @@ Returns: (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION) ); if (!EFI_ERROR (Status)) { - Found = TRUE; + Found = EFI_SUCCESS; } if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) && diff --git a/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c b/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c index 504d98357f..77cee2442b 100644 --- a/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c +++ b/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.c @@ -71,6 +71,15 @@ EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = { NULL }; +STATIC +PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = { + PartitionInstallGptChildHandles, + PartitionInstallElToritoChildHandles, + PartitionInstallMbrChildHandles, + NULL +}; + + EFI_STATUS EFIAPI PartitionDriverBindingSupported ( @@ -212,6 +221,7 @@ PartitionDriverBindingStart ( EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_DISK_IO_PROTOCOL *DiskIo; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + PARTITION_DETECT_ROUTINE *Routine; Status = gBS->OpenProtocol ( ControllerHandle, @@ -269,32 +279,19 @@ PartitionDriverBindingStart ( // media supports a given partition type install child handles to represent // the partitions described by the media. // - if (PartitionInstallGptChildHandles ( - This, - ControllerHandle, - DiskIo, - BlockIo, - ParentDevicePath - ) || - - PartitionInstallElToritoChildHandles ( - This, - ControllerHandle, - DiskIo, - BlockIo, - ParentDevicePath - ) || - - PartitionInstallMbrChildHandles ( - This, - ControllerHandle, - DiskIo, - BlockIo, - ParentDevicePath - )) { - Status = EFI_SUCCESS; - } else { - Status = EFI_NOT_FOUND; + Routine = &mPartitionDetectRoutineTable[0]; + while (*Routine != NULL) { + Status = (*Routine) ( + This, + ControllerHandle, + DiskIo, + BlockIo, + ParentDevicePath + ); + if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED) { + break; + } + Routine++; } } // @@ -303,7 +300,7 @@ PartitionDriverBindingStart ( // driver. So don't try to close them. Otherwise, we will break the dependency // between the controller and the driver set up before. // - if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus)) { + if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus) && Status != EFI_MEDIA_CHANGED) { gBS->CloseProtocol ( ControllerHandle, &gEfiDiskIoProtocolGuid, diff --git a/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h b/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h index ceb838f0ea..ba105554e9 100644 --- a/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h +++ b/EdkModulePkg/Universal/Disk/Partition/Dxe/Partition.h @@ -92,7 +92,7 @@ PartitionInstallChildHandle ( ) ; -BOOLEAN +EFI_STATUS PartitionInstallGptChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -102,7 +102,7 @@ PartitionInstallGptChildHandles ( ) ; -BOOLEAN +EFI_STATUS PartitionInstallElToritoChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -112,7 +112,7 @@ PartitionInstallElToritoChildHandles ( ) ; -BOOLEAN +EFI_STATUS PartitionInstallMbrChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, @@ -122,4 +122,14 @@ PartitionInstallMbrChildHandles ( ) ; +typedef +EFI_STATUS +(*PARTITION_DETECT_ROUTINE) ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + #endif -- 2.39.2