scsibus.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,046 行 · 第 1/3 页
C
1,046 行
//
// Remaining Device Path is not NULL, only scan the specified Pun.
//
Pun = StartPun;
Lun = StartLun;
ScanOtherPuns = FALSE;
}
//
// Avoid creating handle for the host adapter.
//
if (ScsiBusDev->ExtScsiSupport) {
if (Pun == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {
continue;
}
} else {
if (Pun == ScsiBusDev->ScsiInterface->Mode->AdapterId) {
continue;
}
}
//
// Scan for the scsi device, if it attaches to the scsi bus,
// then create handle and install scsi i/o protocol.
//
Status = ScsiScanCreateDevice (This, Controller, Pun, Lun, ScsiBusDev);
}
return Status;
}
EFI_STATUS
EFIAPI
SCSIBusDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to stop driver on
NumberOfChildren - Number of Children in the ChildHandleBuffer
ChildHandleBuffer - List of handles for the children we need to stop.
Returns:
EFI_SUCCESS
Others
--*/
{
EFI_STATUS Status;
BOOLEAN AllChildrenStopped;
UINTN Index;
EFI_SCSI_IO_PROTOCOL *ScsiIo;
SCSI_IO_DEV *ScsiIoDevice;
VOID *ScsiPassThru;
EFI_SCSI_BUS_PROTOCOL *Scsidentifier;
SCSI_BUS_DEVICE *ScsiBusDev;
if (NumberOfChildren == 0) {
//
// Get the SCSI_BUS_DEVICE
//
Status = gBS->OpenProtocol (
Controller,
&mScsiBusProtocolGuid,
(VOID **) &Scsidentifier,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (Scsidentifier);
//
// Uninstall SCSI Bus Protocol
//
gBS->UninstallProtocolInterface (
Controller,
&mScsiBusProtocolGuid,
&ScsiBusDev->BusIdentify
);
//
// Close the bus driver
//
if (ScsiBusDev->ExtScsiSupport) {
gBS->CloseProtocol (
Controller,
&gEfiExtScsiPassThruProtocolGuid,
This->DriverBindingHandle,
Controller
);
} else {
gBS->CloseProtocol (
Controller,
&gEfiScsiPassThruProtocolGuid,
This->DriverBindingHandle,
Controller
);
}
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->FreePool (ScsiBusDev);
return EFI_SUCCESS;
}
AllChildrenStopped = TRUE;
for (Index = 0; Index < NumberOfChildren; Index++) {
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiScsiIoProtocolGuid,
(VOID **) &ScsiIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
continue;
}
ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);
//
// Close the child handle
//
if (ScsiIoDevice->ExtScsiSupport) {
Status = gBS->CloseProtocol (
Controller,
&gEfiExtScsiPassThruProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
} else {
Status = gBS->CloseProtocol (
Controller,
&gEfiScsiPassThruProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
}
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
ScsiIoDevice->DevicePath,
&gEfiScsiIoProtocolGuid,
&ScsiIoDevice->ScsiIo,
NULL
);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
if (ScsiIoDevice->ExtScsiSupport) {
gBS->OpenProtocol (
Controller,
&gEfiExtScsiPassThruProtocolGuid,
&(EFI_EXT_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
gBS->OpenProtocol (
Controller,
&gEfiScsiPassThruProtocolGuid,
&(EFI_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
}
} else {
gBS->FreePool (ScsiIoDevice);
}
}
if (!AllChildrenStopped) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ScsiGetDeviceType (
IN EFI_SCSI_IO_PROTOCOL *This,
OUT UINT8 *DeviceType
)
/*++
Routine Description:
Retrieves the device type information of the SCSI Controller.
Arguments:
This - Protocol instance pointer.
DeviceType - A pointer to the device type information
retrieved from the SCSI Controller.
Returns:
EFI_SUCCESS - Retrieves the device type information successfully.
EFI_INVALID_PARAMETER - The DeviceType is NULL.
--*/
{
SCSI_IO_DEV *ScsiIoDevice;
if (DeviceType == NULL) {
return EFI_INVALID_PARAMETER;
}
ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
*DeviceType = ScsiIoDevice->ScsiDeviceType;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ScsiGetDeviceLocation (
IN EFI_SCSI_IO_PROTOCOL *This,
IN OUT UINT8 **Target,
OUT UINT64 *Lun
)
/*++
Routine Description:
Retrieves the device location in the SCSI channel.
Arguments:
This - Protocol instance pointer.
Target - A pointer to the Target Array which represents ID of a SCSI device
on the SCSI channel.
Lun - A pointer to the LUN of the SCSI device on
the SCSI channel.
Returns:
EFI_SUCCESS - Retrieves the device location successfully.
EFI_INVALID_PARAMETER - The Target or Lun is NULL.
--*/
{
SCSI_IO_DEV *ScsiIoDevice;
if (Target == NULL || Lun == NULL) {
return EFI_INVALID_PARAMETER;
}
ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
(*Target)[0] = (UINT8) (ScsiIoDevice->Pun & 0xff);
(*Target)[1] = (UINT8) ((ScsiIoDevice->Pun >> 8) & 0xff);
(*Target)[2] = (UINT8) ((ScsiIoDevice->Pun >> 16) & 0xff);
(*Target)[3] = (UINT8) ((ScsiIoDevice->Pun >> 24) & 0xff);
*Lun = ScsiIoDevice->Lun;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ScsiResetBus (
IN EFI_SCSI_IO_PROTOCOL *This
)
/*++
Routine Description:
Resets the SCSI Bus that the SCSI Controller is attached to.
Arguments:
This - Protocol instance pointer.
Returns:
EFI_SUCCESS - The SCSI bus is reset successfully.
EFI_DEVICE_ERROR - Errors encountered when resetting the SCSI bus.
EFI_UNSUPPORTED - The bus reset operation is not supported by the
SCSI Host Controller.
EFI_TIMEOUT - A timeout occurred while attempting to reset
the SCSI bus.
--*/
{
SCSI_IO_DEV *ScsiIoDevice;
ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
if (ScsiIoDevice->ExtScsiSupport){
return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);
} else {
return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);
}
}
EFI_STATUS
EFIAPI
ScsiResetDevice (
IN EFI_SCSI_IO_PROTOCOL *This
)
/*++
Routine Description:
Resets the SCSI Controller that the device handle specifies.
Arguments:
This - Protocol instance pointer.
Returns:
EFI_SUCCESS - Reset the SCSI controller successfully.
EFI_DEVICE_ERROR - Errors are encountered when resetting the
SCSI Controller.
EFI_UNSUPPORTED - The SCSI bus does not support a device
reset operation.
EFI_TIMEOUT - A timeout occurred while attempting to
reset the SCSI Controller.
--*/
{
SCSI_IO_DEV *ScsiIoDevice;
UINT8 Target[4];
ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?