NULL\r
};\r
\r
-\r
-//\r
-// The ScsiBusProtocol is just used to locate ScsiBusDev\r
-// structure in the SCSIBusDriverBindingStop(). Then we can\r
-// Close all opened protocols and release this structure.\r
-//\r
-EFI_GUID mScsiBusProtocolGuid = EFI_SCSI_BUS_PROTOCOL_GUID;\r
-\r
VOID *mWorkingBuffer;\r
\r
/**\r
// \r
Status = gBS->InstallProtocolInterface (\r
&Controller,\r
- &mScsiBusProtocolGuid,\r
+ &gEfiCallerIdGuid,\r
EFI_NATIVE_INTERFACE,\r
&ScsiBusDev->BusIdentify\r
);\r
//\r
Status = gBS->OpenProtocol (\r
Controller,\r
- &mScsiBusProtocolGuid,\r
+ &gEfiCallerIdGuid,\r
(VOID **) &BusIdentify,\r
This->DriverBindingHandle,\r
Controller,\r
//\r
Status = gBS->OpenProtocol (\r
Controller,\r
- &mScsiBusProtocolGuid,\r
+ &gEfiCallerIdGuid,\r
(VOID **) &Scsidentifier,\r
This->DriverBindingHandle,\r
Controller,\r
//\r
gBS->UninstallProtocolInterface (\r
Controller,\r
- &mScsiBusProtocolGuid,\r
+ &gEfiCallerIdGuid,\r
&ScsiBusDev->BusIdentify\r
);\r
\r
EFI_STATUS Status;\r
SCSI_IO_DEV *ScsiIoDevice;\r
EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
+ EFI_HANDLE DeviceHandle;\r
+\r
+ DevicePath = NULL;\r
+ RemainingDevicePath = NULL;\r
+ ScsiDevicePath = NULL;\r
+ ScsiIoDevice = NULL;\r
+\r
+ //\r
+ // Build Device Path\r
+ //\r
+ if (ScsiBusDev->ExtScsiSupport){\r
+ Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (\r
+ ScsiBusDev->ExtScsiInterface,\r
+ &TargetId->ScsiId.ExtScsi[0],\r
+ Lun,\r
+ &ScsiDevicePath\r
+ );\r
+ } else {\r
+ Status = ScsiBusDev->ScsiInterface->BuildDevicePath (\r
+ ScsiBusDev->ScsiInterface,\r
+ TargetId->ScsiId.Scsi,\r
+ Lun,\r
+ &ScsiDevicePath\r
+ );\r
+ }\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DevicePath = AppendDevicePathNode (\r
+ ScsiBusDev->DevicePath,\r
+ ScsiDevicePath\r
+ );\r
+\r
+ if (DevicePath == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ DeviceHandle = NULL;\r
+ RemainingDevicePath = DevicePath;\r
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);\r
+ if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {\r
+ //\r
+ // The device has been started, directly return to fast boot.\r
+ //\r
+ Status = EFI_ALREADY_STARTED;\r
+ goto ErrorExit;\r
+ }\r
\r
ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));\r
if (ScsiIoDevice == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
}\r
\r
ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;\r
ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;\r
ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
\r
-\r
if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
- FreePool (ScsiIoDevice);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Set Device Path\r
- //\r
- ScsiDevicePath = NULL;\r
- if (ScsiIoDevice->ExtScsiSupport){\r
- Status = ScsiIoDevice->ExtScsiPassThru->BuildDevicePath (\r
- ScsiIoDevice->ExtScsiPassThru,\r
- &ScsiIoDevice->Pun.ScsiId.ExtScsi[0],\r
- ScsiIoDevice->Lun,\r
- &ScsiDevicePath\r
- );\r
- } else {\r
- Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (\r
- ScsiIoDevice->ScsiPassThru,\r
- ScsiIoDevice->Pun.ScsiId.Scsi,\r
- ScsiIoDevice->Lun,\r
- &ScsiDevicePath\r
- );\r
- }\r
-\r
- if (EFI_ERROR(Status)) {\r
- FreePool (ScsiIoDevice);\r
- return Status;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
}\r
\r
- ScsiIoDevice->DevicePath = AppendDevicePathNode (\r
- ScsiBusDev->DevicePath,\r
- ScsiDevicePath\r
- );\r
- //\r
- // The memory space for ScsiDevicePath is allocated in\r
- // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
- // after EfiAppendDevicePathNode,so free the memory it occupies.\r
- //\r
- FreePool (ScsiDevicePath);\r
-\r
- if (ScsiIoDevice->DevicePath == NULL) {\r
- FreePool (ScsiIoDevice);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
+ ScsiIoDevice->DevicePath = DevicePath;\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&ScsiIoDevice->Handle,\r
NULL\r
);\r
if (EFI_ERROR (Status)) {\r
- FreePool (ScsiIoDevice->DevicePath);\r
- FreePool (ScsiIoDevice);\r
- return EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
} else {\r
if (ScsiBusDev->ExtScsiSupport) {\r
gBS->OpenProtocol (\r
- Controller,\r
- &gEfiExtScsiPassThruProtocolGuid,\r
- (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
- This->DriverBindingHandle,\r
- ScsiIoDevice->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
+ Controller,\r
+ &gEfiExtScsiPassThruProtocolGuid,\r
+ (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
+ This->DriverBindingHandle,\r
+ ScsiIoDevice->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
} else {\r
gBS->OpenProtocol (\r
- Controller,\r
- &gEfiScsiPassThruProtocolGuid,\r
- (VOID **) &(ScsiBusDev->ScsiInterface),\r
- This->DriverBindingHandle,\r
- ScsiIoDevice->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
+ Controller,\r
+ &gEfiScsiPassThruProtocolGuid,\r
+ (VOID **) &(ScsiBusDev->ScsiInterface),\r
+ This->DriverBindingHandle,\r
+ ScsiIoDevice->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
}\r
}\r
return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+ \r
+ //\r
+ // The memory space for ScsiDevicePath is allocated in\r
+ // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
+ // after AppendDevicePathNode,so free the memory it occupies.\r
+ //\r
+ FreePool (ScsiDevicePath);\r
+\r
+ if (DevicePath != NULL) {\r
+ FreePool (DevicePath);\r
+ }\r
+\r
+ if (ScsiIoDevice != NULL) {\r
+ FreePool (ScsiIoDevice);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
\r
UINT8 TargetStatus;\r
EFI_SCSI_SENSE_DATA SenseData;\r
EFI_SCSI_INQUIRY_DATA InquiryData;\r
+ UINT8 MaxRetry;\r
+ UINT8 Index;\r
\r
HostAdapterStatus = 0;\r
TargetStatus = 0;\r
// Using Inquiry command to scan for the device\r
//\r
InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
- SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);\r
-\r
- Status = ScsiInquiryCommand (\r
- &ScsiIoDevice->ScsiIo,\r
- EFI_TIMER_PERIOD_SECONDS (1),\r
- (VOID *) &SenseData,\r
- &SenseDataLength,\r
- &HostAdapterStatus,\r
- &TargetStatus,\r
- (VOID *) &InquiryData,\r
- &InquiryDataLength,\r
- FALSE\r
- );\r
- if (EFI_ERROR (Status) && Status != EFI_BAD_BUFFER_SIZE) {\r
+ SenseDataLength = (UINT8) sizeof (EFI_SCSI_SENSE_DATA);\r
+ ZeroMem (&InquiryData, InquiryDataLength);\r
+\r
+ MaxRetry = 2;\r
+ for (Index = 0; Index < MaxRetry; Index++) {\r
+ Status = ScsiInquiryCommand (\r
+ &ScsiIoDevice->ScsiIo,\r
+ EFI_TIMER_PERIOD_SECONDS (1),\r
+ (VOID *) &SenseData,\r
+ &SenseDataLength,\r
+ &HostAdapterStatus,\r
+ &TargetStatus,\r
+ (VOID *) &InquiryData,\r
+ &InquiryDataLength,\r
+ FALSE\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ break;\r
+ } else if ((Status == EFI_BAD_BUFFER_SIZE) || \r
+ (Status == EFI_INVALID_PARAMETER) ||\r
+ (Status == EFI_UNSUPPORTED)) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ if (Index == MaxRetry) {\r
return FALSE;\r
}\r
+ \r
//\r
// Retrieved inquiry data successfully\r
//\r
//\r
// ANSI-approved version\r
//\r
- ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);\r
+ ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x07);\r
}\r
\r
return TRUE;\r