EFI_EXT_SCSI_PASS_THRU_PROTOCOL PassThru;\r
EFI_EXT_SCSI_PASS_THRU_MODE PassThruMode;\r
UINT8 MaxTarget;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
} MPT_SCSI_DEV;\r
\r
#define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \\r
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
)\r
{\r
- return EFI_UNSUPPORTED;\r
+ MPT_SCSI_DEV *Dev;\r
+ SCSI_DEVICE_PATH *ScsiDevicePath;\r
+\r
+ if (DevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // This device support 256 targets only, so it's enough to dereference\r
+ // the LSB of Target.\r
+ //\r
+ Dev = MPT_SCSI_FROM_PASS_THRU (This);\r
+ if (*Target > Dev->MaxTarget || Lun > 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ ScsiDevicePath = AllocateZeroPool (sizeof (*ScsiDevicePath));\r
+ if (ScsiDevicePath == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ScsiDevicePath->Header.Type = MESSAGING_DEVICE_PATH;\r
+ ScsiDevicePath->Header.SubType = MSG_SCSI_DP;\r
+ ScsiDevicePath->Header.Length[0] = (UINT8)sizeof (*ScsiDevicePath);\r
+ ScsiDevicePath->Header.Length[1] = (UINT8)(sizeof (*ScsiDevicePath) >> 8);\r
+ ScsiDevicePath->Pun = *Target;\r
+ ScsiDevicePath->Lun = (UINT16)Lun;\r
+\r
+ *DevicePath = &ScsiDevicePath->Header;\r
+ return EFI_SUCCESS;\r
}\r
\r
STATIC\r
OUT UINT64 *Lun\r
)\r
{\r
- return EFI_UNSUPPORTED;\r
+ MPT_SCSI_DEV *Dev;\r
+ SCSI_DEVICE_PATH *ScsiDevicePath;\r
+\r
+ if (DevicePath == NULL ||\r
+ Target == NULL || *Target == NULL || Lun == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (DevicePath->Type != MESSAGING_DEVICE_PATH ||\r
+ DevicePath->SubType != MSG_SCSI_DP) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Dev = MPT_SCSI_FROM_PASS_THRU (This);\r
+ ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath;\r
+ if (ScsiDevicePath->Pun > Dev->MaxTarget ||\r
+ ScsiDevicePath->Lun > 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ ZeroMem (*Target, TARGET_MAX_BYTES);\r
+ //\r
+ // This device support 256 targets only, so it's enough to set the LSB\r
+ // of Target.\r
+ //\r
+ **Target = (UINT8)ScsiDevicePath->Pun;\r
+ *Lun = ScsiDevicePath->Lun;\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
STATIC\r
\r
Dev->MaxTarget = PcdGet8 (PcdMptScsiMaxTargetLimit);\r
\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **)&Dev->PciIo,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreePool;\r
+ }\r
+\r
//\r
// Host adapter channel, doesn't exist\r
//\r
&Dev->PassThru\r
);\r
if (EFI_ERROR (Status)) {\r
- goto FreePool;\r
+ goto CloseProtocol;\r
}\r
\r
return EFI_SUCCESS;\r
\r
+CloseProtocol:\r
+ gBS->CloseProtocol (\r
+ ControllerHandle,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle\r
+ );\r
+\r
FreePool:\r
FreePool (Dev);\r
\r
return Status;\r
}\r
\r
+ gBS->CloseProtocol (\r
+ ControllerHandle,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle\r
+ );\r
+\r
FreePool (Dev);\r
\r
return Status;\r