summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-29 05:58:14 +0000
committergikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-29 05:58:14 +0000
commitd14faa5275ef4e26c4137a69abc03d7f9fef3fce (patch)
tree028d7ce0ed4286d78c619bac52740137853e70de
parent248e14f111da2b346b823678dcf3be96bd08b6dd (diff)
downloadedk2-d14faa5275ef4e26c4137a69abc03d7f9fef3fce.zip
edk2-d14faa5275ef4e26c4137a69abc03d7f9fef3fce.tar.gz
edk2-d14faa5275ef4e26c4137a69abc03d7f9fef3fce.tar.bz2
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
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c178
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h35
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf4
3 files changed, 179 insertions, 38 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index 4278b9c..6faebc7 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -244,45 +244,47 @@ ScsiDiskDriverBindingStart (
//
Status = ScsiDiskDetectMedia (ScsiDiskDevice, TRUE, &Temp);
if (!EFI_ERROR (Status)) {
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Controller,
- &gEfiBlockIoProtocolGuid,
- &ScsiDiskDevice->BlkIo,
- NULL
- );
- }
-
- if (EFI_ERROR (Status)) {
- FreePool (ScsiDiskDevice->SenseData);
- gBS->CloseProtocol (
- Controller,
- &gEfiScsiIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- FreePool (ScsiDiskDevice);
- return Status;
+ //
+ // Determine if Block IO should be produced on this controller handle
+ //
+ if (DetermineInstallBlockIo(Controller)) {
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiBlockIoProtocolGuid,
+ &ScsiDiskDevice->BlkIo,
+ NULL
+ );
+ if (!EFI_ERROR(Status)) {
+ ScsiDiskDevice->ControllerNameTable = NULL;
+ AddUnicodeString2 (
+ "eng",
+ gScsiDiskComponentName.SupportedLanguages,
+ &ScsiDiskDevice->ControllerNameTable,
+ L"SCSI Disk Device",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gScsiDiskComponentName2.SupportedLanguages,
+ &ScsiDiskDevice->ControllerNameTable,
+ L"SCSI Disk Device",
+ FALSE
+ );
+ return EFI_SUCCESS;
+ }
+ }
}
- ScsiDiskDevice->ControllerNameTable = NULL;
- AddUnicodeString2 (
- "eng",
- gScsiDiskComponentName.SupportedLanguages,
- &ScsiDiskDevice->ControllerNameTable,
- L"SCSI Disk Device",
- TRUE
- );
- AddUnicodeString2 (
- "en",
- gScsiDiskComponentName2.SupportedLanguages,
- &ScsiDiskDevice->ControllerNameTable,
- L"SCSI Disk Device",
- FALSE
- );
-
-
- 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;
}
+
+/**
+ 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;
+}
+
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
index 300971a..c5761c2 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/BlockIo.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/ScsiPassThruExt.h>
+#include <Protocol/ScsiPassThru.h>
#include <Library/DebugLib.h>
#include <Library/UefiDriverEntryPoint.h>
@@ -787,4 +788,38 @@ ReleaseScsiDiskDeviceResources (
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
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
index 04550d5..c39bc6d 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
@@ -55,4 +55,6 @@
[Protocols]
gEfiBlockIoProtocolGuid ## BY_START
gEfiScsiIoProtocolGuid ## TO_START
-
+ gEfiScsiPassThruProtocolGuid ## TO_START
+ gEfiExtScsiPassThruProtocolGuid ## TO_START
+