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
USB_IO_DEVICE *ChildDevice;\r
UINT8 Index;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
USB_IO_DEVICE *ChildDevice;\r
UINT8 Index;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
\r
//\r
// Double check UsbIoDevice exists\r
\r
//\r
// Double check UsbIoDevice exists\r
// Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// installed on this handle\r
//\r
// Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// installed on this handle\r
//\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- UsbController->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- UsbController->DevicePath,\r
- &gEfiUsbIoProtocolGuid,\r
- &UsbController->UsbIo,\r
- NULL\r
- );\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ UsbController->Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ UsbController->DevicePath,\r
+ &gEfiUsbIoProtocolGuid,\r
+ &UsbController->UsbIo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
if (UsbController->DevicePath != NULL) {\r
gBS->FreePool (UsbController->DevicePath);\r
\r
if (UsbController->DevicePath != NULL) {\r
gBS->FreePool (UsbController->DevicePath);\r
\r
#include "Partition.h"\r
\r
\r
#include "Partition.h"\r
\r
PartitionInstallElToritoChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallElToritoChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
DevicePath - Parent Device Path\r
\r
Returns:\r
DevicePath - Parent Device Path\r
\r
Returns:\r
- TRUE - some child handle(s) was added\r
- FALSE - no child handle was added\r
+ EFI_SUCCESS - some child handle(s) was added\r
+ EFI_MEDIA_CHANGED - Media changed Detected\r
+ !EFI_SUCCESS - no child handle was added\r
CDROM_DEVICE_PATH CdDev;\r
UINT32 SubBlockSize;\r
UINT32 SectorCount;\r
CDROM_DEVICE_PATH CdDev;\r
UINT32 SubBlockSize;\r
UINT32 SectorCount;\r
UINT32 VolSpaceSize;\r
\r
UINT32 VolSpaceSize;\r
\r
+ Found = EFI_NOT_FOUND;\r
Media = BlockIo->Media;\r
VolSpaceSize = 0;\r
\r
Media = BlockIo->Media;\r
VolSpaceSize = 0;\r
\r
// CD_ROM has the fixed block size as 2048 bytes\r
//\r
if (Media->BlockSize != 2048) {\r
// CD_ROM has the fixed block size as 2048 bytes\r
//\r
if (Media->BlockSize != 2048) {\r
+ return EFI_NOT_FOUND;\r
}\r
\r
VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);\r
\r
if (VolDescriptor == NULL) {\r
}\r
\r
VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);\r
\r
if (VolDescriptor == NULL) {\r
+ return EFI_NOT_FOUND;\r
}\r
\r
Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
}\r
\r
Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
VolDescriptor\r
);\r
if (EFI_ERROR (Status)) {\r
VolDescriptor\r
);\r
if (EFI_ERROR (Status)) {\r
FALSE\r
);\r
if (!EFI_ERROR (Status)) {\r
FALSE\r
);\r
if (!EFI_ERROR (Status)) {\r
IN OUT EFI_TABLE_HEADER *Hdr\r
);\r
\r
IN OUT EFI_TABLE_HEADER *Hdr\r
);\r
\r
PartitionInstallGptChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallGptChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
DevicePath - Parent Device Path\r
\r
Returns:\r
DevicePath - Parent Device Path\r
\r
Returns:\r
- TRUE - Valid GPT disk\r
- FALSE - Not a valid GPT disk\r
+ EFI_SUCCESS - Valid GPT disk\r
+ EFI_MEDIA_CHANGED - Media changed Detected\r
+ !EFI_SUCCESS - Not a valid GPT disk\r
EFI_PARTITION_ENTRY *PartEntry;\r
EFI_PARTITION_ENTRY_STATUS *PEntryStatus;\r
UINTN Index;\r
EFI_PARTITION_ENTRY *PartEntry;\r
EFI_PARTITION_ENTRY_STATUS *PEntryStatus;\r
UINTN Index;\r
HARDDRIVE_DEVICE_PATH HdDev;\r
\r
ProtectiveMbr = NULL;\r
HARDDRIVE_DEVICE_PATH HdDev;\r
\r
ProtectiveMbr = NULL;\r
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));\r
DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));\r
\r
DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize));\r
DEBUG ((EFI_D_INFO, " LastBlock : %x \n", LastBlock));\r
\r
+ GptValid = EFI_NOT_FOUND;\r
\r
//\r
// Allocate a buffer for the Protective MBR\r
//\r
ProtectiveMbr = AllocatePool (BlockSize);\r
if (ProtectiveMbr == NULL) {\r
\r
//\r
// Allocate a buffer for the Protective MBR\r
//\r
ProtectiveMbr = AllocatePool (BlockSize);\r
if (ProtectiveMbr == NULL) {\r
+ return EFI_NOT_FOUND;\r
ProtectiveMbr\r
);\r
if (EFI_ERROR (Status)) {\r
ProtectiveMbr\r
);\r
if (EFI_ERROR (Status)) {\r
PartEntry\r
);\r
if (EFI_ERROR (Status)) {\r
PartEntry\r
);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));\r
goto Done;\r
}\r
DEBUG ((EFI_D_INFO, " Partition Entry ReadBlocks error\n"));\r
goto Done;\r
}\r
//\r
// If we got this far the GPT layout of the disk is valid and we should return true\r
//\r
//\r
// If we got this far the GPT layout of the disk is valid and we should return true\r
//\r
+ GptValid = EFI_SUCCESS;\r
\r
//\r
// Create child device handles\r
\r
//\r
// Create child device handles\r
return MbrValid;\r
}\r
\r
return MbrValid;\r
}\r
\r
PartitionInstallMbrChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallMbrChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
DevicePath - Parent Device Path\r
\r
Returns:\r
DevicePath - Parent Device Path\r
\r
Returns:\r
- EFI_SUCCESS - If a child handle was added\r
- other - A child handle was not added\r
+ EFI_SUCCESS - If a child handle was added\r
+ EFI_MEDIA_CHANGED - Media changed Detected\r
+ !EFI_SUCCESS - Not found MBR partition.\r
UINTN Index;\r
HARDDRIVE_DEVICE_PATH HdDev;\r
HARDDRIVE_DEVICE_PATH ParentHdDev;\r
UINTN Index;\r
HARDDRIVE_DEVICE_PATH HdDev;\r
HARDDRIVE_DEVICE_PATH ParentHdDev;\r
UINT32 PartitionNumber;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;\r
\r
Mbr = NULL;\r
UINT32 PartitionNumber;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;\r
\r
Mbr = NULL;\r
+ Found = EFI_NOT_FOUND;\r
\r
Mbr = AllocatePool (BlockIo->Media->BlockSize);\r
if (Mbr == NULL) {\r
\r
Mbr = AllocatePool (BlockIo->Media->BlockSize);\r
if (Mbr == NULL) {\r
Mbr\r
);\r
if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {\r
Mbr\r
);\r
if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {\r
);\r
\r
if (!EFI_ERROR (Status)) {\r
);\r
\r
if (!EFI_ERROR (Status)) {\r
Mbr\r
);\r
if (EFI_ERROR (Status)) {\r
Mbr\r
);\r
if (EFI_ERROR (Status)) {\r
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)\r
);\r
if (!EFI_ERROR (Status)) {\r
(BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)\r
);\r
if (!EFI_ERROR (Status)) {\r
}\r
\r
if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) &&\r
}\r
\r
if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) &&\r
+STATIC \r
+PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {\r
+ PartitionInstallGptChildHandles,\r
+ PartitionInstallElToritoChildHandles,\r
+ PartitionInstallMbrChildHandles,\r
+ NULL\r
+};\r
+\r
+\r
EFI_STATUS\r
EFIAPI\r
PartitionDriverBindingSupported (\r
EFI_STATUS\r
EFIAPI\r
PartitionDriverBindingSupported (\r
EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
EFI_DISK_IO_PROTOCOL *DiskIo;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
EFI_DISK_IO_PROTOCOL *DiskIo;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ PARTITION_DETECT_ROUTINE *Routine;\r
\r
Status = gBS->OpenProtocol (\r
ControllerHandle,\r
\r
Status = gBS->OpenProtocol (\r
ControllerHandle,\r
// media supports a given partition type install child handles to represent\r
// the partitions described by the media.\r
//\r
// media supports a given partition type install child handles to represent\r
// the partitions described by the media.\r
//\r
- if (PartitionInstallGptChildHandles (\r
- This,\r
- ControllerHandle,\r
- DiskIo,\r
- BlockIo,\r
- ParentDevicePath\r
- ) ||\r
-\r
- PartitionInstallElToritoChildHandles (\r
- This,\r
- ControllerHandle,\r
- DiskIo,\r
- BlockIo,\r
- ParentDevicePath\r
- ) ||\r
-\r
- PartitionInstallMbrChildHandles (\r
- This,\r
- ControllerHandle,\r
- DiskIo,\r
- BlockIo,\r
- ParentDevicePath\r
- )) {\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_NOT_FOUND;\r
+ Routine = &mPartitionDetectRoutineTable[0];\r
+ while (*Routine != NULL) {\r
+ Status = (*Routine) (\r
+ This,\r
+ ControllerHandle,\r
+ DiskIo,\r
+ BlockIo,\r
+ ParentDevicePath\r
+ );\r
+ if (!EFI_ERROR (Status) || Status == EFI_MEDIA_CHANGED) {\r
+ break;\r
+ }\r
+ Routine++;\r
// driver. So don't try to close them. Otherwise, we will break the dependency\r
// between the controller and the driver set up before.\r
//\r
// driver. So don't try to close them. Otherwise, we will break the dependency\r
// between the controller and the driver set up before.\r
//\r
- if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus)) {\r
+ if (EFI_ERROR (Status) && !EFI_ERROR (OpenStatus) && Status != EFI_MEDIA_CHANGED) {\r
gBS->CloseProtocol (\r
ControllerHandle,\r
&gEfiDiskIoProtocolGuid,\r
gBS->CloseProtocol (\r
ControllerHandle,\r
&gEfiDiskIoProtocolGuid,\r
PartitionInstallGptChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallGptChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallElToritoChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallElToritoChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallMbrChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
PartitionInstallMbrChildHandles (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
+typedef \r
+EFI_STATUS\r
+(*PARTITION_DETECT_ROUTINE) (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Handle,\r
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ );\r
+\r