SCSI Bus driver that layers on every SCSI Pass Thru and\r
Extended SCSI Pass Thru protocol in the system.\r
\r
-Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
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