/** Test to see if this driver supports ControllerHandle. This service is called by the EFI boot service ConnectController(). In order to make drivers as small as possible, there are a few calling restrictions for this service. ConnectController() must follow these calling restrictions. If any other agent wishes to call Supported() it must also follow these calling restrictions. @param This Protocol instance pointer. @param ControllerHandle Handle of device to test @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver supports this device @retval EFI_ALREADY_STARTED This driver is already running on this device @retval other This driver does not support this device **/ EFI_STATUS EFIAPI SCSIBusDriverBindingSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_SCSI_PASS_THRU_PROTOCOL *PassThru; EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru; UINT64 Lun; UINT8 *TargetId; SCSI_TARGET_ID ScsiTargetId; TargetId = &ScsiTargetId.ScsiId.ExtScsi[0]; SetMem (TargetId, TARGET_MAX_BYTES, 0xFF); // // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead. // Status = gBS->OpenProtocol ( Controller, &gEfiExtScsiPassThruProtocolGuid, (VOID **)&ExtPassThru, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (Status == EFI_ALREADY_STARTED) { return EFI_SUCCESS; } else if (!EFI_ERROR(Status)) { // // Check if RemainingDevicePath is NULL or the End of Device Path Node, // if yes, return EFI_SUCCESS. // if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) { // // Close protocol regardless of RemainingDevicePath validation // gBS->CloseProtocol ( Controller, &gEfiExtScsiPassThruProtocolGuid, This->DriverBindingHandle, Controller ); return EFI_SUCCESS; } else { // // If RemainingDevicePath isn't the End of Device Path Node, check its validation // Status = ExtPassThru->GetTargetLun (ExtPassThru, RemainingDevicePath, &TargetId, &Lun); // // Close protocol regardless of RemainingDevicePath validation // gBS->CloseProtocol ( Controller, &gEfiExtScsiPassThruProtocolGuid, This->DriverBindingHandle, Controller ); if (!EFI_ERROR(Status)) { return EFI_SUCCESS; } } } // // Come here in 2 condition: // 1. ExtPassThru doesn't exist. // 2. ExtPassThru exists but RemainingDevicePath is invalid. // Status = gBS->OpenProtocol ( Controller, &gEfiScsiPassThruProtocolGuid, (VOID **)&PassThru, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (Status == EFI_ALREADY_STARTED) { return EFI_SUCCESS; } if (EFI_ERROR (Status)) { return Status; } // // Test RemainingDevicePath is valid or not. // if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) { Status = PassThru->GetTargetLun (PassThru, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun); } gBS->CloseProtocol ( Controller, &gEfiScsiPassThruProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
// // TDS 4.3 // EFI_STATUS BBTestGetTargetLunConformanceAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru; EFI_TEST_ASSERTION AssertionType; UINT32 Target; UINT64 Lun; EFI_DEVICE_PATH_PROTOCOL *DevicePath; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } ScsiPassThru = (EFI_SCSI_PASS_THRU_PROTOCOL *)ClientInterface; // // Assertion Point 4.3.2.1 // Call GetTargetLun()with NULL DevicePath, NULL Target and NULL Lun. // Status = GetScsiDevice (ScsiPassThru, &Target, &Lun); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"Can't Get any Scsi Device", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return EFI_UNSUPPORTED; } // // Get the valid Device Path Node. // Status = ScsiPassThru->BuildDevicePath (ScsiPassThru, Target, Lun, &DevicePath); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"EFI_SCSI_PASS_THRU_PROTOCOL.BuildDevicePath", L"%a:%d:Status - %r, Target - %d, Lun - %ld", __FILE__, __LINE__, Status, Target, Lun ); return EFI_UNSUPPORTED; } // // Check Point 1. NULL Device Path. // Status = ScsiPassThru->GetTargetLun (ScsiPassThru, NULL, &Target, &Lun); if (Status == EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gScsiPassThruBBTestConformanceAssertionGuid007, L"EFI_SCSI_PASS_THRU_PROTOCOL.GetTargetLun - Invoke GetTargetLun() with NULL Device Path", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); // // Check Point 2. NULL Target. // Status = ScsiPassThru->GetTargetLun (ScsiPassThru, DevicePath, NULL, &Lun); if (Status == EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gScsiPassThruBBTestConformanceAssertionGuid008, L"EFI_SCSI_PASS_THRU_PROTOCOL.GetTargetLun - Invoke GetTargetLun() with NULL Target", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); // // Check Point 3. NULL Lun. // Status = ScsiPassThru->GetTargetLun (ScsiPassThru, DevicePath, &Target, NULL); if (Status == EFI_INVALID_PARAMETER) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gScsiPassThruBBTestConformanceAssertionGuid009, L"EFI_SCSI_PASS_THRU_PROTOCOL.GetTargetLun - Invoke GetTargetLun() with NULL Lun", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); // // Assertion Point 4.3.2.2 // Call GetTargetLun()with unsupported DevicePath. // // // Set the Device Path to Non Scsi Device Path. // DevicePath->Type = 5; DevicePath->SubType = 1; Status = ScsiPassThru->GetTargetLun (ScsiPassThru, DevicePath, &Target, &Lun); if (Status == EFI_UNSUPPORTED) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } //Free the DevicePath. gtBS->FreePool (DevicePath); StandardLib->RecordAssertion ( StandardLib, AssertionType, gScsiPassThruBBTestConformanceAssertionGuid010, L"EFI_SCSI_PASS_THRU_PROTOCOL.GetTargetLun - Invoke GetTargetLun() with unsupported Device Path", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return EFI_SUCCESS; }
// // TDS 3.3 // EFI_STATUS BBTestGetTargetLunFunctionAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru; EFI_TEST_ASSERTION AssertionType; UINT32 Target; UINT64 Lun; UINT32 NewTarget; UINT64 NewLun; EFI_DEVICE_PATH_PROTOCOL *DevicePath; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if ( EFI_ERROR(Status) ) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r\n", __FILE__, (UINTN)__LINE__, Status ); return Status; } ScsiPassThru = (EFI_SCSI_PASS_THRU_PROTOCOL *)ClientInterface; // // Assertion Point 3.3.2.1 // Call GetTargetLun(). // Target = 0xFFFFFFFF; Status = GetPresentTargetLun(ScsiPassThru, &Target, &Lun); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"Can't Get any Scsi Device", L"%a:%d:Status - %r\n", __FILE__, (UINTN)__LINE__, Status ); return EFI_UNSUPPORTED; } // // Get the valid Device Path Node. // Status = ScsiPassThru->BuildDevicePath (ScsiPassThru, Target, Lun, &DevicePath); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"EFI_SCSI_PASS_THRU_PROTOCOL.BuildDevicePath", L"%a:%d:Status - %r, Target - %d, Lun - %ld\n", __FILE__, (UINTN)__LINE__, Status, Target, Lun ); return EFI_UNSUPPORTED; } Status = ScsiPassThru->GetTargetLun (ScsiPassThru, DevicePath, &NewTarget, &NewLun); //Free the DevicePath. gtBS->FreePool (DevicePath); if ((!EFI_ERROR(Status)) && (NewTarget == Target) && (NewLun == Lun)) { AssertionType = EFI_TEST_ASSERTION_PASSED; } else { AssertionType = EFI_TEST_ASSERTION_FAILED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gScsiPassThruBBTestFunctionAssertionGuid003, L"EFI_SCSI_PASS_THRU_PROTOCOL.GetTargetLun - Invoke GetTargetLun() and verify interface correctness within test case", L"%a:%d:Status - %r, Target - %d, Lun - %ld, NewTarget - %d, NewLun - %ld\n", __FILE__, (UINTN)__LINE__, Status, Target, Lun, NewTarget, NewLun ); return EFI_SUCCESS; }