Update the SCSI Disk Driver to not mount drives on physical only SCSI channels

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8677 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
gikidy 2009-06-29 05:58:14 +00:00
parent 248e14f111
commit d14faa5275
3 changed files with 179 additions and 38 deletions

View File

@ -244,26 +244,17 @@ ScsiDiskDriverBindingStart (
// //
Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp); Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
//
// Determine if Block IO should be produced on this controller handle
//
if (DetermineInstallBlockIo(Controller)) {
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&Controller, &Controller,
&gEfiBlockIoProtocolGuid, &gEfiBlockIoProtocolGuid,
&ScsiDiskDevice->BlkIo, &ScsiDiskDevice->BlkIo,
NULL NULL
); );
} if (!EFI_ERROR(Status)) {
if (EFI_ERROR (Status)) {
FreePool (ScsiDiskDevice->SenseData);
gBS->CloseProtocol (
Controller,
&gEfiScsiIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
FreePool (ScsiDiskDevice);
return Status;
}
ScsiDiskDevice->ControllerNameTable = NULL; ScsiDiskDevice->ControllerNameTable = NULL;
AddUnicodeString2 ( AddUnicodeString2 (
"eng", "eng",
@ -279,9 +270,20 @@ ScsiDiskDriverBindingStart (
L"SCSI Disk Device", L"SCSI Disk Device",
FALSE FALSE
); );
return EFI_SUCCESS; return EFI_SUCCESS;
}
}
}
gBS->FreePool (ScsiDiskDevice->SenseData);
gBS->FreePool (ScsiDiskDevice);
gBS->CloseProtocol (
Controller,
&gEfiScsiIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
} }
@ -2249,3 +2251,105 @@ ReleaseScsiDiskDeviceResources (
ScsiDiskDevice = NULL; ScsiDiskDevice = NULL;
} }
/**
Determine if Block Io should be produced.
@param ChildHandle Child Handle to retrive Parent information.
@retval TRUE Should produce Block Io.
@retval FALSE Should not produce Block Io.
**/
BOOLEAN
DetermineInstallBlockIo (
IN EFI_HANDLE ChildHandle
)
{
EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
//
// Firstly, check if ExtScsiPassThru Protocol parent handle exists. If existence,
// check its attribute, logic or physical.
//
ExtScsiPassThru = (EFI_EXT_SCSI_PASS_THRU_PROTOCOL *)GetParentProtocol (&gEfiExtScsiPassThruProtocolGuid, ChildHandle);
if (ExtScsiPassThru != NULL) {
if ((ExtScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL) != 0) {
return TRUE;
}
}
//
// Secondly, check if ScsiPassThru Protocol parent handle exists. If existence,
// check its attribute, logic or physical.
//
ScsiPassThru = (EFI_SCSI_PASS_THRU_PROTOCOL *)GetParentProtocol (&gEfiScsiPassThruProtocolGuid, ChildHandle);
if (ScsiPassThru != NULL) {
if ((ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL) != 0) {
return TRUE;
}
}
return FALSE;
}
/**
Search protocol database and check to see if the protocol
specified by ProtocolGuid is present on a ControllerHandle and opened by
ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
If the ControllerHandle is found, then the protocol specified by ProtocolGuid
will be opened on it.
@param ProtocolGuid ProtocolGuid pointer.
@param ChildHandle Child Handle to retrieve Parent information.
**/
VOID *
EFIAPI
GetParentProtocol (
IN EFI_GUID *ProtocolGuid,
IN EFI_HANDLE ChildHandle
)
{
UINTN Index;
UINTN HandleCount;
VOID *Interface;
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
//
// Retrieve the list of all handles from the handle database
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
ProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return NULL;
}
//
// Iterate to find who is parent handle that is opened with ProtocolGuid by ChildHandle
//
for (Index = 0; Index < HandleCount; Index++) {
Status = EfiTestChildHandle (HandleBuffer[Index], ChildHandle, ProtocolGuid);
if (!EFI_ERROR (Status)) {
Status = gBS->HandleProtocol (HandleBuffer[Index], ProtocolGuid, (VOID **)&Interface);
if (!EFI_ERROR (Status)) {
gBS->FreePool (HandleBuffer);
return Interface;
}
}
}
gBS->FreePool (HandleBuffer);
return NULL;
}

View File

@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/BlockIo.h> #include <Protocol/BlockIo.h>
#include <Protocol/DriverBinding.h> #include <Protocol/DriverBinding.h>
#include <Protocol/ScsiPassThruExt.h> #include <Protocol/ScsiPassThruExt.h>
#include <Protocol/ScsiPassThru.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h> #include <Library/UefiDriverEntryPoint.h>
@ -787,4 +788,38 @@ ReleaseScsiDiskDeviceResources (
IN SCSI_DISK_DEV *ScsiDiskDevice IN SCSI_DISK_DEV *ScsiDiskDevice
); );
/**
Determine if Block Io should be produced.
@param ChildHandle Child Handle to retrive Parent information.
@retval TRUE Should produce Block Io.
@retval FALSE Should not produce Block Io.
**/
BOOLEAN
DetermineInstallBlockIo (
IN EFI_HANDLE ChildHandle
);
/**
Search protocol database and check to see if the protocol
specified by ProtocolGuid is present on a ControllerHandle and opened by
ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
If the ControllerHandle is found, then the protocol specified by ProtocolGuid
will be opened on it.
@param ProtocolGuid ProtocolGuid pointer.
@param ChildHandle Child Handle to retrieve Parent information.
**/
VOID *
EFIAPI
GetParentProtocol (
IN EFI_GUID *ProtocolGuid,
IN EFI_HANDLE ChildHandle
);
#endif #endif

View File

@ -55,4 +55,6 @@
[Protocols] [Protocols]
gEfiBlockIoProtocolGuid ## BY_START gEfiBlockIoProtocolGuid ## BY_START
gEfiScsiIoProtocolGuid ## TO_START gEfiScsiIoProtocolGuid ## TO_START
gEfiScsiPassThruProtocolGuid ## TO_START
gEfiExtScsiPassThruProtocolGuid ## TO_START