add iSCSI protocol
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4423 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -24,6 +24,8 @@ Abstract:
|
|||||||
#define _NET_LIB_H_
|
#define _NET_LIB_H_
|
||||||
|
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Protocol/DriverBinding.h>
|
#include <Protocol/DriverBinding.h>
|
||||||
#include <Protocol/ComponentName.h>
|
#include <Protocol/ComponentName.h>
|
||||||
#include <Protocol/DriverConfiguration.h>
|
#include <Protocol/DriverConfiguration.h>
|
||||||
@ -214,6 +216,8 @@ extern EFI_IPv4_ADDRESS mZeroIp4Addr;
|
|||||||
|
|
||||||
#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
|
#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
|
||||||
#define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1)))
|
#define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1)))
|
||||||
|
#define NET_IS_LOWER_CASE_CHAR(Ch) (('a' <= (Ch)) && ((Ch) <= 'z'))
|
||||||
|
#define NET_IS_UPPER_CASE_CHAR(Ch) (('A' <= (Ch)) && ((Ch) <= 'Z'))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wrap functions to ease the impact of EFI library changes.
|
// Wrap functions to ease the impact of EFI library changes.
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
|
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
|
||||||
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
|
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
|
||||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||||
|
FrameworkIfrSupportLib|IntelFrameworkPkg/Library/FrameworkIfrSupportLib/IfrSupportLib.inf
|
||||||
|
|
||||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||||
@ -257,6 +258,8 @@
|
|||||||
MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf
|
MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf
|
||||||
MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf
|
MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf
|
||||||
|
|
||||||
|
MdeModulePkg/Universal/iScsi/IScsi.inf
|
||||||
|
|
||||||
MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
|
MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
|
||||||
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
|
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
|
||||||
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
|
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
|
||||||
|
146
MdeModulePkg/Universal/iScsi/ComponentName.c
Normal file
146
MdeModulePkg/Universal/iScsi/ComponentName.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
ComponentName.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
ComponentName protocol for iSCSI.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// EFI Component Name Protocol
|
||||||
|
//
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName = {
|
||||||
|
IScsiComponentNameGetDriverName,
|
||||||
|
IScsiComponentNameGetControllerName,
|
||||||
|
"eng"
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// EFI Component Name 2 Protocol
|
||||||
|
//
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2 = {
|
||||||
|
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IScsiComponentNameGetDriverName,
|
||||||
|
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IScsiComponentNameGetControllerName,
|
||||||
|
"en"
|
||||||
|
};
|
||||||
|
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable[] = {
|
||||||
|
{"eng;en", L"iSCSI Driver"},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiComponentNameGetDriverName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **DriverName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||||
|
Language - A pointer to a three character ISO 639-2 language identifier.
|
||||||
|
This is the language of the driver name that that the caller
|
||||||
|
is requesting, and it must match one of the languages specified
|
||||||
|
in SupportedLanguages. The number of languages supported by a
|
||||||
|
driver is up to the driver writer.
|
||||||
|
DriverName - A pointer to the Unicode string to return. This Unicode string
|
||||||
|
is the name of the driver specified by This in the language
|
||||||
|
specified by Language.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
EFI_SUCCESS - The Unicode string for the Driver specified by This
|
||||||
|
and the language specified by Language was returned
|
||||||
|
in DriverName.
|
||||||
|
EFI_INVALID_PARAMETER - Language is NULL.
|
||||||
|
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||||
|
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||||
|
language specified by Language.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
return LookupUnicodeString2 (
|
||||||
|
Language,
|
||||||
|
This->SupportedLanguages,
|
||||||
|
mIScsiDriverNameTable,
|
||||||
|
DriverName,
|
||||||
|
(BOOLEAN)(This == &gIScsiComponentName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiComponentNameGetControllerName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **ControllerName
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Retrieves a Unicode string that is the user readable name of the controller
|
||||||
|
that is being managed by an EFI Driver.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||||
|
ControllerHandle - The handle of a controller that the driver specified by
|
||||||
|
This is managing. This handle specifies the controller
|
||||||
|
whose name is to be returned.
|
||||||
|
ChildHandle - The handle of the child controller to retrieve the name
|
||||||
|
of. This is an optional parameter that may be NULL. It
|
||||||
|
will be NULL for device drivers. It will also be NULL
|
||||||
|
for a bus drivers that wish to retrieve the name of the
|
||||||
|
bus controller. It will not be NULL for a bus driver
|
||||||
|
that wishes to retrieve the name of a child controller.
|
||||||
|
Language - A pointer to a three character ISO 639-2 language
|
||||||
|
identifier. This is the language of the controller name
|
||||||
|
that that the caller is requesting, and it must match one
|
||||||
|
of the languages specified in SupportedLanguages. The
|
||||||
|
number of languages supported by a driver is up to the
|
||||||
|
driver writer.
|
||||||
|
ControllerName - A pointer to the Unicode string to return. This Unicode
|
||||||
|
string is the name of the controller specified by
|
||||||
|
ControllerHandle and ChildHandle in the language
|
||||||
|
specified by Language from the point of view of the
|
||||||
|
driver specified by This.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
EFI_SUCCESS - The Unicode string for the user readable name in the
|
||||||
|
language specified by Language for the driver
|
||||||
|
specified by This was returned in DriverName.
|
||||||
|
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||||
|
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
|
||||||
|
EFI_HANDLE.
|
||||||
|
EFI_INVALID_PARAMETER - Language is NULL.
|
||||||
|
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||||
|
EFI_UNSUPPORTED - The driver specified by This is not currently
|
||||||
|
managing the controller specified by
|
||||||
|
ControllerHandle and ChildHandle.
|
||||||
|
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||||
|
language specified by Language.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
96
MdeModulePkg/Universal/iScsi/IScsi.inf
Normal file
96
MdeModulePkg/Universal/iScsi/IScsi.inf
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#/** @file
|
||||||
|
# Component description file for iSCSI module.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 - 2007, Intel Corporation
|
||||||
|
# All rights reserved. This program and the accompanying materials
|
||||||
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
# http://opensource.org/licenses/bsd-license.php
|
||||||
|
#
|
||||||
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = iSCSI
|
||||||
|
FILE_GUID = 4579B72D-7EC4-4dd4-8486-083C86B182A7
|
||||||
|
MODULE_TYPE = DXE_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
EDK_RELEASE_VERSION = 0x00020000
|
||||||
|
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||||
|
|
||||||
|
ENTRY_POINT = IScsiDriverEntryPoint
|
||||||
|
UNLOAD_IMAGE = EfiIScsiUnload
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||||
|
#
|
||||||
|
# DRIVER_BINDING = gIScsiDriverBinding
|
||||||
|
# COMPONENT_NAME = gIScsiComponentName
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
IScsiTcp4Io.h
|
||||||
|
IScsiProto.h
|
||||||
|
IScsiMisc.h
|
||||||
|
IScsiIbft.h
|
||||||
|
IScsiExtScsiPassThru.h
|
||||||
|
IScsiDriver.h
|
||||||
|
IScsiDhcp.h
|
||||||
|
IScsiCommon.h
|
||||||
|
IScsiCHAP.h
|
||||||
|
IScsiTcp4Io.c
|
||||||
|
IScsiProto.c
|
||||||
|
IScsiMisc.c
|
||||||
|
IScsiInitiatorName.c
|
||||||
|
IScsiIbft.c
|
||||||
|
IScsiExtScsiPassThru.c
|
||||||
|
IScsiDriver.c
|
||||||
|
IScsiDhcp.c
|
||||||
|
IScsiCHAP.c
|
||||||
|
ComponentName.c
|
||||||
|
Md5.c
|
||||||
|
IScsiConfigDxeStrings.uni
|
||||||
|
IScsiConfigDxe.vfr
|
||||||
|
IScsiConfig.c
|
||||||
|
IScsiConfig.h
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||||
|
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
UefiLib
|
||||||
|
BaseLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
BaseMemoryLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
DevicePathLib
|
||||||
|
DebugLib
|
||||||
|
PrintLib
|
||||||
|
FrameworkHiiLib
|
||||||
|
FrameworkIfrSupportLib
|
||||||
|
NetLib
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiIScsiInitiatorNameProtocolGuid
|
||||||
|
gEfiBlockIoProtocolGuid
|
||||||
|
gEfiTcp4ProtocolGuid
|
||||||
|
gEfiExtScsiPassThruProtocolGuid
|
||||||
|
gEfiDevicePathProtocolGuid
|
||||||
|
gEfiTcp4ServiceBindingProtocolGuid
|
||||||
|
gEfiFormCallbackProtocolGuid
|
||||||
|
gEfiFormBrowserProtocolGuid
|
||||||
|
gEfiPciIoProtocolGuid
|
||||||
|
gEfiAcpiSupportProtocolGuid
|
||||||
|
gEfiDhcp4ProtocolGuid
|
||||||
|
gEfiDhcp4ServiceBindingProtocolGuid
|
429
MdeModulePkg/Universal/iScsi/IScsiCHAP.c
Normal file
429
MdeModulePkg/Universal/iScsi/IScsiCHAP.c
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiCHAP.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
#include "Md5.h"
|
||||||
|
|
||||||
|
EFI_GUID mIScsiCHAPAuthInfoGuid = ISCSI_CHAP_AUTH_INFO_GUID;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPCalculateResponse (
|
||||||
|
IN UINT32 ChapIdentifier,
|
||||||
|
IN CHAR8 *ChapSecret,
|
||||||
|
IN UINT32 SecretLength,
|
||||||
|
IN UINT8 *ChapChallenge,
|
||||||
|
IN UINT32 ChallengeLength,
|
||||||
|
OUT UINT8 *ChapResponse
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MD5_CTX Md5Ctx;
|
||||||
|
CHAR8 IdByte[1];
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Status = MD5Init (&Md5Ctx);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hash Identifier - Only calculate 1 byte data (RFC1994)
|
||||||
|
//
|
||||||
|
IdByte[0] = (CHAR8) ChapIdentifier;
|
||||||
|
MD5Update (&Md5Ctx, IdByte, 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hash Secret
|
||||||
|
//
|
||||||
|
if (SecretLength < ISCSI_CHAP_SECRET_MIN_LEN - 1) {
|
||||||
|
return EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MD5Update (&Md5Ctx, ChapSecret, SecretLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hash Challenge received from Target
|
||||||
|
//
|
||||||
|
MD5Update (&Md5Ctx, ChapChallenge, ChallengeLength);
|
||||||
|
|
||||||
|
Status = MD5Final (&Md5Ctx, ChapResponse);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPAuthTarget (
|
||||||
|
IN ISCSI_CHAP_AUTH_DATA *AuthData,
|
||||||
|
IN UINT8 *TargetResponse
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 SecretSize;
|
||||||
|
UINT8 VerifyRsp[ISCSI_CHAP_RSP_LEN];
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
SecretSize = (UINT32) AsciiStrLen (AuthData->AuthConfig.ReverseCHAPSecret);
|
||||||
|
Status = IScsiCHAPCalculateResponse (
|
||||||
|
AuthData->OutIdentifier,
|
||||||
|
AuthData->AuthConfig.ReverseCHAPSecret,
|
||||||
|
SecretSize,
|
||||||
|
AuthData->OutChallenge,
|
||||||
|
AuthData->OutChallengeLength,
|
||||||
|
VerifyRsp
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NetCompareMem (VerifyRsp, TargetResponse, ISCSI_CHAP_RSP_LEN)) {
|
||||||
|
Status = EFI_SECURITY_VIOLATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPOnRspReceived (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN BOOLEAN Transit
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function checks the received iSCSI Login Response during the security
|
||||||
|
negotiation stage.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Conn - The iSCSI connection.
|
||||||
|
Transit - The transit flag of the latest iSCSI Login Response.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The Login Response passed the CHAP validation.
|
||||||
|
EFI_OUT_OF_RESOURCES - Failed to allocate memory.
|
||||||
|
EFI_PROTOCOL_ERROR - Some kind of protocol error happend.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
ISCSI_SESSION_CONFIG_DATA *ConfigData;
|
||||||
|
ISCSI_CHAP_AUTH_DATA *AuthData;
|
||||||
|
CHAR8 *Value;
|
||||||
|
UINT8 *Data;
|
||||||
|
UINT32 Len;
|
||||||
|
NET_LIST_ENTRY *KeyValueList;
|
||||||
|
UINTN Algorithm;
|
||||||
|
CHAR8 *Identifier;
|
||||||
|
CHAR8 *Challenge;
|
||||||
|
CHAR8 *Name;
|
||||||
|
CHAR8 *Response;
|
||||||
|
UINT8 TargetRsp[ISCSI_CHAP_RSP_LEN];
|
||||||
|
UINT32 RspLen;
|
||||||
|
|
||||||
|
ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
|
||||||
|
ASSERT (Conn->RspQue.BufNum != 0);
|
||||||
|
|
||||||
|
Session = Conn->Session;
|
||||||
|
ConfigData = &Session->ConfigData;
|
||||||
|
AuthData = &Session->AuthData;
|
||||||
|
|
||||||
|
Len = Conn->RspQue.BufSize;
|
||||||
|
Data = NetAllocatePool (Len);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Copy the data in case the data spans over multiple PDUs.
|
||||||
|
//
|
||||||
|
NetbufQueCopy (&Conn->RspQue, 0, Len, Data);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build the key-value list from the data segment of the Login Response.
|
||||||
|
//
|
||||||
|
KeyValueList = IScsiBuildKeyValueList (Data, Len);
|
||||||
|
if (KeyValueList == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_PROTOCOL_ERROR;
|
||||||
|
|
||||||
|
switch (Conn->CHAPStep) {
|
||||||
|
case ISCSI_CHAP_INITIAL:
|
||||||
|
//
|
||||||
|
// The first Login Response.
|
||||||
|
//
|
||||||
|
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
|
||||||
|
if (Value == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session->TargetPortalGroupTag = (UINT16) AsciiStrDecimalToUintn (Value);
|
||||||
|
|
||||||
|
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_AUTH_METHOD);
|
||||||
|
if (Value == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initiator mandates CHAP authentication but target replies without "CHAP" or
|
||||||
|
// initiator suggets "None" but target replies with some kind of auth method.
|
||||||
|
//
|
||||||
|
if (AsciiStrCmp (Value, ISCSI_AUTH_METHOD_CHAP) == 0) {
|
||||||
|
if (AuthData->AuthConfig.CHAPType == ISCSI_CHAP_NONE) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (AuthData->AuthConfig.CHAPType != ISCSI_CHAP_NONE) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Transit to CHAP step one.
|
||||||
|
//
|
||||||
|
Conn->CHAPStep = ISCSI_CHAP_STEP_ONE;
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_STEP_TWO:
|
||||||
|
//
|
||||||
|
// The Target replies with CHAP_A=<A> CHAP_I=<I> CHAP_C=<C>
|
||||||
|
//
|
||||||
|
Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_ALGORITHM);
|
||||||
|
if (Value == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Algorithm = AsciiStrDecimalToUintn (Value);
|
||||||
|
if (Algorithm != ISCSI_CHAP_ALGORITHM_MD5) {
|
||||||
|
//
|
||||||
|
// Unsupported algorithm is chosen by target.
|
||||||
|
//
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_IDENTIFIER);
|
||||||
|
if (Identifier == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Challenge = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_CHALLENGE);
|
||||||
|
if (Challenge == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Process the CHAP identifier and CHAP Challenge from Target
|
||||||
|
// Calculate Response value
|
||||||
|
//
|
||||||
|
AuthData->InIdentifier = (UINT32) AsciiStrDecimalToUintn (Identifier);
|
||||||
|
AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
|
||||||
|
IScsiHexToBin ((UINT8 *) AuthData->InChallenge, &AuthData->InChallengeLength, Challenge);
|
||||||
|
Status = IScsiCHAPCalculateResponse (
|
||||||
|
AuthData->InIdentifier,
|
||||||
|
AuthData->AuthConfig.CHAPSecret,
|
||||||
|
(UINT32) AsciiStrLen (AuthData->AuthConfig.CHAPSecret),
|
||||||
|
AuthData->InChallenge,
|
||||||
|
AuthData->InChallengeLength,
|
||||||
|
AuthData->CHAPResponse
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Transit to next step.
|
||||||
|
//
|
||||||
|
Conn->CHAPStep = ISCSI_CHAP_STEP_THREE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_STEP_THREE:
|
||||||
|
//
|
||||||
|
// one way CHAP authentication and the target would like to
|
||||||
|
// authenticate us.
|
||||||
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_STEP_FOUR:
|
||||||
|
ASSERT (AuthData->AuthConfig.CHAPType == ISCSI_CHAP_MUTUAL);
|
||||||
|
//
|
||||||
|
// The forth step, CHAP_N=<N> CHAP_R=<R> is received from Target.
|
||||||
|
//
|
||||||
|
Name = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_NAME);
|
||||||
|
if (Name == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Response = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_RESPONSE);
|
||||||
|
if (Response == NULL) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
RspLen = ISCSI_CHAP_RSP_LEN;
|
||||||
|
IScsiHexToBin (TargetRsp, &RspLen, Response);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the CHAP Name and Response replied by Target.
|
||||||
|
//
|
||||||
|
Status = IScsiCHAPAuthTarget (AuthData, TargetRsp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
|
||||||
|
IScsiFreeKeyValueList (KeyValueList);
|
||||||
|
|
||||||
|
NetFreePool (Data);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPToSendReq (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN NET_BUF *Pdu
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function fills the CHAP authentication information into the login PDU
|
||||||
|
during the security negotiation stage in the iSCSI connection login.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Conn - The iSCSI connection.
|
||||||
|
Pdu - The PDU to send out.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - All check passed and the phase-related CHAP authentication
|
||||||
|
info is filled into the iSCSI PDU.
|
||||||
|
EFI_OUT_OF_RESOURCES - Failed to allocate memory.
|
||||||
|
EFI_PROTOCOL_ERROR - Some kind of protocol error happend.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
ISCSI_LOGIN_REQUEST *LoginReq;
|
||||||
|
ISCSI_SESSION_CONFIG_DATA *ConfigData;
|
||||||
|
ISCSI_CHAP_AUTH_DATA *AuthData;
|
||||||
|
CHAR8 *Value;
|
||||||
|
CHAR8 ValueStr[256];
|
||||||
|
CHAR8 *Response;
|
||||||
|
UINT32 RspLen;
|
||||||
|
CHAR8 *Challenge;
|
||||||
|
UINT32 ChallengeLen;
|
||||||
|
|
||||||
|
ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
|
||||||
|
|
||||||
|
Session = Conn->Session;
|
||||||
|
ConfigData = &Session->ConfigData;
|
||||||
|
AuthData = &Session->AuthData;
|
||||||
|
LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufGetByte (Pdu, 0, 0);
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
RspLen = 2 * ISCSI_CHAP_RSP_LEN + 3;
|
||||||
|
Response = NetAllocatePool (RspLen);
|
||||||
|
if (Response == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChallengeLen = 2 * ISCSI_CHAP_RSP_LEN + 3;
|
||||||
|
Challenge = NetAllocatePool (ChallengeLen);
|
||||||
|
if (Challenge == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Conn->CHAPStep) {
|
||||||
|
case ISCSI_CHAP_INITIAL:
|
||||||
|
//
|
||||||
|
// It's the initial Login Request. Fill in the key=value pairs mandatory
|
||||||
|
// for the initial Login Request.
|
||||||
|
//
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_INITIATOR_NAME, Session->InitiatorName);
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_SESSION_TYPE, "Normal");
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_TARGET_NAME, Session->ConfigData.NvData.TargetName);
|
||||||
|
|
||||||
|
if (AuthData->AuthConfig.CHAPType == ISCSI_CHAP_NONE) {
|
||||||
|
Value = ISCSI_KEY_VALUE_NONE;
|
||||||
|
ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
|
||||||
|
} else {
|
||||||
|
Value = ISCSI_AUTH_METHOD_CHAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_AUTH_METHOD, Value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_STEP_ONE:
|
||||||
|
//
|
||||||
|
// First step, send the Login Request with CHAP_A=<A1,A2...> key-value pair.
|
||||||
|
//
|
||||||
|
AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", ISCSI_CHAP_ALGORITHM_MD5);
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_ALGORITHM, ValueStr);
|
||||||
|
|
||||||
|
Conn->CHAPStep = ISCSI_CHAP_STEP_TWO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_STEP_THREE:
|
||||||
|
//
|
||||||
|
// Third step, send the Login Request with CHAP_N=<N> CHAP_R=<R> or
|
||||||
|
// CHAP_N=<N> CHAP_R=<R> CHAP_I=<I> CHAP_C=<C> if target ahtentication is
|
||||||
|
// required too.
|
||||||
|
//
|
||||||
|
// CHAP_N=<N>
|
||||||
|
//
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_NAME, (UINT8 *) &AuthData->AuthConfig.CHAPName);
|
||||||
|
//
|
||||||
|
// CHAP_R=<R>
|
||||||
|
//
|
||||||
|
IScsiBinToHex ((UINT8 *) AuthData->CHAPResponse, ISCSI_CHAP_RSP_LEN, Response, &RspLen);
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_RESPONSE, Response);
|
||||||
|
|
||||||
|
if (AuthData->AuthConfig.CHAPType == ISCSI_CHAP_MUTUAL) {
|
||||||
|
//
|
||||||
|
// CHAP_I=<I>
|
||||||
|
//
|
||||||
|
IScsiGenRandom ((UINT8 *) &AuthData->OutIdentifier, 1);
|
||||||
|
AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier);
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr);
|
||||||
|
//
|
||||||
|
// CHAP_C=<C>
|
||||||
|
//
|
||||||
|
IScsiGenRandom ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN);
|
||||||
|
AuthData->OutChallengeLength = ISCSI_CHAP_RSP_LEN;
|
||||||
|
IScsiBinToHex ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN, Challenge, &ChallengeLen);
|
||||||
|
IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_CHALLENGE, Challenge);
|
||||||
|
|
||||||
|
Conn->CHAPStep = ISCSI_CHAP_STEP_FOUR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// set the stage transition flag.
|
||||||
|
//
|
||||||
|
ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = EFI_PROTOCOL_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetFreePool (Response);
|
||||||
|
NetFreePool (Challenge);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
95
MdeModulePkg/Universal/iScsi/IScsiCHAP.h
Normal file
95
MdeModulePkg/Universal/iScsi/IScsiCHAP.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiCHAP.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_CHAP_H_
|
||||||
|
#define _ISCSI_CHAP_H_
|
||||||
|
|
||||||
|
#define ISCSI_CHAP_AUTH_INFO_GUID \
|
||||||
|
{ \
|
||||||
|
0x786ec0ac, 0x65ae, 0x4d1b, 0xb1, 0x37, 0xd, 0x11, 0xa, 0x48, 0x37, 0x97 \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern EFI_GUID mIScsiCHAPAuthInfoGuid;
|
||||||
|
|
||||||
|
#define ISCSI_AUTH_METHOD_CHAP "CHAP"
|
||||||
|
|
||||||
|
#define ISCSI_KEY_CHAP_ALGORITHM "CHAP_A"
|
||||||
|
#define ISCSI_KEY_CHAP_IDENTIFIER "CHAP_I"
|
||||||
|
#define ISCSI_KEY_CHAP_CHALLENGE "CHAP_C"
|
||||||
|
#define ISCSI_KEY_CHAP_NAME "CHAP_N"
|
||||||
|
#define ISCSI_KEY_CHAP_RESPONSE "CHAP_R"
|
||||||
|
|
||||||
|
#define ISCSI_CHAP_ALGORITHM_MD5 5
|
||||||
|
|
||||||
|
#define ISCSI_CHAP_AUTH_MAX_LEN 1024
|
||||||
|
#define ISCSI_CHAP_RSP_LEN 16 // == MD5_HASHSIZE
|
||||||
|
typedef enum {
|
||||||
|
ISCSI_CHAP_INITIAL,
|
||||||
|
ISCSI_CHAP_STEP_ONE,
|
||||||
|
ISCSI_CHAP_STEP_TWO,
|
||||||
|
ISCSI_CHAP_STEP_THREE,
|
||||||
|
ISCSI_CHAP_STEP_FOUR
|
||||||
|
} ISCSI_CHAP_STEP;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct _ISCSI_CHAP_AUTH_CONFIG_NVDATA {
|
||||||
|
UINT8 CHAPType;
|
||||||
|
CHAR8 CHAPName[ISCSI_CHAP_NAME_MAX_LEN];
|
||||||
|
CHAR8 CHAPSecret[ISCSI_CHAP_SECRET_MAX_LEN];
|
||||||
|
CHAR8 ReverseCHAPName[ISCSI_CHAP_NAME_MAX_LEN];
|
||||||
|
CHAR8 ReverseCHAPSecret[ISCSI_CHAP_SECRET_MAX_LEN];
|
||||||
|
} ISCSI_CHAP_AUTH_CONFIG_NVDATA;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
//
|
||||||
|
// ISCSI CHAP Authentication Data
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_CHAP_AUTH_DATA {
|
||||||
|
ISCSI_CHAP_AUTH_CONFIG_NVDATA AuthConfig;
|
||||||
|
UINT32 InIdentifier;
|
||||||
|
UINT8 InChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
|
||||||
|
UINT32 InChallengeLength;
|
||||||
|
//
|
||||||
|
// Calculated CHAP Response (CHAP_R) value
|
||||||
|
//
|
||||||
|
UINT8 CHAPResponse[ISCSI_CHAP_RSP_LEN];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Auth-data to be sent out for mutual authentication
|
||||||
|
//
|
||||||
|
UINT32 OutIdentifier;
|
||||||
|
UINT8 OutChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
|
||||||
|
UINT32 OutChallengeLength;
|
||||||
|
} ISCSI_CHAP_AUTH_DATA;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPOnRspReceived (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN BOOLEAN Transit
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCHAPToSendReq (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN NET_BUF *Pdu
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
28
MdeModulePkg/Universal/iScsi/IScsiCommon.h
Normal file
28
MdeModulePkg/Universal/iScsi/IScsiCommon.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiCommon.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_COMMON_H_
|
||||||
|
#define _ISCSI_COMMON_H_
|
||||||
|
|
||||||
|
typedef struct _ISCSI_SESSION ISCSI_SESSION;
|
||||||
|
typedef struct _ISCSI_CONNECTION ISCSI_CONNECTION;
|
||||||
|
typedef struct _ISCSI_DRIVER_DATA ISCSI_DRIVER_DATA;
|
||||||
|
typedef struct _ISCSI_SESSION_CONFIG_DATA ISCSI_SESSION_CONFIG_DATA;
|
||||||
|
|
||||||
|
#endif
|
1074
MdeModulePkg/Universal/iScsi/IScsiConfig.c
Normal file
1074
MdeModulePkg/Universal/iScsi/IScsiConfig.c
Normal file
File diff suppressed because it is too large
Load Diff
111
MdeModulePkg/Universal/iScsi/IScsiConfig.h
Normal file
111
MdeModulePkg/Universal/iScsi/IScsiConfig.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiConfig.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_CONFIG_H_
|
||||||
|
#define _ISCSI_CONFIG_H_
|
||||||
|
|
||||||
|
//#include "Tiano.h"
|
||||||
|
//#include "EfiDriverLib.h"
|
||||||
|
//#include "Base.h"
|
||||||
|
#include <Library/FrameworkHiiLib.h>
|
||||||
|
#include <Protocol/FrameworkFormBrowser.h>
|
||||||
|
#include <Protocol/FrameworkFormCallback.h>
|
||||||
|
#include <Library/FrameworkIfrSupportLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
//#include "EfiPrintLib.h"
|
||||||
|
//#include EFI_PROTOCOL_DEFINITION (Hii)
|
||||||
|
//#include EFI_PROTOCOL_DEFINITION (FormBrowser)
|
||||||
|
//#include EFI_PROTOCOL_DEFINITION (FormCallback)
|
||||||
|
|
||||||
|
#include <Library/NetLib.h>
|
||||||
|
#include "IScsiConfigNVDataStruc.h"
|
||||||
|
|
||||||
|
extern UINT8 IScsiConfigDxeBin[];
|
||||||
|
extern UINT8 iSCSIStrings[];
|
||||||
|
|
||||||
|
#define ISCSI_INITATOR_NAME_VAR_NAME L"I_NAME"
|
||||||
|
|
||||||
|
#define ISCSI_CONFIG_VAR_ATTR (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE)
|
||||||
|
|
||||||
|
#define ISCSI_FORM_CALLBACK_INFO_SIGNATURE EFI_SIGNATURE_32 ('I', 'f', 'c', 'i')
|
||||||
|
|
||||||
|
#define ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK(Callback) \
|
||||||
|
CR ( \
|
||||||
|
Callback, \
|
||||||
|
ISCSI_FORM_CALLBACK_INFO, \
|
||||||
|
FormCallback, \
|
||||||
|
ISCSI_FORM_CALLBACK_INFO_SIGNATURE \
|
||||||
|
)
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct _ISCSI_MAC_INFO {
|
||||||
|
EFI_MAC_ADDRESS Mac;
|
||||||
|
UINT8 Len;
|
||||||
|
} ISCSI_MAC_INFO;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_DEVICE_LIST {
|
||||||
|
UINT8 NumDevice;
|
||||||
|
ISCSI_MAC_INFO MacInfo[1];
|
||||||
|
} ISCSI_DEVICE_LIST;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct _ISCSI_CONFIG_FORM_ENTRY {
|
||||||
|
NET_LIST_ENTRY Link;
|
||||||
|
EFI_HANDLE Controller;
|
||||||
|
CHAR16 MacString[95];
|
||||||
|
STRING_REF PortTitleToken;
|
||||||
|
STRING_REF PortTitleHelpToken;
|
||||||
|
|
||||||
|
ISCSI_SESSION_CONFIG_NVDATA SessionConfigData;
|
||||||
|
ISCSI_CHAP_AUTH_CONFIG_NVDATA AuthConfigData;
|
||||||
|
} ISCSI_CONFIG_FORM_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_FORM_CALLBACK_INFO {
|
||||||
|
UINTN Signature;
|
||||||
|
EFI_HANDLE CallbackHandle;
|
||||||
|
EFI_FORM_CALLBACK_PROTOCOL FormCallback;
|
||||||
|
UINT16 *KeyList;
|
||||||
|
VOID *FormBuffer;
|
||||||
|
EFI_HII_HANDLE RegisteredHandle;
|
||||||
|
EFI_HII_PROTOCOL *Hii;
|
||||||
|
ISCSI_CONFIG_FORM_ENTRY *Current;
|
||||||
|
} ISCSI_FORM_CALLBACK_INFO;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiConfigUpdateForm (
|
||||||
|
IN EFI_HANDLE DriverBindingHandle,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN BOOLEAN AddForm
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiConfigFormInit (
|
||||||
|
IN EFI_HANDLE DriverBindingHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiConfigFormUnload (
|
||||||
|
IN EFI_HANDLE DriverBindingHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
212
MdeModulePkg/Universal/iScsi/IScsiConfigDxe.vfr
Normal file
212
MdeModulePkg/Universal/iScsi/IScsiConfigDxe.vfr
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
// *++
|
||||||
|
//
|
||||||
|
//Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
//This software and associated documentation (if any) is furnished
|
||||||
|
//under a license and may only be used or copied in accordance
|
||||||
|
//with the terms of the license. Except as permitted by such
|
||||||
|
//license, no part of this software or documentation may be
|
||||||
|
//reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
//form or by any means without the express written consent of
|
||||||
|
//Intel Corporation.
|
||||||
|
//
|
||||||
|
// Module Name:
|
||||||
|
//
|
||||||
|
// IScsiConfigVfr.vfr
|
||||||
|
//
|
||||||
|
// Abstract:
|
||||||
|
//
|
||||||
|
// Revision History:
|
||||||
|
//
|
||||||
|
// --*/
|
||||||
|
|
||||||
|
#include "IScsiConfigNVDataStruc.h"
|
||||||
|
#define EFI_NETWORK_DEVICE_CLASS 0x04
|
||||||
|
|
||||||
|
formset
|
||||||
|
guid = ISCSI_CONFIG_GUID,
|
||||||
|
title = STRING_TOKEN(STR_ISCSI_CONFIG_FORM_TITLE),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_CONFIG_FORM_HELP),
|
||||||
|
class = EFI_NETWORK_DEVICE_CLASS,
|
||||||
|
subclass = 0x03,
|
||||||
|
|
||||||
|
form formid = FORMID_MAIN_FORM,
|
||||||
|
title = STRING_TOKEN(STR_ISCSI_MAIN_FORM_TITLE); // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.InitiatorName,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_CONFIG_INIT_NAME),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_CONFIG_INIT_NAME_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_INITIATOR_NAME,
|
||||||
|
minsize = 8,
|
||||||
|
maxsize = ISCSI_NAME_IFR_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
label DEVICE_ENTRY_LABEL;
|
||||||
|
|
||||||
|
endform;
|
||||||
|
|
||||||
|
form formid = FORMID_DEVICE_FORM,
|
||||||
|
title = STRING_TOKEN(STR_ISCSI_DEVICE_FORM_TITLE);
|
||||||
|
|
||||||
|
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.Enabled,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_DEVICE_ENABLE),
|
||||||
|
help = STRING_TOKEN(STR_NULL),
|
||||||
|
flags = 0,
|
||||||
|
endcheckbox;
|
||||||
|
|
||||||
|
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_DHCP_ENABLE,
|
||||||
|
endcheckbox;
|
||||||
|
|
||||||
|
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp == 0x01;
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.LocalIp,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_IP_ADDRESS),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_LOCAL_IP,
|
||||||
|
minsize = IP_MIN_SIZE,
|
||||||
|
maxsize = IP_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.SubnetMask,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_MASK),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_SUBNET_MASK,
|
||||||
|
minsize = IP_MIN_SIZE,
|
||||||
|
maxsize = IP_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.Gateway,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_LOCAL_GATEWAY),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_GATE_WAY,
|
||||||
|
minsize = IP_MIN_SIZE,
|
||||||
|
maxsize = IP_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
endif;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.InitiatorInfoFromDhcp == 0x00;
|
||||||
|
checkbox varid = ISCSI_CONFIG_IFR_NVDATA.TargetInfoFromDhcp,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP_ON_TARGET),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_ENABLE_DHCP_ON_TARGET),
|
||||||
|
flags = 0,
|
||||||
|
endcheckbox;
|
||||||
|
endif;
|
||||||
|
|
||||||
|
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.TargetInfoFromDhcp == 0x01;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.TargetName,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_TARGET_NAME),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_TARGET_NAME),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_TARGET_NAME,
|
||||||
|
minsize = 8,
|
||||||
|
maxsize = ISCSI_NAME_IFR_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.TargetIp,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_TARGET_IP_ADDRESS),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_TARGET_IP,
|
||||||
|
minsize = IP_MIN_SIZE,
|
||||||
|
maxsize = IP_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
numeric varid = ISCSI_CONFIG_IFR_NVDATA.TargetPort,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
|
||||||
|
flags = 0,
|
||||||
|
minimum = TARGET_PORT_MIN_NUM,
|
||||||
|
maximum = TARGET_PORT_MAX_NUM,
|
||||||
|
step = 0,
|
||||||
|
endnumeric;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.BootLun,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_BOOT_LUN),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_BOOT_LUN_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_BOOT_LUN,
|
||||||
|
minsize = LUN_MIN_SIZE,
|
||||||
|
maxsize = LUN_MAX_SIZE,
|
||||||
|
endstring;
|
||||||
|
endif;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
oneof varid = ISCSI_CONFIG_IFR_NVDATA.CHAPType,
|
||||||
|
prompt = STRING_TOKEN(STR_CHAP_TYPE_PROMPT),
|
||||||
|
help = STRING_TOKEN(STR_CHAP_TYPE_HELP),
|
||||||
|
option text = STRING_TOKEN(STR_CHAP_TYPE_NONE), value = ISCSI_CHAP_NONE, flags = DEFAULT;
|
||||||
|
option text = STRING_TOKEN(STR_CHAP_TYPE_UNI), value = ISCSI_CHAP_UNI, flags = 0;
|
||||||
|
option text = STRING_TOKEN(STR_CHAP_TYPE_MUTUAL), value = ISCSI_CHAP_MUTUAL, flags = 0;
|
||||||
|
endoneof;
|
||||||
|
|
||||||
|
suppressif ideqval ISCSI_CONFIG_IFR_NVDATA.CHAPType == ISCSI_CHAP_NONE;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.CHAPName,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_CHAP_NAME),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_CHAP_NAME),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_CHAP_NAME,
|
||||||
|
minsize = 0,
|
||||||
|
maxsize = ISCSI_CHAP_NAME_MAX_LEN,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.CHAPSecret,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_CHAP_SECRET),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_CHAP_SECRET_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_CHAP_SECRET,
|
||||||
|
minsize = ISCSI_CHAP_SECRET_MIN_LEN,
|
||||||
|
maxsize = ISCSI_CHAP_SECRET_MAX_LEN,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
endif;
|
||||||
|
|
||||||
|
suppressif NOT ideqval ISCSI_CONFIG_IFR_NVDATA.CHAPType == ISCSI_CHAP_MUTUAL;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.ReverseCHAPName,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_NAME),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_NAME),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_REVERSE_CHAP_NAME,
|
||||||
|
minsize = 0,
|
||||||
|
maxsize = ISCSI_CHAP_NAME_MAX_LEN,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
string varid = ISCSI_CONFIG_IFR_NVDATA.ReverseCHAPSecret,
|
||||||
|
prompt = STRING_TOKEN(STR_ISCSI_REVERSE_CHAP_SECRET),
|
||||||
|
help = STRING_TOKEN(STR_ISCSI_CHAP_SECRET_HELP),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_REVERSE_CHAP_SECRET,
|
||||||
|
minsize = ISCSI_CHAP_SECRET_MIN_LEN,
|
||||||
|
maxsize = ISCSI_CHAP_SECRET_MAX_LEN,
|
||||||
|
endstring;
|
||||||
|
|
||||||
|
endif;
|
||||||
|
|
||||||
|
subtitle text = STRING_TOKEN(STR_NULL);
|
||||||
|
|
||||||
|
goto FORMID_DEVICE_FORM,
|
||||||
|
prompt = STRING_TOKEN (STR_SAVE_CHANGES),
|
||||||
|
help = STRING_TOKEN (STR_SAVE_CHANGES),
|
||||||
|
flags = INTERACTIVE,
|
||||||
|
key = KEY_SAVE_CHANGES;
|
||||||
|
|
||||||
|
goto FORMID_MAIN_FORM,
|
||||||
|
prompt = STRING_TOKEN (STR_RETURN_MAIN_FORM),
|
||||||
|
help = STRING_TOKEN (STR_RETURN_MAIN_FORM),
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
endform;
|
||||||
|
|
||||||
|
endformset;
|
||||||
|
|
BIN
MdeModulePkg/Universal/iScsi/IScsiConfigDxeStrings.uni
Normal file
BIN
MdeModulePkg/Universal/iScsi/IScsiConfigDxeStrings.uni
Normal file
Binary file not shown.
104
MdeModulePkg/Universal/iScsi/IScsiConfigNVDataStruc.h
Normal file
104
MdeModulePkg/Universal/iScsi/IScsiConfigNVDataStruc.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiConfigNVDataStruc.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
NVData structure used by the iSCSI configuration component.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_NVDATASTRUC_H_
|
||||||
|
#define _ISCSI_NVDATASTRUC_H_
|
||||||
|
|
||||||
|
#define ISCSI_CONFIG_GUID \
|
||||||
|
{ \
|
||||||
|
0x6456ed61, 0x3579, 0x41c9, { 0x8a, 0x26, 0x0a, 0x0b, 0xd6, 0x2b, 0x78, 0xfc } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VAR_EQ_TEST_NAME 0x100
|
||||||
|
|
||||||
|
#define FORMID_MAIN_FORM 1
|
||||||
|
#define FORMID_DEVICE_FORM 2
|
||||||
|
|
||||||
|
#define ISCSI_NAME_MAX_SIZE 224
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vfr has a limit on the size, it's 255 bytes.
|
||||||
|
//
|
||||||
|
#define ISCSI_NAME_IFR_MAX_SIZE 126
|
||||||
|
|
||||||
|
#define IP_MIN_SIZE 7
|
||||||
|
#define IP_MAX_SIZE 15
|
||||||
|
#define IP4_STR_MAX_SIZE 16
|
||||||
|
|
||||||
|
#define LUN_MIN_SIZE 1
|
||||||
|
#define LUN_MAX_SIZE 20
|
||||||
|
|
||||||
|
#define ISCSI_CHAP_NONE 0
|
||||||
|
#define ISCSI_CHAP_UNI 1
|
||||||
|
#define ISCSI_CHAP_MUTUAL 2
|
||||||
|
|
||||||
|
#define TARGET_PORT_MIN_NUM 0
|
||||||
|
#define TARGET_PORT_MAX_NUM 65535
|
||||||
|
|
||||||
|
#define DEVICE_ENTRY_LABEL 0x1234
|
||||||
|
|
||||||
|
#define KEY_INITIATOR_NAME 0x01
|
||||||
|
#define KEY_DHCP_ENABLE 0x02
|
||||||
|
#define KEY_LOCAL_IP 0x03
|
||||||
|
#define KEY_SUBNET_MASK 0x04
|
||||||
|
#define KEY_GATE_WAY 0x05
|
||||||
|
#define KEY_TARGET_IP 0x06
|
||||||
|
#define KEY_CHAP_NAME 0x07
|
||||||
|
#define KEY_CHAP_SECRET 0x08
|
||||||
|
#define KEY_REVERSE_CHAP_NAME 0x09
|
||||||
|
#define KEY_REVERSE_CHAP_SECRET 0x0a
|
||||||
|
#define KEY_SAVE_CHANGES 0x0b
|
||||||
|
#define KEY_TARGET_NAME 0x0c
|
||||||
|
#define KEY_BOOT_LUN 0x0d
|
||||||
|
|
||||||
|
#define KEY_DEVICE_ENTRY_BASE 0x1000
|
||||||
|
|
||||||
|
#define ISCSI_LUN_STR_MAX_LEN 21
|
||||||
|
#define ISCSI_CHAP_SECRET_MIN_LEN 13
|
||||||
|
#define ISCSI_CHAP_SECRET_MAX_LEN 17
|
||||||
|
#define ISCSI_CHAP_NAME_MAX_LEN 126
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
CHAR16 InitiatorName[ISCSI_NAME_IFR_MAX_SIZE];
|
||||||
|
|
||||||
|
UINT8 Enabled;
|
||||||
|
|
||||||
|
UINT8 InitiatorInfoFromDhcp;
|
||||||
|
CHAR16 LocalIp[IP4_STR_MAX_SIZE];
|
||||||
|
CHAR16 SubnetMask[IP4_STR_MAX_SIZE];
|
||||||
|
CHAR16 Gateway[IP4_STR_MAX_SIZE];
|
||||||
|
|
||||||
|
CHAR16 TargetName[ISCSI_NAME_IFR_MAX_SIZE];
|
||||||
|
CHAR16 TargetIp[IP4_STR_MAX_SIZE];
|
||||||
|
UINT16 TargetPort;
|
||||||
|
CHAR16 BootLun[ISCSI_LUN_STR_MAX_LEN];
|
||||||
|
UINT8 TargetInfoFromDhcp;
|
||||||
|
|
||||||
|
UINT8 CHAPType;
|
||||||
|
CHAR16 CHAPName[ISCSI_CHAP_NAME_MAX_LEN];
|
||||||
|
CHAR16 CHAPSecret[ISCSI_CHAP_SECRET_MAX_LEN];
|
||||||
|
CHAR16 ReverseCHAPName[ISCSI_CHAP_NAME_MAX_LEN];
|
||||||
|
CHAR16 ReverseCHAPSecret[ISCSI_CHAP_SECRET_MAX_LEN];
|
||||||
|
} ISCSI_CONFIG_IFR_NVDATA;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#endif
|
498
MdeModulePkg/Universal/iScsi/IScsiDhcp.c
Normal file
498
MdeModulePkg/Universal/iScsi/IScsiDhcp.c
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiDhcp.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
iSCSI DHCP related configuration routines.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiDhcpExtractRootPath (
|
||||||
|
IN CHAR8 *RootPath,
|
||||||
|
IN UINT8 Length,
|
||||||
|
IN ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Extract the Root Path option and get the required target information.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
RootPath - The RootPath.
|
||||||
|
Length - Length of the RootPath option payload.
|
||||||
|
ConfigNvData - The iSCSI session configuration data read from nonvolatile device.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - All required information is extracted from the RootPath option.
|
||||||
|
EFI_NOT_FOUND - The RootPath is not an iSCSI RootPath.
|
||||||
|
EFI_OUT_OF_RESOURCES - Failed to allocate memory.
|
||||||
|
EFI_INVALID_PARAMETER - The RootPath is mal-formatted.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT8 IScsiRootPathIdLen;
|
||||||
|
CHAR8 *TmpStr;
|
||||||
|
ISCSI_ROOT_PATH_FIELD Fields[RP_FIELD_IDX_MAX];
|
||||||
|
ISCSI_ROOT_PATH_FIELD *Field;
|
||||||
|
UINT32 FieldIndex;
|
||||||
|
UINT8 Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
|
||||||
|
//
|
||||||
|
IScsiRootPathIdLen = (UINT8) AsciiStrLen (ISCSI_ROOT_PATH_ID);
|
||||||
|
|
||||||
|
if ((Length <= IScsiRootPathIdLen) || (NetCompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Skip the iSCSI RootPath ID "iscsi:".
|
||||||
|
//
|
||||||
|
RootPath += IScsiRootPathIdLen;
|
||||||
|
Length = (UINT8) (Length - IScsiRootPathIdLen);
|
||||||
|
|
||||||
|
TmpStr = (CHAR8 *) NetAllocatePool (Length + 1);
|
||||||
|
if (TmpStr == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (TmpStr, RootPath, Length);
|
||||||
|
TmpStr[Length] = '\0';
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
FieldIndex = 0;
|
||||||
|
NetZeroMem (&Fields[0], sizeof (Fields));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extract the fields in the Root Path option string.
|
||||||
|
//
|
||||||
|
for (FieldIndex = 0; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {
|
||||||
|
if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {
|
||||||
|
Fields[FieldIndex].Str = &TmpStr[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TmpStr[Index] == ISCSI_ROOT_PATH_FIELD_DELIMITER) {
|
||||||
|
if (FieldIndex != RP_FIELD_IDX_TARGETNAME) {
|
||||||
|
TmpStr[Index] = '\0';
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fields[FieldIndex].Str != NULL) {
|
||||||
|
Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FieldIndex != RP_FIELD_IDX_MAX) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||
|
||||||
|
(Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||
|
||||||
|
(Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)
|
||||||
|
) {
|
||||||
|
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the IP address of the target.
|
||||||
|
//
|
||||||
|
Field = &Fields[RP_FIELD_IDX_SERVERNAME];
|
||||||
|
Status = IScsiAsciiStrToIp (Field->Str, &ConfigNvData->TargetIp);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Check the protocol type.
|
||||||
|
//
|
||||||
|
Field = &Fields[RP_FIELD_IDX_PROTOCOL];
|
||||||
|
if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the port of the iSCSI target.
|
||||||
|
//
|
||||||
|
Field = &Fields[RP_FIELD_IDX_PORT];
|
||||||
|
if (Field->Str != NULL) {
|
||||||
|
ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);
|
||||||
|
} else {
|
||||||
|
ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the LUN.
|
||||||
|
//
|
||||||
|
Field = &Fields[RP_FIELD_IDX_LUN];
|
||||||
|
if (Field->Str != NULL) {
|
||||||
|
Status = IScsiAsciiStrToLun (Field->Str, ConfigNvData->BootLun);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NetZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the target iSCSI Name.
|
||||||
|
//
|
||||||
|
Field = &Fields[RP_FIELD_IDX_TARGETNAME];
|
||||||
|
|
||||||
|
if (AsciiStrLen (Field->Str) > ISCSI_NAME_MAX_SIZE - 1) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Validate the iSCSI name.
|
||||||
|
//
|
||||||
|
Status = IScsiNormalizeName (Field->Str, AsciiStrLen (Field->Str));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsciiStrCpy (ConfigNvData->TargetName, Field->Str);
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
|
||||||
|
NetFreePool (TmpStr);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiDhcpSelectOffer (
|
||||||
|
IN EFI_DHCP4_PROTOCOL * This,
|
||||||
|
IN VOID *Context,
|
||||||
|
IN EFI_DHCP4_STATE CurrentState,
|
||||||
|
IN EFI_DHCP4_EVENT Dhcp4Event,
|
||||||
|
IN EFI_DHCP4_PACKET * Packet, OPTIONAL
|
||||||
|
OUT EFI_DHCP4_PACKET **NewPacket OPTIONAL
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
The callback function registerd to the DHCP4 instance which is used to select
|
||||||
|
the qualified DHCP OFFER.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - The DHCP4 protocol.
|
||||||
|
Context - The context set when configuring the DHCP4 protocol.
|
||||||
|
CurrentState - The current state of the DHCP4 protocol.
|
||||||
|
Dhcp4Event - The event occurs in the current state.
|
||||||
|
Packet - The DHCP packet that is to be sent or already received.
|
||||||
|
NewPackt - The packet used to replace the above Packet.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_NOT_READY - The DHCP OFFER packet doesn't match our requirements.
|
||||||
|
EFI_SUCCESS - Either the DHCP OFFER is qualified or we're not intereseted
|
||||||
|
in the Dhcp4Event.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 OptionCount;
|
||||||
|
EFI_DHCP4_PACKET_OPTION **OptionList;
|
||||||
|
UINT32 Index;
|
||||||
|
|
||||||
|
if ((Dhcp4Event != Dhcp4RcvdOffer) && (Dhcp4Event != Dhcp4SelectOffer)) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionCount = 0;
|
||||||
|
|
||||||
|
Status = This->Parse (This, Packet, &OptionCount, NULL);
|
||||||
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionList = NetAllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
|
||||||
|
if (OptionList == NULL) {
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = This->Parse (This, Packet, &OptionCount, OptionList);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
NetFreePool (OptionList);
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < OptionCount; Index++) {
|
||||||
|
if (OptionList[Index]->OpCode != DHCP4_TAG_ROOT_PATH) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = IScsiDhcpExtractRootPath (
|
||||||
|
(CHAR8 *) &OptionList[Index]->Data[0],
|
||||||
|
OptionList[Index]->Length,
|
||||||
|
(ISCSI_SESSION_CONFIG_NVDATA *) Context
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Index == OptionCount)) {
|
||||||
|
Status = EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetFreePool (OptionList);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiParseDhcpAck (
|
||||||
|
IN EFI_DHCP4_PROTOCOL *Dhcp4,
|
||||||
|
IN ISCSI_SESSION_CONFIG_DATA *ConfigData
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Parse the DHCP ACK to get the address configuration and DNS information.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Dhcp4 - The DHCP4 protocol.
|
||||||
|
ConfigData - The session configuration data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The DNS information is got from the DHCP ACK.
|
||||||
|
EFI_NO_MAPPING - DHCP failed to acquire address and other information.
|
||||||
|
EFI_INVALID_PARAMETER - The DHCP ACK's DNS option is mal-formatted.
|
||||||
|
EFI_DEVICE_ERROR - Some unexpected error happened.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DHCP4_MODE_DATA Dhcp4ModeData;
|
||||||
|
UINT32 OptionCount;
|
||||||
|
EFI_DHCP4_PACKET_OPTION **OptionList;
|
||||||
|
UINT32 Index;
|
||||||
|
|
||||||
|
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dhcp4ModeData.State != Dhcp4Bound) {
|
||||||
|
return EFI_NO_MAPPING;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (&ConfigData->NvData.LocalIp, &Dhcp4ModeData.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
NetCopyMem (&ConfigData->NvData.SubnetMask, &Dhcp4ModeData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
NetCopyMem (&ConfigData->NvData.Gateway, &Dhcp4ModeData.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
OptionCount = 0;
|
||||||
|
OptionList = NULL;
|
||||||
|
|
||||||
|
Status = Dhcp4->Parse (Dhcp4, Dhcp4ModeData.ReplyPacket, &OptionCount, OptionList);
|
||||||
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionList = NetAllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
|
||||||
|
if (OptionList == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Dhcp4->Parse (Dhcp4, Dhcp4ModeData.ReplyPacket, &OptionCount, OptionList);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
NetFreePool (OptionList);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; Index < OptionCount; Index++) {
|
||||||
|
//
|
||||||
|
// Get DNS server addresses and DHCP server address from this offer.
|
||||||
|
//
|
||||||
|
if (OptionList[Index]->OpCode == DHCP4_TAG_DNS) {
|
||||||
|
|
||||||
|
if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Primary DNS server address.
|
||||||
|
//
|
||||||
|
NetCopyMem (&ConfigData->PrimaryDns, &OptionList[Index]->Data[0], sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
if (OptionList[Index]->Length > 4) {
|
||||||
|
//
|
||||||
|
// Secondary DNS server address
|
||||||
|
//
|
||||||
|
NetCopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[4], sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
}
|
||||||
|
} else if (OptionList[Index]->OpCode == DHCP4_TAG_SERVER_ID) {
|
||||||
|
if (OptionList[Index]->Length != 4) {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[0], sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetFreePool (OptionList);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiDoDhcp (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN ISCSI_SESSION_CONFIG_DATA *ConfigData
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Parse the DHCP ACK to get the address configuration and DNS information.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Image - The handle of the driver image.
|
||||||
|
Controller - The handle of the controller;
|
||||||
|
ConfigData - The session configuration data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The DNS information is got from the DHCP ACK.
|
||||||
|
EFI_NO_MAPPING - DHCP failed to acquire address and other information.
|
||||||
|
EFI_INVALID_PARAMETER - The DHCP ACK's DNS option is mal-formatted.
|
||||||
|
EFI_DEVICE_ERROR - Some unexpected error happened.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_HANDLE Dhcp4Handle;
|
||||||
|
EFI_DHCP4_PROTOCOL *Dhcp4;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DHCP4_PACKET_OPTION *ParaList;
|
||||||
|
EFI_DHCP4_CONFIG_DATA Dhcp4ConfigData;
|
||||||
|
|
||||||
|
Dhcp4Handle = NULL;
|
||||||
|
Dhcp4 = NULL;
|
||||||
|
ParaList = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a DHCP4 child instance and get the protocol.
|
||||||
|
//
|
||||||
|
Status = NetLibCreateServiceChild (
|
||||||
|
Controller,
|
||||||
|
Image,
|
||||||
|
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||||
|
&Dhcp4Handle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Dhcp4Handle,
|
||||||
|
&gEfiDhcp4ProtocolGuid,
|
||||||
|
(VOID **)&Dhcp4,
|
||||||
|
Image,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParaList = NetAllocatePool (sizeof (EFI_DHCP4_PACKET_OPTION) + 3);
|
||||||
|
if (ParaList == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Ask the server to reply with Netmask, Router, DNS and RootPath options.
|
||||||
|
//
|
||||||
|
ParaList->OpCode = DHCP4_TAG_PARA_LIST;
|
||||||
|
ParaList->Length = ConfigData->NvData.TargetInfoFromDhcp ? 4 : 3;
|
||||||
|
ParaList->Data[0] = DHCP4_TAG_NETMASK;
|
||||||
|
ParaList->Data[1] = DHCP4_TAG_ROUTER;
|
||||||
|
ParaList->Data[2] = DHCP4_TAG_DNS;
|
||||||
|
ParaList->Data[3] = DHCP4_TAG_ROOT_PATH;
|
||||||
|
|
||||||
|
NetZeroMem (&Dhcp4ConfigData, sizeof (EFI_DHCP4_CONFIG_DATA));
|
||||||
|
Dhcp4ConfigData.OptionCount = 1;
|
||||||
|
Dhcp4ConfigData.OptionList = &ParaList;
|
||||||
|
|
||||||
|
if (ConfigData->NvData.TargetInfoFromDhcp) {
|
||||||
|
//
|
||||||
|
// Use callback to select an offer which contains target information.
|
||||||
|
//
|
||||||
|
Dhcp4ConfigData.Dhcp4Callback = IScsiDhcpSelectOffer;
|
||||||
|
Dhcp4ConfigData.CallbackContext = &ConfigData->NvData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Dhcp4->Configure (Dhcp4, &Dhcp4ConfigData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = Dhcp4->Start (Dhcp4, NULL);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Parse the ACK to get required information.
|
||||||
|
//
|
||||||
|
Status = IScsiParseDhcpAck (Dhcp4, ConfigData);
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
|
||||||
|
if (ParaList != NULL) {
|
||||||
|
NetFreePool (ParaList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dhcp4 != NULL) {
|
||||||
|
Dhcp4->Stop (Dhcp4);
|
||||||
|
Dhcp4->Configure (Dhcp4, NULL);
|
||||||
|
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Dhcp4Handle,
|
||||||
|
&gEfiDhcp4ProtocolGuid,
|
||||||
|
Image,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetLibDestroyServiceChild (
|
||||||
|
Controller,
|
||||||
|
Image,
|
||||||
|
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||||
|
Dhcp4Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
57
MdeModulePkg/Universal/iScsi/IScsiDhcp.h
Normal file
57
MdeModulePkg/Universal/iScsi/IScsiDhcp.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiDhcp.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_DHCP_H_
|
||||||
|
#define _ISCSI_DHCP_H_
|
||||||
|
|
||||||
|
//#include "Tiano.h"
|
||||||
|
//#include EFI_PROTOCOL_CONSUMER (Dhcp4)
|
||||||
|
#include "protocol\Dhcp4.h"
|
||||||
|
|
||||||
|
#define DHCP4_TAG_PARA_LIST 55
|
||||||
|
#define DHCP4_TAG_NETMASK 1
|
||||||
|
#define DHCP4_TAG_ROUTER 3
|
||||||
|
#define DHCP4_TAG_DNS 6
|
||||||
|
#define DHCP4_TAG_SERVER_ID 54
|
||||||
|
#define DHCP4_TAG_ROOT_PATH 17
|
||||||
|
#define ISCSI_ROOT_PATH_ID "iscsi:"
|
||||||
|
#define ISCSI_ROOT_PATH_FIELD_DELIMITER ':'
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RP_FIELD_IDX_SERVERNAME = 0,
|
||||||
|
RP_FIELD_IDX_PROTOCOL,
|
||||||
|
RP_FIELD_IDX_PORT,
|
||||||
|
RP_FIELD_IDX_LUN,
|
||||||
|
RP_FIELD_IDX_TARGETNAME,
|
||||||
|
RP_FIELD_IDX_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _ISCSI_ROOT_PATH_FIELD {
|
||||||
|
CHAR8 *Str;
|
||||||
|
UINT8 Len;
|
||||||
|
} ISCSI_ROOT_PATH_FIELD;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiDoDhcp (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN ISCSI_SESSION_CONFIG_DATA *ConfigData
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
462
MdeModulePkg/Universal/iScsi/IScsiDriver.c
Normal file
462
MdeModulePkg/Universal/iScsi/IScsiDriver.c
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiDriver.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
|
||||||
|
IScsiDriverBindingSupported,
|
||||||
|
IScsiDriverBindingStart,
|
||||||
|
IScsiDriverBindingStop,
|
||||||
|
0xa,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
EFI_GUID mIScsiPrivateGuid = ISCSI_PRIVATE_GUID;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingSupported (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Test to see if iSCSI driver supports the given controller.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
ControllerHandle - Handle of controller to test.
|
||||||
|
RemainingDevicePath - Optional parameter use to pick a specific child device to start.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCES - This driver supports the controller.
|
||||||
|
EFI_ALREADY_STARTED - This driver is already running on this device.
|
||||||
|
EFI_UNSUPPORTED - This driver doesn't support the controller.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&mIScsiPrivateGuid,
|
||||||
|
NULL,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
return EFI_ALREADY_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentDevicePath = RemainingDevicePath;
|
||||||
|
if (CurrentDevicePath != NULL) {
|
||||||
|
while (!IsDevicePathEnd (CurrentDevicePath)) {
|
||||||
|
if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingStart (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Start to manage the controller.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
ControllerHandle - Handle of the controller.
|
||||||
|
RemainingDevicePath - Optional parameter use to pick a specific child device to start.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCES - This driver supports this device.
|
||||||
|
EFI_ALREADY_STARTED - This driver is already running on this device.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to add a port configuration page for this controller.
|
||||||
|
//
|
||||||
|
IScsiConfigUpdateForm (This->DriverBindingHandle, ControllerHandle, TRUE);
|
||||||
|
|
||||||
|
Private = IScsiCreateDriverData (This->DriverBindingHandle, ControllerHandle);
|
||||||
|
if (Private == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the iSCSI configuration data of this controller.
|
||||||
|
//
|
||||||
|
Status = IScsiGetConfigData (Private);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Try to login and create an iSCSI session according to the configuration.
|
||||||
|
//
|
||||||
|
Status = IScsiSessionLogin (Private);
|
||||||
|
if (Status == EFI_MEDIA_CHANGED) {
|
||||||
|
//
|
||||||
|
// The specified target is not available and the redirection information is
|
||||||
|
// got, login the session again with the updated target address.
|
||||||
|
//
|
||||||
|
Status = IScsiSessionLogin (Private);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Duplicate the Session's tcp connection device path. The source port field
|
||||||
|
// will be set to zero as one iSCSI session is comprised of several iSCSI
|
||||||
|
// connections.
|
||||||
|
//
|
||||||
|
Private->DevicePath = IScsiGetTcpConnDevicePath (Private);
|
||||||
|
if (Private->DevicePath == NULL) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Install the updated device path onto the ExtScsiPassThruHandle.
|
||||||
|
//
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&Private->ExtScsiPassThruHandle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
Private->DevicePath
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Install the iSCSI private stuff as a flag to indicate this controller
|
||||||
|
// is already controlled by iSCSI driver.
|
||||||
|
//
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&ControllerHandle,
|
||||||
|
&mIScsiPrivateGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
&Private->IScsiIdentifier
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Update/Publish the iSCSI Boot Firmware Table.
|
||||||
|
//
|
||||||
|
IScsiPublishIbft ();
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
ON_ERROR:
|
||||||
|
|
||||||
|
IScsiSessionAbort (&Private->Session);
|
||||||
|
IScsiCleanDriverData (Private);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingStop (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN UINTN NumberOfChildren,
|
||||||
|
IN EFI_HANDLE *ChildHandleBuffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Release the control of this controller and remove the iSCSI functions.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
ControllerHandle - Handle of controller to stop.
|
||||||
|
NumberOfChildren - Not used.
|
||||||
|
ChildHandleBuffer - Not used.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCES - This driver supports this device.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_HANDLE IScsiController;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;
|
||||||
|
ISCSI_CONNECTION *Conn;
|
||||||
|
|
||||||
|
if (NumberOfChildren != 0) {
|
||||||
|
//
|
||||||
|
// We should have only one child.
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ChildHandleBuffer[0],
|
||||||
|
&gEfiExtScsiPassThruProtocolGuid,
|
||||||
|
(VOID **) &PassThru,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);
|
||||||
|
Conn = NET_LIST_HEAD (&Private->Session.Conns, ISCSI_CONNECTION, Link);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Previously the TCP4 protocol is opened BY_CHILD_CONTROLLER. Just close
|
||||||
|
// the protocol here but not uninstall the device path protocol and
|
||||||
|
// EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Conn->Tcp4Io.Handle,
|
||||||
|
&gEfiTcp4ProtocolGuid,
|
||||||
|
Private->Image,
|
||||||
|
Private->ExtScsiPassThruHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the handle of the controller we are controling.
|
||||||
|
//
|
||||||
|
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
IScsiController,
|
||||||
|
&mIScsiPrivateGuid,
|
||||||
|
(VOID **)&IScsiIdentifier,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uninstall the private protocol.
|
||||||
|
//
|
||||||
|
gBS->UninstallProtocolInterface (
|
||||||
|
IScsiController,
|
||||||
|
&mIScsiPrivateGuid,
|
||||||
|
&Private->IScsiIdentifier
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the iSCSI Boot Firware Table.
|
||||||
|
//
|
||||||
|
IScsiPublishIbft ();
|
||||||
|
|
||||||
|
IScsiSessionAbort (&Private->Session);
|
||||||
|
IScsiCleanDriverData (Private);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
EfiIScsiUnload (
|
||||||
|
IN EFI_HANDLE ImageHandle
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Unload the iSCSI driver.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
ImageHandle - The handle of the driver image.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The driver is unloaded.
|
||||||
|
EFI_DEVICE_ERROR - Some unexpected error happened.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN DeviceHandleCount;
|
||||||
|
EFI_HANDLE *DeviceHandleBuffer;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to disonnect the driver from the devices it's controlling.
|
||||||
|
//
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
AllHandles,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&DeviceHandleCount,
|
||||||
|
&DeviceHandleBuffer
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
for (Index = 0; Index < DeviceHandleCount; Index++) {
|
||||||
|
Status = gBS->DisconnectController (
|
||||||
|
DeviceHandleBuffer[Index],
|
||||||
|
ImageHandle,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeviceHandleBuffer != NULL) {
|
||||||
|
NetFreePool (DeviceHandleBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Unload the iSCSI configuration form.
|
||||||
|
//
|
||||||
|
IScsiConfigFormUnload (gIScsiDriverBinding.DriverBindingHandle);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uninstall the protocols installed by iSCSI driver.
|
||||||
|
//
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid,
|
||||||
|
&gIScsiDriverBinding,
|
||||||
|
&gEfiComponentName2ProtocolGuid,
|
||||||
|
&gIScsiComponentName2,
|
||||||
|
&gEfiComponentNameProtocolGuid,
|
||||||
|
&gIScsiComponentName,
|
||||||
|
&gEfiIScsiInitiatorNameProtocolGuid,
|
||||||
|
&gIScsiInitiatorName,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverEntryPoint (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initialize the global variables publish the driver binding protocol.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
ImageHandle - The handle of the driver image.
|
||||||
|
SystemTable - The EFI system table.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The protocols are installed.
|
||||||
|
EFI_DEVICE_ERROR - Some unexpected error happened.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
//EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the EFI Driver Library
|
||||||
|
//
|
||||||
|
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||||
|
ImageHandle,
|
||||||
|
SystemTable,
|
||||||
|
&gIScsiDriverBinding,
|
||||||
|
ImageHandle,
|
||||||
|
&gIScsiComponentName,
|
||||||
|
&gIScsiComponentName2
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&ImageHandle,
|
||||||
|
&gEfiIScsiInitiatorNameProtocolGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
&gIScsiInitiatorName
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid,
|
||||||
|
&gIScsiDriverBinding,
|
||||||
|
&gEfiComponentName2ProtocolGuid,
|
||||||
|
&gIScsiComponentName2,
|
||||||
|
&gEfiComponentNameProtocolGuid,
|
||||||
|
&gIScsiComponentName,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize the configuration form of iSCSI.
|
||||||
|
//
|
||||||
|
IScsiConfigFormInit (gIScsiDriverBinding.DriverBindingHandle);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
123
MdeModulePkg/Universal/iScsi/IScsiDriver.h
Normal file
123
MdeModulePkg/Universal/iScsi/IScsiDriver.h
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiDriver.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_DRIVER_H_
|
||||||
|
#define _ISCSI_DRIVER_H_
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
#include <Protocol/DevicePath.h>
|
||||||
|
#include <Protocol/LoadedImage.h>
|
||||||
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DevicePathLib.h>
|
||||||
|
#include <protocol/DriverBinding.h>
|
||||||
|
#include <protocol/ScsiPassThruExt.h>
|
||||||
|
#include <protocol/IScsiInitiatorName.h>
|
||||||
|
#include <protocol/Ip4Config.h>
|
||||||
|
#include <protocol/ComponentName.h>
|
||||||
|
#include <protocol/ComponentName2.h>
|
||||||
|
|
||||||
|
#define ISCSI_PRIVATE_GUID \
|
||||||
|
{ \
|
||||||
|
0xfa3cde4c, 0x87c2, 0x427d, 0xae, 0xde, 0x7d, 0xd0, 0x96, 0xc8, 0x8c, 0x58 \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ISCSI_INITIATOR_NAME_VAR_NAME L"I_NAME"
|
||||||
|
|
||||||
|
extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2;
|
||||||
|
extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName;
|
||||||
|
|
||||||
|
extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName;
|
||||||
|
|
||||||
|
extern EFI_GUID mIScsiPrivateGuid;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_PRIVATE_PROTOCOL {
|
||||||
|
UINT32 Reserved;
|
||||||
|
} ISCSI_PRIVATE_PROTOCOL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// EFI Driver Binding Protocol for iSCSI driver.
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingSupported (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingStart (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiDriverBindingStop (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN UINTN NumberOfChildren,
|
||||||
|
IN EFI_HANDLE *ChildHandleBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// EFI Component Name Protocol for iSCSI driver.
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiComponentNameGetDriverName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **DriverName
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiComponentNameGetControllerName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||||
|
IN CHAR8 *Language,
|
||||||
|
OUT CHAR16 **ControllerName
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// EFI iSCSI Initiator Name Protocol for iSCSI driver.
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiGetInitiatorName (
|
||||||
|
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
|
||||||
|
IN OUT UINTN *BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiSetInitiatorName (
|
||||||
|
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
|
||||||
|
IN OUT UINTN *BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
401
MdeModulePkg/Universal/iScsi/IScsiExtScsiPassThru.c
Normal file
401
MdeModulePkg/Universal/iScsi/IScsiExtScsiPassThru.c
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiExtScsiPassThru.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruFunction (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN UINT8 *Target,
|
||||||
|
IN UINT64 Lun,
|
||||||
|
IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
|
||||||
|
IN EFI_EVENT Event OPTIONAL
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This function sends out the SCSI command via iSCSI transport layer and returned
|
||||||
|
back the data received from the iSCSI target.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
|
||||||
|
Target - The Target ID of device to send the SCSI Request Packet.
|
||||||
|
Lun - The LUN of the device to send the SCSI Request Packet.
|
||||||
|
Packet - The SCSI Request Packet to send to the device.
|
||||||
|
Event - The event used in non-blocking mode, it should be always NULL.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
if (Target[0] != 0) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Packet == NULL) || (Packet->Cdb == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IScsiExecuteScsiCommand (This, Target, Lun, Packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruGetNextTargetLun (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN OUT UINT8 **Target,
|
||||||
|
IN OUT UINT64 *Lun
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance..
|
||||||
|
Target - On input, a pointer to the Target ID of a SCSI device present on the
|
||||||
|
SCSI channel. On output, a pointer to the Target ID of the next SCSI
|
||||||
|
device present on a SCSI channel. An input value of 0xFFFFFFFF
|
||||||
|
retrieves the Target ID of the first SCSI device present on a SCSI channel.
|
||||||
|
Lun - On input, a pointer to the LUN of a SCSI device present on the SCSI
|
||||||
|
channel. On output, a pointer to the LUN of the next SCSI device present on
|
||||||
|
a SCSI channel.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The Target ID and Lun of the next SCSI device
|
||||||
|
on the SCSI channel was returned in Target and Lun.
|
||||||
|
EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.
|
||||||
|
EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
|
||||||
|
returned on a previous call to GetNextDevice().
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
|
||||||
|
UINT8 TargetId[TARGET_MAX_BYTES];
|
||||||
|
|
||||||
|
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
|
||||||
|
ConfigNvData = &Private->Session.ConfigData.NvData;
|
||||||
|
|
||||||
|
if ((*Target)[0] == 0 && (NetCompareMem (Lun, ConfigNvData->BootLun, sizeof (UINT64)) == 0)) {
|
||||||
|
//
|
||||||
|
// Only one <Target, Lun> pair per iSCSI Driver instance.
|
||||||
|
//
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetSetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
|
||||||
|
if (NetCompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {
|
||||||
|
(*Target)[0] = 0;
|
||||||
|
NetCopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruBuildDevicePath (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN UINT8 *Target,
|
||||||
|
IN UINT64 Lun,
|
||||||
|
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Allocate and build a device path node for a SCSI device on a SCSI channel.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
Target - The Target ID of the SCSI device for which
|
||||||
|
a device path node is to be allocated and built.
|
||||||
|
Lun - The LUN of the SCSI device for which a device
|
||||||
|
path node is to be allocated and built.
|
||||||
|
DevicePath - A pointer to a single device path node that
|
||||||
|
describes the SCSI device specified by
|
||||||
|
Target and Lun. This function is responsible
|
||||||
|
for allocating the buffer DevicePath with the boot
|
||||||
|
service AllocatePool(). It is the caller's
|
||||||
|
responsibility to free DevicePath when the caller
|
||||||
|
is finished with DevicePath.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The device path node that describes the SCSI device
|
||||||
|
specified by Target and Lun was allocated and
|
||||||
|
returned in DevicePath.
|
||||||
|
EFI_NOT_FOUND - The SCSI devices specified by Target and Lun does
|
||||||
|
not exist on the SCSI channel.
|
||||||
|
EFI_INVALID_PARAMETER - DevicePath is NULL.
|
||||||
|
EFI_OUT_OF_RESOURCES - There are not enough resources to allocate
|
||||||
|
DevicePath.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
|
||||||
|
ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
|
||||||
|
EFI_DEV_PATH *Node;
|
||||||
|
UINTN DevPathNodeLen;
|
||||||
|
|
||||||
|
if ((DevicePath == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Target[0] != 0) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
|
||||||
|
Session = &Private->Session;
|
||||||
|
ConfigNvData = &Session->ConfigData.NvData;
|
||||||
|
AuthConfig = &Session->AuthData.AuthConfig;
|
||||||
|
|
||||||
|
if (NetCompareMem (&Lun, ConfigNvData->BootLun, sizeof (UINT64)) != 0) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
DevPathNodeLen = sizeof (ISCSI_DEVICE_PATH) + AsciiStrLen (ConfigNvData->TargetName) + 1;
|
||||||
|
Node = NetAllocatePool (DevPathNodeLen);
|
||||||
|
if (Node == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node->DevPath.Type = MESSAGING_DEVICE_PATH;
|
||||||
|
Node->DevPath.SubType = MSG_ISCSI_DP;
|
||||||
|
SetDevicePathNodeLength (&Node->DevPath, DevPathNodeLen);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 0 for TCP, others are reserved.
|
||||||
|
//
|
||||||
|
Node->Iscsi.NetworkProtocol = 0;
|
||||||
|
|
||||||
|
Node->Iscsi.LoginOption = 0;
|
||||||
|
switch (AuthConfig->CHAPType) {
|
||||||
|
case ISCSI_CHAP_NONE:
|
||||||
|
Node->Iscsi.LoginOption |= 0x0800;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ISCSI_CHAP_UNI:
|
||||||
|
Node->Iscsi.LoginOption |= 0x1000;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (&Node->Iscsi.Lun, ConfigNvData->BootLun, sizeof (UINT64));
|
||||||
|
Node->Iscsi.TargetPortalGroupTag = Session->TargetPortalGroupTag;
|
||||||
|
AsciiStrCpy ((CHAR8 *) Node + sizeof (ISCSI_DEVICE_PATH), ConfigNvData->TargetName);
|
||||||
|
|
||||||
|
*DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruGetTargetLun (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||||
|
OUT UINT8 **Target,
|
||||||
|
OUT UINT64 *Lun
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Translate a device path node to a Target ID and LUN.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
DevicePath - A pointer to the device path node that
|
||||||
|
describes a SCSI device on the SCSI channel.
|
||||||
|
Target - A pointer to the Target ID of a SCSI device
|
||||||
|
on the SCSI channel.
|
||||||
|
Lun - A pointer to the LUN of a SCSI device on
|
||||||
|
the SCSI channel.
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - DevicePath was successfully translated to a
|
||||||
|
Target ID and LUN, and they were returned
|
||||||
|
in Target and Lun.
|
||||||
|
EFI_INVALID_PARAMETER - DevicePath/Target/Lun is NULL.
|
||||||
|
EFI_UNSUPPORTED - This driver does not support the device path
|
||||||
|
node type in DevicePath.
|
||||||
|
EFI_NOT_FOUND - A valid translation from DevicePath to a
|
||||||
|
Target ID and LUN does not exist.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;
|
||||||
|
|
||||||
|
if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
|
||||||
|
(DevicePath->SubType != MSG_ISCSI_DP) ||
|
||||||
|
(DevicePathNodeLength (DevicePath) <= sizeof (ISCSI_DEVICE_PATH))
|
||||||
|
) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
|
||||||
|
ConfigNvData = &Private->Session.ConfigData.NvData;
|
||||||
|
|
||||||
|
NetZeroMem (*Target, TARGET_MAX_BYTES);
|
||||||
|
|
||||||
|
if (AsciiStrCmp (ConfigNvData->TargetName, (CHAR8 *) DevicePath + sizeof (ISCSI_DEVICE_PATH)) != 0) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruResetChannel (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Resets a SCSI channel.This operation resets all the SCSI devices connected to
|
||||||
|
the SCSI channel.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_UNSUPPORTED - It's not supported.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruResetTargetLun (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN UINT8 *Target,
|
||||||
|
IN UINT64 Lun
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Resets a SCSI device that is connected to a SCSI channel.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
Target - The Target ID of the SCSI device to reset.
|
||||||
|
Lun - The LUN of the SCSI device to reset.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_UNSUPPORTED - It's not supported.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiExtScsiPassThruGetNextTarget (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
|
||||||
|
IN OUT UINT8 **Target
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
This - Protocol instance pointer.
|
||||||
|
Target - On input, a pointer to the Target ID of a SCSI
|
||||||
|
device present on the SCSI channel. On output,
|
||||||
|
a pointer to the Target ID of the next SCSI device
|
||||||
|
present on a SCSI channel. An input value of
|
||||||
|
0xFFFFFFFF retrieves the Target ID of the first
|
||||||
|
SCSI device present on a SCSI channel.
|
||||||
|
Lun - On input, a pointer to the LUN of a SCSI device
|
||||||
|
present on the SCSI channel. On output, a pointer
|
||||||
|
to the LUN of the next SCSI device present on
|
||||||
|
a SCSI channel.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The Target ID and Lun of the next SCSI device
|
||||||
|
on the SCSI channel was returned in Target and Lun.
|
||||||
|
EFI_NOT_FOUND - There are no more SCSI devices on this SCSI channel.
|
||||||
|
EFI_INVALID_PARAMETER - Target is not 0xFFFFFFFF,and Target and Lun were not
|
||||||
|
returned on a previous call to GetNextDevice().
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT8 TargetId[TARGET_MAX_BYTES];
|
||||||
|
|
||||||
|
NetSetMem (TargetId, TARGET_MAX_BYTES, 0xFF);
|
||||||
|
|
||||||
|
if (NetCompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {
|
||||||
|
(*Target)[0] = 0;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
} else if ((*Target)[0] == 0) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate = {
|
||||||
|
NULL,
|
||||||
|
IScsiExtScsiPassThruFunction,
|
||||||
|
IScsiExtScsiPassThruGetNextTargetLun,
|
||||||
|
IScsiExtScsiPassThruBuildDevicePath,
|
||||||
|
IScsiExtScsiPassThruGetTargetLun,
|
||||||
|
IScsiExtScsiPassThruResetChannel,
|
||||||
|
IScsiExtScsiPassThruResetTargetLun,
|
||||||
|
IScsiExtScsiPassThruGetNextTarget
|
||||||
|
};
|
27
MdeModulePkg/Universal/iScsi/IScsiExtScsiPassThru.h
Normal file
27
MdeModulePkg/Universal/iScsi/IScsiExtScsiPassThru.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiExtScsiPassThru.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_EXT_SCSI_PASS_THRU_H_
|
||||||
|
#define _ISCSI_EXT_SCSI_PASS_THRU_H_
|
||||||
|
|
||||||
|
#include <protocol/ScsiPassThruExt.h>
|
||||||
|
|
||||||
|
extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate;
|
||||||
|
|
||||||
|
#endif
|
645
MdeModulePkg/Universal/iScsi/IScsiIbft.c
Normal file
645
MdeModulePkg/Universal/iScsi/IScsiIbft.c
Normal file
@ -0,0 +1,645 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiIbft.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Implementation for iSCSI Boot Firmware Table publication.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiInitIbfTableHeader (
|
||||||
|
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initialize the header of the iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Header - The header of the iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
NetZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));
|
||||||
|
|
||||||
|
Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;
|
||||||
|
Header->Length = IBFT_HEAP_OFFSET;
|
||||||
|
Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;
|
||||||
|
Header->Checksum = 0;
|
||||||
|
|
||||||
|
Header->OemId[0] = 'I';
|
||||||
|
Header->OemId[1] = 'N';
|
||||||
|
Header->OemId[2] = 'T';
|
||||||
|
Header->OemId[3] = 'E';
|
||||||
|
Header->OemId[4] = 'L';
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiInitControlSection (
|
||||||
|
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
|
||||||
|
IN UINTN HandleCount
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initialize the control section of the iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Table - The ACPI table.
|
||||||
|
HandleCount - The number of the handles associated with iSCSI sessions, it's
|
||||||
|
equal to the number of iSCSI sessions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
|
||||||
|
UINTN NumOffset;
|
||||||
|
|
||||||
|
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
|
||||||
|
|
||||||
|
NetZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));
|
||||||
|
|
||||||
|
Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;
|
||||||
|
Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;
|
||||||
|
Control->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Each session occupies two offsets, one for the NIC section,
|
||||||
|
// the other for the Target section.
|
||||||
|
//
|
||||||
|
NumOffset = 2 * HandleCount;
|
||||||
|
if (NumOffset > 4) {
|
||||||
|
//
|
||||||
|
// Need expand the control section if more than 2 NIC/Target sections
|
||||||
|
// exist.
|
||||||
|
//
|
||||||
|
Control->Header.Length += (UINT16) (NumOffset - 4) * sizeof (UINT16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiAddHeapItem (
|
||||||
|
IN OUT UINT8 **Heap,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN Len
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Add one item into the heap.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Heap - On input, the current address of the heap; On output, the address of
|
||||||
|
the heap after the item is added.
|
||||||
|
Data - The data to add into the heap.
|
||||||
|
Len - Length of the Data in byte.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Add one byte for the NULL delimiter.
|
||||||
|
//
|
||||||
|
*Heap -= Len + 1;
|
||||||
|
|
||||||
|
NetCopyMem (*Heap, Data, Len);
|
||||||
|
*(*Heap + Len) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiFillInitiatorSection (
|
||||||
|
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
|
||||||
|
IN OUT UINT8 **Heap,
|
||||||
|
IN EFI_HANDLE Handle
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Fill the Initiator section of the iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Table - The ACPI table.
|
||||||
|
Heap - The heap.
|
||||||
|
Handle - The handle associated with the iSCSI session.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;
|
||||||
|
ISCSI_DRIVER_DATA *DriverData;
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initiator section immediately follows the control section.
|
||||||
|
//
|
||||||
|
Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));
|
||||||
|
|
||||||
|
Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);
|
||||||
|
|
||||||
|
NetZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));
|
||||||
|
|
||||||
|
Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;
|
||||||
|
Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;
|
||||||
|
Initiator->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);
|
||||||
|
Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the identifier from the handle.
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (Handle, &mIScsiPrivateGuid, &IScsiIdentifier);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
|
||||||
|
Session = &DriverData->Session;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the iSCSI Initiator Name into the heap.
|
||||||
|
//
|
||||||
|
IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1);
|
||||||
|
|
||||||
|
Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1);
|
||||||
|
Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiMapV4ToV6Addr (
|
||||||
|
IN EFI_IPv4_ADDRESS *V4,
|
||||||
|
OUT EFI_IPv6_ADDRESS *V6
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Map the v4 IP address into v6 IP address.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
V4 - The v4 IP address.
|
||||||
|
V6 - The v6 IP address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
NetZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));
|
||||||
|
|
||||||
|
V6->Addr[10] = 0xff;
|
||||||
|
V6->Addr[11] = 0xff;
|
||||||
|
|
||||||
|
for (Index = 0; Index < 4; Index++) {
|
||||||
|
V6->Addr[12 + Index] = V4->Addr[Index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
UINT16
|
||||||
|
IScsiGetNICPciLocation (
|
||||||
|
IN EFI_HANDLE Controller
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Get the NIC's PCI location and return it accroding to the composited
|
||||||
|
format defined in iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Controller - The handle of the controller.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
UINT16 - The composited representation of the NIC PCI location.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
EFI_HANDLE PciIoHandle;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
UINTN Segment;
|
||||||
|
UINTN Bus;
|
||||||
|
UINTN Device;
|
||||||
|
UINTN Function;
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
&DevicePath
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->LocateDevicePath (
|
||||||
|
&gEfiPciIoProtocolGuid,
|
||||||
|
&DevicePath,
|
||||||
|
&PciIoHandle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, &PciIo);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (UINT16) ((Bus << 8) | (Device << 3) | Function);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_MAC_ADDRESS *
|
||||||
|
IScsiGetMacAddress (
|
||||||
|
IN EFI_HANDLE Controller
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Get the MAC address of the controller.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Controller - The handle of the controller.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_MAC_ADDRESS * - The mac address.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&Snp
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
return &Snp->Mode->PermanentAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
IScsiFillNICAndTargetSections (
|
||||||
|
IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
|
||||||
|
IN OUT UINT8 **Heap,
|
||||||
|
IN UINTN HandleCount,
|
||||||
|
IN EFI_HANDLE *Handles
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Fill the NIC and target sections in iSCSI Boot Firmware Table.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Table - The buffer of the ACPI table.
|
||||||
|
Heap - The heap buffer used to store the variable length parameters such as iSCSI name.
|
||||||
|
HandleCount - The number of handles having iSCSI private protocol installed.
|
||||||
|
Handles - The handle buffer.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;
|
||||||
|
ISCSI_DRIVER_DATA *DriverData;
|
||||||
|
ISCSI_SESSION_CONFIG_DATA *SessionConfigData;
|
||||||
|
ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
|
||||||
|
UINT16 *SectionOffset;
|
||||||
|
UINTN Index;
|
||||||
|
UINT16 Length;
|
||||||
|
EFI_MAC_ADDRESS *Mac;
|
||||||
|
ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the offset of the first Nic and Target section.
|
||||||
|
//
|
||||||
|
Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);
|
||||||
|
Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +
|
||||||
|
Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));
|
||||||
|
Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
|
||||||
|
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
|
||||||
|
|
||||||
|
SectionOffset = &Control->NIC0Offset;
|
||||||
|
|
||||||
|
for (Index = 0; Index < HandleCount; Index++) {
|
||||||
|
Status = gBS->HandleProtocol (Handles[Index], &mIScsiPrivateGuid, &IScsiIdentifier);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
|
||||||
|
SessionConfigData = &DriverData->Session.ConfigData;
|
||||||
|
AuthConfig = &DriverData->Session.AuthData.AuthConfig;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the Nic section.
|
||||||
|
//
|
||||||
|
NetZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));
|
||||||
|
|
||||||
|
Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;
|
||||||
|
Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;
|
||||||
|
Nic->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);
|
||||||
|
Nic->Header.Index = (UINT8) Index;
|
||||||
|
Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the subnet mask prefix length.
|
||||||
|
//
|
||||||
|
Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);
|
||||||
|
|
||||||
|
if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {
|
||||||
|
Nic->Origin = IpPrefixOriginDhcp;
|
||||||
|
} else {
|
||||||
|
Nic->Origin = IpPrefixOriginManual;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Map the various v4 addresses into v6 addresses.
|
||||||
|
//
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);
|
||||||
|
|
||||||
|
Mac = IScsiGetMacAddress (DriverData->Controller);
|
||||||
|
NetCopyMem (Nic->Mac, Mac, sizeof (Nic->Mac));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the PCI location of the Nic.
|
||||||
|
//
|
||||||
|
Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller);
|
||||||
|
|
||||||
|
*SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);
|
||||||
|
SectionOffset++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the Target section.
|
||||||
|
//
|
||||||
|
NetZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));
|
||||||
|
|
||||||
|
Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;
|
||||||
|
Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;
|
||||||
|
Target->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);
|
||||||
|
Target->Header.Index = (UINT8) Index;
|
||||||
|
Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;
|
||||||
|
Target->Port = SessionConfigData->NvData.TargetPort;
|
||||||
|
Target->CHAPType = AuthConfig->CHAPType;
|
||||||
|
Target->NicIndex = (UINT8) Index;
|
||||||
|
|
||||||
|
IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);
|
||||||
|
NetCopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.
|
||||||
|
//
|
||||||
|
Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName);
|
||||||
|
IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);
|
||||||
|
|
||||||
|
Target->IScsiNameLength = Length;
|
||||||
|
Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
|
||||||
|
if (Target->CHAPType != ISCSI_CHAP_NONE) {
|
||||||
|
//
|
||||||
|
// CHAP Name
|
||||||
|
//
|
||||||
|
Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);
|
||||||
|
IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);
|
||||||
|
Target->CHAPNameLength = Length;
|
||||||
|
Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
|
||||||
|
//
|
||||||
|
// CHAP Secret
|
||||||
|
//
|
||||||
|
Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);
|
||||||
|
IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);
|
||||||
|
Target->CHAPSecretLength = Length;
|
||||||
|
Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
|
||||||
|
if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {
|
||||||
|
//
|
||||||
|
// Reverse CHAP Name
|
||||||
|
//
|
||||||
|
Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);
|
||||||
|
IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);
|
||||||
|
Target->ReverseCHAPNameLength = Length;
|
||||||
|
Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reverse CHAP Secret
|
||||||
|
//
|
||||||
|
Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);
|
||||||
|
IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);
|
||||||
|
Target->ReverseCHAPSecretLength = Length;
|
||||||
|
Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);
|
||||||
|
SectionOffset++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Advance to the next NIC/Target pair
|
||||||
|
//
|
||||||
|
Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +
|
||||||
|
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));
|
||||||
|
Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +
|
||||||
|
IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiPublishIbft (
|
||||||
|
IN VOID
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
|
||||||
|
session status.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN TableHandle;
|
||||||
|
EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;
|
||||||
|
EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;
|
||||||
|
UINTN HandleCount;
|
||||||
|
EFI_HANDLE *HandleBuffer;
|
||||||
|
UINT8 *Heap;
|
||||||
|
INTN Index;
|
||||||
|
EFI_ACPI_TABLE_VERSION Version;
|
||||||
|
UINT32 Signature;
|
||||||
|
|
||||||
|
Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, &AcpiSupport);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Try to remove the old iSCSI Boot Firmware Table.
|
||||||
|
//
|
||||||
|
for (Index = 0;; Index++) {
|
||||||
|
Status = AcpiSupport->GetAcpiTable (
|
||||||
|
AcpiSupport,
|
||||||
|
Index,
|
||||||
|
&Table,
|
||||||
|
&Version,
|
||||||
|
&TableHandle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature = Table->Signature;
|
||||||
|
NetFreePool (Table);
|
||||||
|
|
||||||
|
if (Signature == EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE) {
|
||||||
|
//
|
||||||
|
// Remove the table.
|
||||||
|
//
|
||||||
|
Status = AcpiSupport->SetAcpiTable (
|
||||||
|
AcpiSupport,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
Version,
|
||||||
|
&TableHandle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get all iSCSI private protocols.
|
||||||
|
//
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
ByProtocol,
|
||||||
|
&mIScsiPrivateGuid,
|
||||||
|
NULL,
|
||||||
|
&HandleCount,
|
||||||
|
&HandleBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Allocate 4k bytes to hold the ACPI table.
|
||||||
|
//
|
||||||
|
Table = NetAllocatePool (IBFT_MAX_SIZE);
|
||||||
|
if (Table == NULL) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Heap = (CHAR8 *) Table + IBFT_HEAP_OFFSET;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill in the various section of the iSCSI Boot Firmware Table.
|
||||||
|
//
|
||||||
|
IScsiInitIbfTableHeader (Table);
|
||||||
|
IScsiInitControlSection (Table, HandleCount);
|
||||||
|
IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);
|
||||||
|
IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);
|
||||||
|
|
||||||
|
NetFreePool (HandleBuffer);
|
||||||
|
|
||||||
|
TableHandle = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install or update the iBFT table.
|
||||||
|
//
|
||||||
|
Status = AcpiSupport->SetAcpiTable (
|
||||||
|
AcpiSupport,
|
||||||
|
Table,
|
||||||
|
TRUE,
|
||||||
|
EFI_ACPI_TABLE_VERSION_3_0,
|
||||||
|
&TableHandle
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
AcpiSupport->PublishTables (AcpiSupport, EFI_ACPI_TABLE_VERSION_3_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetFreePool (Table);
|
||||||
|
}
|
40
MdeModulePkg/Universal/iScsi/IScsiIbft.h
Normal file
40
MdeModulePkg/Universal/iScsi/IScsiIbft.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiIbft.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Some extra definitions for iBFT.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_IBFT_H_
|
||||||
|
#define _ISCSI_IBFT_H_
|
||||||
|
|
||||||
|
#include <industrystandard/IScsiBootFirmwareTable.h>
|
||||||
|
#include <protocol/AcpiSupport.h>
|
||||||
|
#include <protocol/PciIo.h>
|
||||||
|
|
||||||
|
#define IBFT_TABLE_VAR_NAME L"iBFT"
|
||||||
|
#define IBFT_MAX_SIZE 4096
|
||||||
|
#define IBFT_HEAP_OFFSET 2048
|
||||||
|
|
||||||
|
#define IBFT_ROUNDUP(size) NET_ROUNDUP ((size), EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_STRUCTURE_ALIGNMENT)
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiPublishIbft (
|
||||||
|
IN VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
161
MdeModulePkg/Universal/iScsi/IScsiImpl.h
Normal file
161
MdeModulePkg/Universal/iScsi/IScsiImpl.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiImpl.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_IMPL_H_
|
||||||
|
#define _ISCSI_IMPL_H_
|
||||||
|
|
||||||
|
#include <Library/NetLib.h>
|
||||||
|
#include <Library/PrintLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include "IScsiCommon.h"
|
||||||
|
#include "IScsiDriver.h"
|
||||||
|
#include "IScsiConfigNVDataStruc.h"
|
||||||
|
#include "IScsiExtScsiPassThru.h"
|
||||||
|
#include "IScsiProto.h"
|
||||||
|
#include "IScsiCHAP.h"
|
||||||
|
#include "IScsiDhcp.h"
|
||||||
|
#include "IScsiTcp4Io.h"
|
||||||
|
#include "IScsiIbft.h"
|
||||||
|
#include "IScsiMisc.h"
|
||||||
|
#include "IScsiConfig.h"
|
||||||
|
|
||||||
|
#define ISCSI_SESSION_SIGNATURE EFI_SIGNATURE_32 ('I', 'S', 'S', 'N')
|
||||||
|
|
||||||
|
typedef struct _ISCSI_SESSION {
|
||||||
|
UINT32 Signature;
|
||||||
|
|
||||||
|
ISCSI_SESSION_CONFIG_DATA ConfigData;
|
||||||
|
ISCSI_CHAP_AUTH_DATA AuthData;
|
||||||
|
|
||||||
|
CHAR8 InitiatorName[ISCSI_NAME_MAX_SIZE];
|
||||||
|
UINTN InitiatorNameLength;
|
||||||
|
UINT8 State;
|
||||||
|
|
||||||
|
UINT8 ISID[6];
|
||||||
|
UINT16 TSIH;
|
||||||
|
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT16 NextCID;
|
||||||
|
|
||||||
|
NET_LIST_ENTRY Conns;
|
||||||
|
UINT32 NumConns;
|
||||||
|
|
||||||
|
NET_LIST_ENTRY TcbList;
|
||||||
|
|
||||||
|
//
|
||||||
|
// session-wide parameters
|
||||||
|
//
|
||||||
|
UINT16 TargetPortalGroupTag;
|
||||||
|
UINT32 MaxConnections;
|
||||||
|
BOOLEAN InitialR2T;
|
||||||
|
BOOLEAN ImmediateData;
|
||||||
|
UINT32 MaxBurstLength;
|
||||||
|
UINT32 FirstBurstLength;
|
||||||
|
UINT32 DefaultTime2Wait;
|
||||||
|
UINT32 DefaultTime2Retain;
|
||||||
|
UINT16 MaxOutstandingR2T;
|
||||||
|
BOOLEAN DataPDUInOrder;
|
||||||
|
BOOLEAN DataSequenceInOrder;
|
||||||
|
UINT8 ErrorRecoveryLevel;
|
||||||
|
} ISCSI_SESSION;
|
||||||
|
|
||||||
|
#define ISCSI_CONNECTION_SIGNATURE EFI_SIGNATURE_32 ('I', 'S', 'C', 'N')
|
||||||
|
|
||||||
|
typedef struct _ISCSI_CONNECTION {
|
||||||
|
UINT32 Signature;
|
||||||
|
NET_LIST_ENTRY Link;
|
||||||
|
|
||||||
|
EFI_EVENT TimeoutEvent;
|
||||||
|
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
|
||||||
|
UINT8 State;
|
||||||
|
UINT8 CurrentStage;
|
||||||
|
UINT8 NextStage;
|
||||||
|
|
||||||
|
UINT8 CHAPStep;
|
||||||
|
|
||||||
|
BOOLEAN PartialReqSent;
|
||||||
|
BOOLEAN PartialRspRcvd;
|
||||||
|
|
||||||
|
BOOLEAN TransitInitiated;
|
||||||
|
|
||||||
|
UINT16 CID;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
|
||||||
|
//
|
||||||
|
// queues...
|
||||||
|
//
|
||||||
|
NET_BUF_QUEUE RspQue;
|
||||||
|
|
||||||
|
TCP4_IO Tcp4Io;
|
||||||
|
|
||||||
|
//
|
||||||
|
// connection-only parameters
|
||||||
|
//
|
||||||
|
UINT32 MaxRecvDataSegmentLength;
|
||||||
|
ISCSI_DIGEST_TYPE HeaderDigest;
|
||||||
|
ISCSI_DIGEST_TYPE DataDigest;
|
||||||
|
} ISCSI_CONNECTION;
|
||||||
|
|
||||||
|
#define ISCSI_DRIVER_DATA_SIGNATURE EFI_SIGNATURE_32 ('I', 'S', 'D', 'A')
|
||||||
|
|
||||||
|
#define ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU(PassThru) \
|
||||||
|
CR ( \
|
||||||
|
PassThru, \
|
||||||
|
ISCSI_DRIVER_DATA, \
|
||||||
|
IScsiExtScsiPassThru, \
|
||||||
|
ISCSI_DRIVER_DATA_SIGNATURE \
|
||||||
|
)
|
||||||
|
#define ISCSI_DRIVER_DATA_FROM_IDENTIFIER(Identifier) \
|
||||||
|
CR ( \
|
||||||
|
Identifier, \
|
||||||
|
ISCSI_DRIVER_DATA, \
|
||||||
|
IScsiIdentifier, \
|
||||||
|
ISCSI_DRIVER_DATA_SIGNATURE \
|
||||||
|
)
|
||||||
|
#define ISCSI_DRIVER_DATA_FROM_SESSION(s) \
|
||||||
|
CR ( \
|
||||||
|
s, \
|
||||||
|
ISCSI_DRIVER_DATA, \
|
||||||
|
Session, \
|
||||||
|
ISCSI_DRIVER_DATA_SIGNATURE \
|
||||||
|
)
|
||||||
|
|
||||||
|
typedef struct _ISCSI_DRIVER_DATA {
|
||||||
|
UINT32 Signature;
|
||||||
|
EFI_HANDLE Image;
|
||||||
|
EFI_HANDLE Controller;
|
||||||
|
ISCSI_PRIVATE_PROTOCOL IScsiIdentifier;
|
||||||
|
|
||||||
|
EFI_EVENT ExitBootServiceEvent;
|
||||||
|
|
||||||
|
EFI_EXT_SCSI_PASS_THRU_PROTOCOL IScsiExtScsiPassThru;
|
||||||
|
EFI_EXT_SCSI_PASS_THRU_MODE ExtScsiPassThruMode;
|
||||||
|
EFI_HANDLE ExtScsiPassThruHandle;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
|
||||||
|
ISCSI_SESSION Session;
|
||||||
|
} ISCSI_DRIVER_DATA;
|
||||||
|
|
||||||
|
#endif
|
145
MdeModulePkg/Universal/iScsi/IScsiInitiatorName.c
Normal file
145
MdeModulePkg/Universal/iScsi/IScsiInitiatorName.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiInitiatorName.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Implementation for EFI iSCSI Initiator Name Protocol.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName = {
|
||||||
|
IScsiGetInitiatorName,
|
||||||
|
IScsiSetInitiatorName
|
||||||
|
};
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiGetInitiatorName (
|
||||||
|
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
|
||||||
|
IN OUT UINTN *BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Retrieves the current set value of iSCSI Initiator Name.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL instance.
|
||||||
|
BufferSize - Size of the buffer in bytes pointed to by Buffer / Actual size of
|
||||||
|
the variable data buffer.
|
||||||
|
Buffer - Pointer to the buffer for data to be read.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - Data was successfully retrieved into the provided
|
||||||
|
buffer and the BufferSize was sufficient to handle the
|
||||||
|
iSCSI initiator name.
|
||||||
|
EFI_BUFFER_TOO_SMALL - BufferSize is too small for the result. BufferSize will
|
||||||
|
be updated with the size required to complete the request.
|
||||||
|
Buffer will not be affected.
|
||||||
|
EFI_INVALID_PARAMETER - BufferSize is NULL. BufferSize and Buffer will not be
|
||||||
|
affected.
|
||||||
|
EFI_INVALID_PARAMETER - Buffer is NULL. BufferSize and Buffer will not be
|
||||||
|
affected.
|
||||||
|
EFI_DEVICE_ERROR - The iSCSI initiator name could not be retrieved due to
|
||||||
|
a hardware error.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if ((BufferSize == NULL) || (Buffer == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
ISCSI_INITIATOR_NAME_VAR_NAME,
|
||||||
|
&gEfiIScsiInitiatorNameProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
BufferSize,
|
||||||
|
Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
IScsiSetInitiatorName (
|
||||||
|
IN EFI_ISCSI_INITIATOR_NAME_PROTOCOL *This,
|
||||||
|
IN OUT UINTN *BufferSize,
|
||||||
|
OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Sets the iSSI Initiator Name.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
This - Pointer to the EFI_ISCSI_INITIATOR_NAME_PROTOCOL instance.
|
||||||
|
BufferSize - Size of the buffer in bytes pointed to by Buffer.
|
||||||
|
Buffer - Pointer to the buffer for data to be written.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - Data was successfully stored by the protocol.
|
||||||
|
EFI_UNSUPPORTED - Platform policies do not allow for data to be written.
|
||||||
|
EFI_INVALID_PARAMETER - BufferSize exceeds the maximum allowed limit.
|
||||||
|
BufferSize will be updated with the maximum size
|
||||||
|
required to complete the request.
|
||||||
|
EFI_INVALID_PARAMETER - Buffersize is NULL. BufferSize and Buffer will not be
|
||||||
|
affected.
|
||||||
|
EFI_INVALID_PARAMETER - Buffer is NULL. BufferSize and Buffer will not be affected.
|
||||||
|
EFI_DEVICE_ERROR - The data could not be stored due to a hardware error.
|
||||||
|
EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the data
|
||||||
|
EFI_PROTOCOL_ERROR - Input iSCSI initiator name does not adhere to RFC 3720
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if ((BufferSize == NULL) || (Buffer == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*BufferSize > ISCSI_NAME_MAX_SIZE) {
|
||||||
|
*BufferSize = ISCSI_NAME_MAX_SIZE;
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// only support iqn iSCSI names.
|
||||||
|
//
|
||||||
|
Status = IScsiNormalizeName ((CHAR8 *) Buffer, *BufferSize - 1);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->SetVariable (
|
||||||
|
ISCSI_INITIATOR_NAME_VAR_NAME,
|
||||||
|
&gEfiIScsiInitiatorNameProtocolGuid,
|
||||||
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||||
|
*BufferSize,
|
||||||
|
Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
965
MdeModulePkg/Universal/iScsi/IScsiMisc.c
Normal file
965
MdeModulePkg/Universal/iScsi/IScsiMisc.c
Normal file
@ -0,0 +1,965 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiMisc.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Miscellaneous routines for iSCSI driver.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
STATIC CONST CHAR8 IScsiHexString[] = "0123456789ABCDEFabcdef";
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
IsHexDigit (
|
||||||
|
OUT UINT8 *Digit,
|
||||||
|
IN CHAR16 Char
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
Determines if a Unicode character is a hexadecimal digit.
|
||||||
|
The test is case insensitive.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
Digit - Pointer to byte that receives the value of the hex character.
|
||||||
|
Char - Unicode character to test.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
TRUE - If the character is a hexadecimal digit.
|
||||||
|
FALSE - Otherwise.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
if ((Char >= L'0') && (Char <= L'9')) {
|
||||||
|
*Digit = (UINT8) (Char - L'0');
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Char >= L'A') && (Char <= L'F')) {
|
||||||
|
*Digit = (UINT8) (Char - L'A' + 0x0A);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Char >= L'a') && (Char <= L'f')) {
|
||||||
|
*Digit = (UINT8) (Char - L'a' + 0x0A);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
StrTrim (
|
||||||
|
IN OUT CHAR16 *str,
|
||||||
|
IN CHAR16 CharC
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Removes (trims) specified leading and trailing characters from a string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
str - Pointer to the null-terminated string to be trimmed. On return,
|
||||||
|
str will hold the trimmed string.
|
||||||
|
CharC - Character will be trimmed from str.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
CHAR16 *p1;
|
||||||
|
CHAR16 *p2;
|
||||||
|
|
||||||
|
if (*str == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trim off the leading and trailing characters c
|
||||||
|
//
|
||||||
|
for (p1 = str; *p1 && *p1 == CharC; p1++) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
p2 = str;
|
||||||
|
if (p2 == p1) {
|
||||||
|
while (*p1) {
|
||||||
|
p2++;
|
||||||
|
p1++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (*p1) {
|
||||||
|
*p2 = *p1;
|
||||||
|
p1++;
|
||||||
|
p2++;
|
||||||
|
}
|
||||||
|
*p2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (p1 = str + StrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
if (p1 != str + StrLen(str) - 1) {
|
||||||
|
*(p1 + 1) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8
|
||||||
|
IScsiGetSubnetMaskPrefixLength (
|
||||||
|
IN EFI_IPv4_ADDRESS *SubnetMask
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Calculate the prefix length of the IPv4 subnet mask.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
SubnetMask - The IPv4 subnet mask.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
The prefix length of the subnet mask.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT8 Len;
|
||||||
|
UINT32 ReverseMask;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The SubnetMask is in network byte order.
|
||||||
|
//
|
||||||
|
ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reverse it.
|
||||||
|
//
|
||||||
|
ReverseMask = ~ReverseMask;
|
||||||
|
|
||||||
|
if (ReverseMask & (ReverseMask + 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Len = 0;
|
||||||
|
|
||||||
|
while (ReverseMask != 0) {
|
||||||
|
ReverseMask = ReverseMask >> 1;
|
||||||
|
Len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 32 - Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiAsciiStrToLun (
|
||||||
|
IN CHAR8 *Str,
|
||||||
|
OUT UINT8 *Lun
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the hexadecimal encoded LUN string into the 64-bit LUN.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Str - The hexadecimal encoded LUN string.
|
||||||
|
Lun - Storage to return the 64-bit LUN.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The 64-bit LUN is stored in Lun.
|
||||||
|
EFI_INVALID_PARAMETER - The string is malformatted.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT32 Index;
|
||||||
|
CHAR8 *LunUnitStr[4];
|
||||||
|
CHAR8 Digit;
|
||||||
|
|
||||||
|
NetZeroMem (Lun, 8);
|
||||||
|
NetZeroMem (LunUnitStr, sizeof (LunUnitStr));
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
LunUnitStr[0] = Str;
|
||||||
|
|
||||||
|
if (!IsHexDigit (&Digit, *Str)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*Str != '\0') {
|
||||||
|
//
|
||||||
|
// Legal representations of LUN:
|
||||||
|
// 4752-3A4F-6b7e-2F99,
|
||||||
|
// 6734-9-156f-127,
|
||||||
|
// 4186-9
|
||||||
|
//
|
||||||
|
if (*Str == '-') {
|
||||||
|
*Str = '\0';
|
||||||
|
Index++;
|
||||||
|
|
||||||
|
if (*(Str + 1) != '\0') {
|
||||||
|
if (!IsHexDigit (&Digit, *(Str + 1))) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
LunUnitStr[Index] = Str + 1;
|
||||||
|
}
|
||||||
|
} else if (!IsHexDigit (&Digit, *Str)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0; (Index < 4) && (LunUnitStr[Index] != NULL); Index++) {
|
||||||
|
if (AsciiStrLen (LunUnitStr[Index]) > 4) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((UINT16 *) &Lun[Index * 2]) = HTONS (AsciiStrHexToUintn (LunUnitStr[Index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiLunToUnicodeStr (
|
||||||
|
IN UINT8 *Lun,
|
||||||
|
OUT CHAR16 *Str
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the 64-bit LUN into the hexadecimal encoded LUN string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Lun - The 64-bit LUN.
|
||||||
|
Str - The storage to return the hexadecimal encoded LUN string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
CHAR16 *TempStr;
|
||||||
|
|
||||||
|
TempStr = Str;
|
||||||
|
|
||||||
|
for (Index = 0; Index < 4; Index++) {
|
||||||
|
|
||||||
|
if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {
|
||||||
|
StrCpy (TempStr, L"0-");
|
||||||
|
} else {
|
||||||
|
TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];
|
||||||
|
TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0xf];
|
||||||
|
TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];
|
||||||
|
TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0xf];
|
||||||
|
TempStr[4] = L'-';
|
||||||
|
TempStr[5] = 0;
|
||||||
|
|
||||||
|
StrTrim (TempStr, L'0');
|
||||||
|
}
|
||||||
|
|
||||||
|
TempStr += StrLen (TempStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Str[StrLen (Str) - 1] = 0;
|
||||||
|
|
||||||
|
for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {
|
||||||
|
if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {
|
||||||
|
Str[Index - 1] = 0;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR16 *
|
||||||
|
IScsiAsciiStrToUnicodeStr (
|
||||||
|
IN CHAR8 *Source,
|
||||||
|
OUT CHAR16 *Destination
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the ASCII string into a UNICODE string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Source - The ASCII string.
|
||||||
|
Destination - The storage to return the UNICODE string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Pointer to the UNICODE string.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ASSERT (Destination != NULL);
|
||||||
|
ASSERT (Source != NULL);
|
||||||
|
|
||||||
|
while (*Source != '\0') {
|
||||||
|
*(Destination++) = (CHAR16) *(Source++);
|
||||||
|
}
|
||||||
|
|
||||||
|
*Destination = '\0';
|
||||||
|
|
||||||
|
return Destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHAR8 *
|
||||||
|
IScsiUnicodeStrToAsciiStr (
|
||||||
|
IN CHAR16 *Source,
|
||||||
|
OUT CHAR8 *Destination
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the UNICODE string into an ASCII string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Source - The UNICODE string.
|
||||||
|
Destination - The storage to return the ASCII string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
Pointer to the ASCII string.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ASSERT (Destination != NULL);
|
||||||
|
ASSERT (Source != NULL);
|
||||||
|
|
||||||
|
while (*Source != '\0') {
|
||||||
|
//
|
||||||
|
// If any Unicode characters in Source contain
|
||||||
|
// non-zero value in the upper 8 bits, then ASSERT().
|
||||||
|
//
|
||||||
|
ASSERT (*Source < 0x100);
|
||||||
|
*(Destination++) = (CHAR8) *(Source++);
|
||||||
|
}
|
||||||
|
|
||||||
|
*Destination = '\0';
|
||||||
|
|
||||||
|
return Destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiAsciiStrToIp (
|
||||||
|
IN CHAR8 *Str,
|
||||||
|
OUT EFI_IPv4_ADDRESS *Ip
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the decimal dotted IPv4 address into the binary IPv4 address.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Str - The UNICODE string.
|
||||||
|
Ip - The storage to return the ASCII string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The binary IP address is returned in Ip.
|
||||||
|
EFI_INVALID_PARAMETER - The IP string is malformatted.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
UINTN Number;
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
|
||||||
|
while (*Str) {
|
||||||
|
|
||||||
|
if (Index > 3) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Number = 0;
|
||||||
|
while (NET_IS_DIGIT (*Str)) {
|
||||||
|
Number = Number * 10 + (*Str - '0');
|
||||||
|
Str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number > 0xFF) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ip->Addr[Index] = (UINT8) Number;
|
||||||
|
|
||||||
|
if ((*Str != '\0') && (*Str != '.')) {
|
||||||
|
//
|
||||||
|
// The current character should be either the NULL terminator or
|
||||||
|
// the dot delimiter.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*Str == '.') {
|
||||||
|
//
|
||||||
|
// Skip the delimiter.
|
||||||
|
//
|
||||||
|
Str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Index != 4) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiMacAddrToStr (
|
||||||
|
IN EFI_MAC_ADDRESS *Mac,
|
||||||
|
IN UINT32 Len,
|
||||||
|
OUT CHAR16 *Str
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the mac address into a hexadecimal encoded "-" seperated string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Mac - The mac address.
|
||||||
|
Len - Length in bytes of the mac address.
|
||||||
|
Str - The storage to return the mac string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT32 Index;
|
||||||
|
|
||||||
|
for (Index = 0; Index < Len; Index++) {
|
||||||
|
Str[3 * Index] = NibbleToHexChar (Mac->Addr[Index] >> 4);
|
||||||
|
Str[3 * Index + 1] = NibbleToHexChar (Mac->Addr[Index]);
|
||||||
|
Str[3 * Index + 2] = L'-';
|
||||||
|
}
|
||||||
|
|
||||||
|
Str[3 * Index - 1] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiBinToHex (
|
||||||
|
IN UINT8 *BinBuffer,
|
||||||
|
IN UINT32 BinLength,
|
||||||
|
IN OUT CHAR8 *HexStr,
|
||||||
|
IN OUT UINT32 *HexLength
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the binary encoded buffer into a hexadecimal encoded string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
BinBuffer - The buffer containing the binary data.
|
||||||
|
BinLength - Length of the binary buffer.
|
||||||
|
HexStr - Pointer to the string.
|
||||||
|
HexLength - The length of the string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The binary data is converted to the hexadecimal string
|
||||||
|
and the length of the string is updated.
|
||||||
|
EFI_BUFFER_TOO_SMALL - The string is too small.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((*HexLength) - 3) < BinLength * 2) {
|
||||||
|
*HexLength = BinLength * 2 + 3;
|
||||||
|
return EFI_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*HexLength = BinLength * 2 + 3;
|
||||||
|
//
|
||||||
|
// Prefix for Hex String
|
||||||
|
//
|
||||||
|
HexStr[0] = '0';
|
||||||
|
HexStr[1] = 'x';
|
||||||
|
|
||||||
|
for (Index = 0; Index < BinLength; Index++) {
|
||||||
|
HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];
|
||||||
|
HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
HexStr[Index * 2 + 2] = '\0';
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiHexToBin (
|
||||||
|
IN OUT UINT8 *BinBuffer,
|
||||||
|
IN OUT UINT32 *BinLength,
|
||||||
|
IN CHAR8 *HexStr
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Convert the hexadecimal string into a binary encoded buffer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
BinBuffer - The binary buffer.
|
||||||
|
BinLength - Length of the binary buffer.
|
||||||
|
HexStr - The hexadecimal string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The hexadecimal string is converted into a binary
|
||||||
|
encoded buffer.
|
||||||
|
EFI_BUFFER_TOO_SMALL - The binary buffer is too small to hold the converted data.s
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
UINT32 HexCount;
|
||||||
|
CHAR8 *HexBuf;
|
||||||
|
UINT8 Digit;
|
||||||
|
UINT8 Byte;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find out how many hex characters the string has.
|
||||||
|
//
|
||||||
|
HexBuf = HexStr;
|
||||||
|
if ((HexBuf[0] == '0') && ((HexBuf[1] == 'x') || (HexBuf[1] == 'X'))) {
|
||||||
|
HexBuf += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Index = 0, HexCount = 0; IsHexDigit (&Digit, HexBuf[Index]); Index++, HexCount++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (HexCount == 0) {
|
||||||
|
*BinLength = 0;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Test if buffer is passed enough.
|
||||||
|
//
|
||||||
|
if (((HexCount + 1) / 2) > *BinLength) {
|
||||||
|
*BinLength = (HexCount + 1) / 2;
|
||||||
|
return EFI_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*BinLength = (HexCount + 1) / 2;
|
||||||
|
|
||||||
|
for (Index = 0; Index < HexCount; Index++) {
|
||||||
|
|
||||||
|
IsHexDigit (&Digit, HexBuf[HexCount - 1 - Index]);
|
||||||
|
|
||||||
|
if ((Index & 1) == 0) {
|
||||||
|
Byte = Digit;
|
||||||
|
} else {
|
||||||
|
Byte = BinBuffer[*BinLength - 1 - Index / 2];
|
||||||
|
Byte &= 0x0F;
|
||||||
|
Byte |= Digit << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinBuffer[*BinLength - 1 - Index / 2] = Byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiGenRandom (
|
||||||
|
IN OUT UINT8 *Rand,
|
||||||
|
IN UINTN RandLength
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Generate random numbers.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Rand - The buffer to contain random numbers.
|
||||||
|
RandLength - The length of the Rand buffer.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT32 Random;
|
||||||
|
|
||||||
|
while (RandLength > 0) {
|
||||||
|
Random = NET_RANDOM (NetRandomInitSeed ());
|
||||||
|
*Rand++ = (UINT8) (Random);
|
||||||
|
RandLength--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISCSI_DRIVER_DATA *
|
||||||
|
IScsiCreateDriverData (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Create the iSCSI driver data..
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Image - The handle of the driver image.
|
||||||
|
Controller - The handle of the controller.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
The iSCSI driver data created.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Private = NetAllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));
|
||||||
|
if (Private == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;
|
||||||
|
Private->Image = Image;
|
||||||
|
Private->Controller = Controller;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create an event to be signal when the BS to RT transition is triggerd so
|
||||||
|
// as to abort the iSCSI session.
|
||||||
|
//
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||||
|
TPL_CALLBACK,
|
||||||
|
IScsiOnExitBootService,
|
||||||
|
Private,
|
||||||
|
&Private->ExitBootServiceEvent
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
NetFreePool (Private);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));
|
||||||
|
|
||||||
|
//
|
||||||
|
// 0 is designated to the TargetId, so use another value for the AdapterId.
|
||||||
|
//
|
||||||
|
Private->ExtScsiPassThruMode.AdapterId = 2;
|
||||||
|
Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
|
||||||
|
Private->ExtScsiPassThruMode.IoAlign = 4;
|
||||||
|
Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install the Ext SCSI PASS THRU protocol.
|
||||||
|
//
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&Private->ExtScsiPassThruHandle,
|
||||||
|
&gEfiExtScsiPassThruProtocolGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
&Private->IScsiExtScsiPassThru
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
gBS->CloseEvent (Private->ExitBootServiceEvent);
|
||||||
|
NetFreePool (Private);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IScsiSessionInit (&Private->Session, FALSE);
|
||||||
|
|
||||||
|
return Private;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiCleanDriverData (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Clean the iSCSI driver data.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Private - The iSCSI driver data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
if (Private->DevicePath != NULL) {
|
||||||
|
gBS->UninstallProtocolInterface (
|
||||||
|
Private->ExtScsiPassThruHandle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
Private->DevicePath
|
||||||
|
);
|
||||||
|
|
||||||
|
NetFreePool (Private->DevicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Private->ExtScsiPassThruHandle != NULL) {
|
||||||
|
gBS->UninstallProtocolInterface (
|
||||||
|
Private->ExtScsiPassThruHandle,
|
||||||
|
&gEfiExtScsiPassThruProtocolGuid,
|
||||||
|
&Private->IScsiExtScsiPassThru
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->CloseEvent (Private->ExitBootServiceEvent);
|
||||||
|
|
||||||
|
NetFreePool (Private);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiGetConfigData (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Get the various configuration data of this iSCSI instance.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Private - The iSCSI driver data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The configuration of this instance is got.
|
||||||
|
EFI_NOT_FOUND - This iSCSI instance is not configured yet.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
UINTN BufferSize;
|
||||||
|
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||||
|
EFI_SIMPLE_NETWORK_MODE *Mode;
|
||||||
|
CHAR16 MacString[65];
|
||||||
|
|
||||||
|
//
|
||||||
|
// get the iSCSI Initiator Name
|
||||||
|
//
|
||||||
|
Session = &Private->Session;
|
||||||
|
Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;
|
||||||
|
Status = gIScsiInitiatorName.Get (
|
||||||
|
&gIScsiInitiatorName,
|
||||||
|
&Session->InitiatorNameLength,
|
||||||
|
Session->InitiatorName
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
Private->Controller,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&Snp
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode = Snp->Mode;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the mac string, it's the name of various variable
|
||||||
|
//
|
||||||
|
IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the normal configuration.
|
||||||
|
//
|
||||||
|
BufferSize = sizeof (Session->ConfigData.NvData);
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
MacString,
|
||||||
|
&gEfiIScsiInitiatorNameProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&BufferSize,
|
||||||
|
&Session->ConfigData.NvData
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Session->ConfigData.NvData.Enabled) {
|
||||||
|
return EFI_ABORTED;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Get the CHAP Auth information.
|
||||||
|
//
|
||||||
|
BufferSize = sizeof (Session->AuthData.AuthConfig);
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
MacString,
|
||||||
|
&mIScsiCHAPAuthInfoGuid,
|
||||||
|
NULL,
|
||||||
|
&BufferSize,
|
||||||
|
&Session->AuthData.AuthConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {
|
||||||
|
//
|
||||||
|
// Start dhcp.
|
||||||
|
//
|
||||||
|
Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *
|
||||||
|
IScsiGetTcpConnDevicePath (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Get the device path of the iSCSI tcp connection and update it.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Private - The iSCSI driver data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
The updated device path.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_SESSION *Session;
|
||||||
|
ISCSI_CONNECTION *Conn;
|
||||||
|
TCP4_IO *Tcp4Io;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DEV_PATH *DPathNode;
|
||||||
|
|
||||||
|
Session = &Private->Session;
|
||||||
|
if (Session->State != SESSION_STATE_LOGGED_IN) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Conn = NET_LIST_USER_STRUCT_S (
|
||||||
|
Session->Conns.ForwardLink,
|
||||||
|
ISCSI_CONNECTION,
|
||||||
|
Link,
|
||||||
|
ISCSI_CONNECTION_SIGNATURE
|
||||||
|
);
|
||||||
|
Tcp4Io = &Conn->Tcp4Io;
|
||||||
|
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
Tcp4Io->Handle,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
&DevicePath
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Duplicate it.
|
||||||
|
//
|
||||||
|
DevicePath = DuplicateDevicePath (DevicePath);
|
||||||
|
|
||||||
|
DPathNode = (EFI_DEV_PATH *) DevicePath;
|
||||||
|
|
||||||
|
while (!IsDevicePathEnd (&DPathNode->DevPath)) {
|
||||||
|
if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&
|
||||||
|
(DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)
|
||||||
|
) {
|
||||||
|
|
||||||
|
DPathNode->Ipv4.LocalPort = 0;
|
||||||
|
DPathNode->Ipv4.StaticIpAddress = !Session->ConfigData.NvData.InitiatorInfoFromDhcp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
IScsiOnExitBootService (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Abort the session when the transition from BS to RT is initiated.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Event - The event signaled.
|
||||||
|
Context - The iSCSI driver data.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
ISCSI_DRIVER_DATA *Private;
|
||||||
|
|
||||||
|
Private = (ISCSI_DRIVER_DATA *) Context;
|
||||||
|
gBS->CloseEvent (Private->ExitBootServiceEvent);
|
||||||
|
|
||||||
|
IScsiSessionAbort (&Private->Session);
|
||||||
|
}
|
143
MdeModulePkg/Universal/iScsi/IScsiMisc.h
Normal file
143
MdeModulePkg/Universal/iScsi/IScsiMisc.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiMisc.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Miscellaneous definitions for iSCSI driver.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_MISC_H_
|
||||||
|
#define _ISCSI_MISC_H_
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct _ISCSI_SESSION_CONFIG_NVDATA {
|
||||||
|
BOOLEAN Enabled;
|
||||||
|
|
||||||
|
BOOLEAN InitiatorInfoFromDhcp;
|
||||||
|
EFI_IPv4_ADDRESS LocalIp;
|
||||||
|
EFI_IPv4_ADDRESS SubnetMask;
|
||||||
|
EFI_IPv4_ADDRESS Gateway;
|
||||||
|
|
||||||
|
BOOLEAN TargetInfoFromDhcp;
|
||||||
|
CHAR8 TargetName[ISCSI_NAME_MAX_SIZE];
|
||||||
|
EFI_IPv4_ADDRESS TargetIp;
|
||||||
|
UINT16 TargetPort;
|
||||||
|
UINT8 BootLun[8];
|
||||||
|
} ISCSI_SESSION_CONFIG_NVDATA;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct _ISCSI_SESSION_CONFIG_DATA {
|
||||||
|
ISCSI_SESSION_CONFIG_NVDATA NvData;
|
||||||
|
|
||||||
|
EFI_IPv4_ADDRESS PrimaryDns;
|
||||||
|
EFI_IPv4_ADDRESS SecondaryDns;
|
||||||
|
EFI_IPv4_ADDRESS DhcpServer;
|
||||||
|
} ISCSI_SESSION_CONFIG_DATA;
|
||||||
|
|
||||||
|
UINT8
|
||||||
|
IScsiGetSubnetMaskPrefixLength (
|
||||||
|
IN EFI_IPv4_ADDRESS *SubnetMask
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiAsciiStrToLun (
|
||||||
|
IN CHAR8 *Str,
|
||||||
|
OUT UINT8 *Lun
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiLunToUnicodeStr (
|
||||||
|
IN UINT8 *Lun,
|
||||||
|
OUT CHAR16 *String
|
||||||
|
);
|
||||||
|
|
||||||
|
CHAR16 *
|
||||||
|
IScsiAsciiStrToUnicodeStr (
|
||||||
|
IN CHAR8 *Source,
|
||||||
|
OUT CHAR16 *Destination
|
||||||
|
);
|
||||||
|
|
||||||
|
CHAR8 *
|
||||||
|
IScsiUnicodeStrToAsciiStr (
|
||||||
|
IN CHAR16 *Source,
|
||||||
|
OUT CHAR8 *Destination
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiMacAddrToStr (
|
||||||
|
IN EFI_MAC_ADDRESS *Mac,
|
||||||
|
IN UINT32 Len,
|
||||||
|
OUT CHAR16 *Str
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiAsciiStrToIp (
|
||||||
|
IN CHAR8 *Str,
|
||||||
|
OUT EFI_IPv4_ADDRESS *Ip
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiBinToHex (
|
||||||
|
IN UINT8 *BinBuffer,
|
||||||
|
IN UINT32 BinLength,
|
||||||
|
IN OUT CHAR8 *HexStr,
|
||||||
|
IN OUT UINT32 *HexLength
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiHexToBin (
|
||||||
|
IN OUT UINT8 *BinBuffer,
|
||||||
|
IN OUT UINT32 *BinLength,
|
||||||
|
IN CHAR8 *HexStr
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiGenRandom (
|
||||||
|
IN OUT UINT8 *Rand,
|
||||||
|
IN UINTN RandLength
|
||||||
|
);
|
||||||
|
|
||||||
|
ISCSI_DRIVER_DATA *
|
||||||
|
IScsiCreateDriverData (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiCleanDriverData (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiGetConfigData (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *
|
||||||
|
IScsiGetTcpConnDevicePath (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
IScsiOnExitBootService (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
);
|
||||||
|
|
||||||
|
extern CHAR16 NibbleToHexChar(UINT8 Nibble);
|
||||||
|
|
||||||
|
#endif
|
3080
MdeModulePkg/Universal/iScsi/IScsiProto.c
Normal file
3080
MdeModulePkg/Universal/iScsi/IScsiProto.c
Normal file
File diff suppressed because it is too large
Load Diff
786
MdeModulePkg/Universal/iScsi/IScsiProto.h
Normal file
786
MdeModulePkg/Universal/iScsi/IScsiProto.h
Normal file
@ -0,0 +1,786 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiProto.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Protocol definitions for iSCSI driver, mainly from RFC3720.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_PROTO_H_
|
||||||
|
#define _ISCSI_PROTO_H_
|
||||||
|
|
||||||
|
#include <protocol/ScsiPassThruExt.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// RFC 1982 Serial Number Arithmetic, SERIAL_BITS = 32
|
||||||
|
//
|
||||||
|
#define ISCSI_SEQ_EQ(s1, s2) ((s1) == (s2))
|
||||||
|
#define ISCSI_SEQ_LT(s1, s2) \
|
||||||
|
( \
|
||||||
|
(((INT32) (s1) < (INT32) (s2)) && (s2 - s1) < (1 << 31)) || \
|
||||||
|
(((INT32) (s1) > (INT32) (s2)) && (s1 - s2) > (1 << 31)) \
|
||||||
|
)
|
||||||
|
#define ISCSI_SEQ_GT(s1, s2) \
|
||||||
|
( \
|
||||||
|
(((INT32) (s1) < (INT32) (s2)) && (s2 - s1) > (1 << 31)) || \
|
||||||
|
(((INT32) (s1) > (INT32) (s2)) && (s1 - s2) < (1 << 31)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ISCSI_WELL_KNOWN_PORT 3260
|
||||||
|
#define ISCSI_MAX_CONNS_PER_SESSION 1
|
||||||
|
|
||||||
|
#define DEFAULT_MAX_RECV_DATA_SEG_LEN 8192
|
||||||
|
#define MAX_RECV_DATA_SEG_LEN_IN_FFP 65536
|
||||||
|
#define DEFAULT_MAX_OUTSTANDING_R2T 1
|
||||||
|
|
||||||
|
#define ISCSI_VERSION_MAX 0x00
|
||||||
|
#define ISCSI_VERSION_MIN 0x00
|
||||||
|
|
||||||
|
#define ISID_BYTE_0 0 // OUI format
|
||||||
|
#define ISID_BYTE_1 0
|
||||||
|
#define ISID_BYTE_2 0xaa
|
||||||
|
#define ISID_BYTE_3 0x1
|
||||||
|
|
||||||
|
#define ISCSI_KEY_AUTH_METHOD "AuthMethod"
|
||||||
|
#define ISCSI_KEY_HEADER_DIGEST "HeaderDigest"
|
||||||
|
#define ISCSI_KEY_DATA_DIGEST "DataDigest"
|
||||||
|
#define ISCSI_KEY_MAX_CONNECTIONS "MaxConnections"
|
||||||
|
#define ISCSI_KEY_TARGET_NAME "TargetName"
|
||||||
|
#define ISCSI_KEY_INITIATOR_NAME "InitiatorName"
|
||||||
|
#define ISCSI_KEY_TARGET_ALIAS "TargetAlias"
|
||||||
|
#define ISCSI_KEY_INITIATOR_ALIAS "InitiatorAlias"
|
||||||
|
#define ISCSI_KEY_TARGET_ADDRESS "TargetAddress"
|
||||||
|
#define ISCSI_KEY_INITIAL_R2T "InitialR2T"
|
||||||
|
#define ISCSI_KEY_IMMEDIATE_DATA "ImmediateData"
|
||||||
|
#define ISCSI_KEY_TARGET_PORTAL_GROUP_TAG "TargetPortalGroupTag"
|
||||||
|
#define ISCSI_KEY_MAX_BURST_LENGTH "MaxBurstLength"
|
||||||
|
#define ISCSI_KEY_FIRST_BURST_LENGTH "FirstBurstLength"
|
||||||
|
#define ISCSI_KEY_DEFAULT_TIME2WAIT "DefaultTime2Wait"
|
||||||
|
#define ISCSI_KEY_DEFAULT_TIME2RETAIN "DefaultTime2Retain"
|
||||||
|
#define ISCSI_KEY_MAX_OUTSTANDING_R2T "MaxOutstandingR2T"
|
||||||
|
#define ISCSI_KEY_DATA_PDU_IN_ORDER "DataPDUInOrder"
|
||||||
|
#define ISCSI_KEY_DATA_SEQUENCE_IN_ORDER "DataSequenceInOrder"
|
||||||
|
#define ISCSI_KEY_ERROR_RECOVERY_LEVEL "ErrorRecoveryLevel"
|
||||||
|
#define ISCSI_KEY_SESSION_TYPE "SessionType"
|
||||||
|
#define ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH "MaxRecvDataSegmentLength"
|
||||||
|
|
||||||
|
#define ISCSI_KEY_VALUE_NONE "None"
|
||||||
|
|
||||||
|
//
|
||||||
|
// connection state for initiator
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
CONN_STATE_FREE,
|
||||||
|
CONN_STATE_XPT_WAIT,
|
||||||
|
CONN_STATE_IN_LOGIN,
|
||||||
|
CONN_STATE_LOGGED_IN,
|
||||||
|
CONN_STATE_IN_LOGOUT,
|
||||||
|
CONN_STATE_LOGOUT_REQUESTED,
|
||||||
|
CONN_STATE_CLEANUP_WAIT,
|
||||||
|
CONN_STATE_IN_CLEANUP
|
||||||
|
} CONNECTION_STATE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// session state for initiator
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
SESSION_STATE_FREE,
|
||||||
|
SESSION_STATE_LOGGED_IN,
|
||||||
|
SESSION_STATE_FAILED
|
||||||
|
} SESSION_STATE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DataIn = 0,
|
||||||
|
DataOut = 1,
|
||||||
|
DataBi = 2
|
||||||
|
} DATA_DIRECTION;
|
||||||
|
|
||||||
|
#define ISCSI_RESERVED_TAG 0xffffffff
|
||||||
|
|
||||||
|
#define ISCSI_REQ_IMMEDIATE 0x40
|
||||||
|
#define ISCSI_OPCODE_MASK 0x3F
|
||||||
|
|
||||||
|
#define ISCSI_SET_OPCODE(PduHdr, Op, Flgs) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) = ((Op) | (Flgs)))
|
||||||
|
#define ISCSI_GET_OPCODE(PduHdr) ((((ISCSI_BASIC_HEADER *) (PduHdr))->OpCode) & ISCSI_OPCODE_MASK)
|
||||||
|
#define ISCSI_CHECK_OPCODE(PduHdr, Op) ((((PduHdr)->OpCode) & ISCSI_OPCODE_MASK) == (Op))
|
||||||
|
#define ISCSI_IMMEDIATE_ON(PduHdr) ((PduHdr)->OpCode & ISCSI_REQ_IMMEDIATE)
|
||||||
|
#define ISCSI_SET_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags |= (Flag))
|
||||||
|
#define ISCSI_CLEAR_FLAG(PduHdr, Flag) (((ISCSI_BASIC_HEADER *) (PduHdr))->Flags &= ~(Flag))
|
||||||
|
#define ISCSI_FLAG_ON(PduHdr, Flag) ((((ISCSI_BASIC_HEADER *) (PduHdr))->Flags & (Flag)) == (Flag))
|
||||||
|
#define ISCSI_SET_STAGES(PduHdr, Cur, Nxt) ((PduHdr)->Flags |= ((Cur) << 2 | (Nxt)))
|
||||||
|
#define ISCSI_GET_CURRENT_STAGE(PduHdr) (((PduHdr)->Flags >> 2) & 0x3)
|
||||||
|
#define ISCSI_GET_NEXT_STAGE(PduHdr) (((PduHdr)->Flags) & 0x3)
|
||||||
|
|
||||||
|
#define ISCSI_GET_PAD_LEN(DataLen) ((~(DataLen) + 1) & 0x3)
|
||||||
|
#define ISCSI_ROUNDUP(DataLen) (((DataLen) + 3) &~(0x3))
|
||||||
|
|
||||||
|
#define HTON24(Dst, Src) \
|
||||||
|
do { \
|
||||||
|
(Dst)[0] = (UINT8) ((Src) >> 16) & 0xFF; \
|
||||||
|
(Dst)[1] = (UINT8) ((Src) >> 8) & 0xFF; \
|
||||||
|
(Dst)[2] = (UINT8) (Src) & 0xFF; \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define NTOH24(src) (((src)[0] << 16) | ((src)[1] << 8) | ((src)[2]))
|
||||||
|
|
||||||
|
#define ISCSI_GET_DATASEG_LEN(PduHdr) NTOH24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength)
|
||||||
|
#define ISCSI_SET_DATASEG_LEN(PduHdr, Len) HTON24 (((ISCSI_BASIC_HEADER *) (PduHdr))->DataSegmentLength, (Len))
|
||||||
|
|
||||||
|
//
|
||||||
|
// initiator opcodes
|
||||||
|
//
|
||||||
|
#define ISCSI_OPCODE_NOP_OUT 0x00
|
||||||
|
#define ISCSI_OPCODE_SCSI_CMD 0x01
|
||||||
|
#define ISCSI_OPCODE_SCSI_TMF_REQ 0x02
|
||||||
|
#define ISCSI_OPCODE_LOGIN_REQ 0x03
|
||||||
|
#define ISCSI_OPCODE_TEXT_REQ 0x04
|
||||||
|
#define ISCSI_OPCODE_SCSI_DATA_OUT 0x05
|
||||||
|
#define ISCSI_OPCODE_LOGOUT_REQ 0x06
|
||||||
|
#define ISCSI_OPCODE_SNACK_REQ 0x10
|
||||||
|
#define ISCSI_OPCODE_VENDOR_I0 0x1c
|
||||||
|
#define ISCSI_OPCODE_VENDOR_I1 0x1d
|
||||||
|
#define ISCSI_OPCODE_VENDOR_I2 0x1e
|
||||||
|
|
||||||
|
//
|
||||||
|
// target opcodes
|
||||||
|
//
|
||||||
|
#define ISCSI_OPCODE_NOP_IN 0x20
|
||||||
|
#define ISCSI_OPCODE_SCSI_RSP 0x21
|
||||||
|
#define ISCSI_OPCODE_SCSI_TMF_RSP 0x22
|
||||||
|
#define ISCSI_OPCODE_LOGIN_RSP 0x23
|
||||||
|
#define ISCSI_OPCODE_TEXT_RSP 0x24
|
||||||
|
#define ISCSI_OPCODE_SCSI_DATA_IN 0x25
|
||||||
|
#define ISCSI_OPCODE_LOGOUT_RSP 0x26
|
||||||
|
#define ISCSI_OPCODE_R2T 0x31
|
||||||
|
#define ISCSI_OPCODE_ASYNC_MSG 0x32
|
||||||
|
#define ISCSI_OPCODE_VENDOR_T0 0x3c
|
||||||
|
#define ISCSI_OPCODE_VENDOR_T1 0x3d
|
||||||
|
#define ISCSI_OPCODE_VENDOR_T2 0x3e
|
||||||
|
#define ISCSI_OPCODE_REJECT 0x3f
|
||||||
|
|
||||||
|
#define ISCSI_BHS_FLAG_FINAL 0x80
|
||||||
|
|
||||||
|
//
|
||||||
|
// iSCSI Basic Header Segment
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_BASIC_HEADER {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT16 OpCodeSpecific1;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 OpCodeSpecific2[7];
|
||||||
|
} ISCSI_BASIC_HEADER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Defined AHS types, others are reserved.
|
||||||
|
//
|
||||||
|
#define ISCSI_AHS_TYPE_EXT_CDB 0x1
|
||||||
|
#define ISCSI_AHS_TYPE_BI_EXP_READ_DATA_LEN 0x2
|
||||||
|
|
||||||
|
typedef struct _ISCSI_ADDTIONAL_HEADER {
|
||||||
|
UINT16 Length;
|
||||||
|
UINT8 Type;
|
||||||
|
UINT8 TypeSpecific[1];
|
||||||
|
} ISCSI_ADDITIONAL_HEADER;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_BI_EXP_READ_DATA_LEN_AHS {
|
||||||
|
UINT16 Length;
|
||||||
|
UINT8 Type;
|
||||||
|
UINT8 Reserved;
|
||||||
|
UINT32 ExpReadDataLength;
|
||||||
|
} ISCSI_BI_EXP_READ_DATA_LEN_AHS;
|
||||||
|
|
||||||
|
#define SCSI_CMD_PDU_FLAG_READ 0x40
|
||||||
|
#define SCSI_CMD_PDU_FLAG_WRITE 0x20
|
||||||
|
|
||||||
|
#define ISCSI_CMD_PDU_TASK_ATTR_MASK 0x07
|
||||||
|
|
||||||
|
//
|
||||||
|
// task attributes
|
||||||
|
//
|
||||||
|
#define ISCSI_TASK_ATTR_UNTAGGED 0x00
|
||||||
|
#define ISCSI_TASK_ATTR_SIMPLE 0x01
|
||||||
|
#define ISCSI_TASK_ATTR_ORDERD 0x02
|
||||||
|
#define ISCSI_TASK_ATTR_HOQ 0x03
|
||||||
|
#define ISCSI_TASK_ATTR_ACA 0x04
|
||||||
|
|
||||||
|
//
|
||||||
|
// SCSI Command
|
||||||
|
//
|
||||||
|
typedef struct _SCSI_COMMAND {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT16 Reserved;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 ExpDataXferLength;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT8 CDB[16];
|
||||||
|
} SCSI_COMMAND;
|
||||||
|
|
||||||
|
//
|
||||||
|
// flag bit definitions in SCSI response
|
||||||
|
//
|
||||||
|
#define SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW 0x10
|
||||||
|
#define SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW 0x08
|
||||||
|
#define SCSI_RSP_PDU_FLAG_OVERFLOW 0x04
|
||||||
|
#define SCSI_RSP_PDU_FLAG_UNDERFLOW 0x02
|
||||||
|
|
||||||
|
//
|
||||||
|
// iSCSI service response codes
|
||||||
|
//
|
||||||
|
#define ISCSI_SERVICE_RSP_COMMAND_COMPLETE_AT_TARGET 0x00
|
||||||
|
#define ISCSI_SERVICE_RSP_TARGET_FAILURE 0x01
|
||||||
|
|
||||||
|
//
|
||||||
|
// SCSI Response
|
||||||
|
//
|
||||||
|
typedef struct _SCSI_RESPONSE {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT8 Response;
|
||||||
|
UINT8 Status;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Reserved[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 SNACKTag;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 ExpDataSN;
|
||||||
|
UINT32 BiReadResidualCount;
|
||||||
|
UINT32 ResidualCount;
|
||||||
|
} SCSI_RESPONSE;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_SENSE_DATA {
|
||||||
|
UINT16 Length;
|
||||||
|
UINT8 Data[2];
|
||||||
|
} ISCSI_SENSE_DATA;
|
||||||
|
|
||||||
|
//
|
||||||
|
// iSCSI Task Managment Function Request
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_TMF_REQUEST {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Fuction;
|
||||||
|
UINT16 Reserved1;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 ReferencedTaskTag;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 RefCmdSN;
|
||||||
|
UINT32 ExpDataSN;
|
||||||
|
UINT32 Reserved2[2];
|
||||||
|
} ISCSI_TMF_REQUEST;
|
||||||
|
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_COMPLETE 0
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_TASK_NOT_EXIST 1
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_LUN_NOT_EXIST 2
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_TASK_STILL_ALLEGIANT 3
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_TASK_REASSGIN_NOT_SUPPORTED 4
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_NOT_SUPPORTED 5
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_AHTH_FAILED 6
|
||||||
|
#define ISCSI_TMF_RSP_PDU_RSP_FUNCTION_REJECTED 255
|
||||||
|
|
||||||
|
//
|
||||||
|
// iSCSI Task Management Function Response
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_TMF_RESPONSE {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1;
|
||||||
|
UINT8 Response;
|
||||||
|
UINT8 Reserved2;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT32 Reserver3[2];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 Reserved4;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 Reserved[3];
|
||||||
|
} ISCSI_TMF_RESPONSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SCSI Data-Out
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_SCSI_DATA_OUT {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1[3];
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 Reserved2;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 Reserved3;
|
||||||
|
UINT32 DataSN;
|
||||||
|
UINT32 BufferOffset;
|
||||||
|
UINT32 Reserved4;
|
||||||
|
} ISCSI_SCSI_DATA_OUT;
|
||||||
|
|
||||||
|
#define SCSI_DATA_IN_PDU_FLAG_ACKKNOWLEDGE 0x40
|
||||||
|
#define SCSI_DATA_IN_PDU_FLAG_OVERFLOW SCSI_RSP_PDU_FLAG_OVERFLOW
|
||||||
|
#define SCSI_DATA_IN_PDU_FLAG_UNDERFLOW SCSI_RSP_PDU_FLAG_UNDERFLOW
|
||||||
|
#define SCSI_DATA_IN_PDU_FLAG_STATUS_VALID 0x01
|
||||||
|
//
|
||||||
|
// SCSI Data-In
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_SCSI_DATA_IN {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT8 Reserved1;
|
||||||
|
UINT8 Status;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 DataSN;
|
||||||
|
UINT32 BufferOffset;
|
||||||
|
UINT32 ResidualCount;
|
||||||
|
} ISCSI_SCSI_DATA_IN;
|
||||||
|
|
||||||
|
#define ISCSI_GET_BUFFER_OFFSET(PduHdr) NTOHL (((ISCSI_SCSI_DATA_IN *) (PduHdr))->BufferOffset)
|
||||||
|
//
|
||||||
|
// Ready To Transfer
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_READY_TO_TRANSFER {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1[3];
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 R2TSN;
|
||||||
|
UINT32 BufferOffset;
|
||||||
|
UINT32 DesiredDataTransferLength;
|
||||||
|
} ISCSI_READY_TO_TRANSFER;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_ASYNC_MESSAGE {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1[8];
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 Reserved2;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT8 AsyncEvent;
|
||||||
|
UINT8 AsyncVCode;
|
||||||
|
UINT16 Parameter1;
|
||||||
|
UINT16 Parameter2;
|
||||||
|
UINT16 Parameter3;
|
||||||
|
UINT32 Reserved3;
|
||||||
|
} ISCSI_ASYNC_MESSAGE;
|
||||||
|
|
||||||
|
#define ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT 0x80
|
||||||
|
#define ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE 0x40
|
||||||
|
|
||||||
|
//
|
||||||
|
// Login Request
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_LOGIN_REQUEST {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT8 VersionMax;
|
||||||
|
UINT8 VersionMin;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 ISID[6];
|
||||||
|
UINT16 TSIH;
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT16 CID;
|
||||||
|
UINT16 Reserved1;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 Reserved2[4];
|
||||||
|
} ISCSI_LOGIN_REQUEST;
|
||||||
|
|
||||||
|
#define ISCSI_LOGIN_RSP_PDU_FLAG_TRANSIT ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT
|
||||||
|
#define ISCSI_LOGIN_RSP_PDU_FLAG_CONTINUE ISCSI_LOGIN_REQ_PDU_FLAG_CONTINUE
|
||||||
|
|
||||||
|
#define ISCSI_LOGIN_STATUS_SUCCESS 0
|
||||||
|
#define ISCSI_LOGIN_STATUS_REDIRECTION 1
|
||||||
|
#define ISCSI_LOGIN_STATUS_INITIATOR_ERROR 2
|
||||||
|
#define ISCSI_LOGIN_STATUS_TARGET_ERROR 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Login Response
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_LOGIN_RESPONSE {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Flags;
|
||||||
|
UINT8 VersionMax;
|
||||||
|
UINT8 VersionActive;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 ISID[6];
|
||||||
|
UINT16 TSIH;
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 Reserved1;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT8 StatusClass;
|
||||||
|
UINT8 StatusDetail;
|
||||||
|
UINT8 Reserved2[10];
|
||||||
|
} ISCSI_LOGIN_RESPONSE;
|
||||||
|
|
||||||
|
#define ISCSI_LOGOUT_REASON_CLOSE_SESSION 0
|
||||||
|
#define ISCSI_LOGOUT_REASON_CLOSE_CONNECTION 1
|
||||||
|
#define ISCSI_LOGOUT_REASON_REMOVE_CONNECTION_FOR_RECOVERY 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logout Request
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_LOGOUT_REQUEST {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 ReasonCode;
|
||||||
|
UINT16 Reserved1;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT32 Reserved2[2];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT16 CID;
|
||||||
|
UINT16 Reserved3;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 Reserved4[4];
|
||||||
|
} ISCSI_LOGOUT_REQUEST;
|
||||||
|
|
||||||
|
#define ISCSI_LOGOUT_RESPONSE_SESSION_CLOSED_SUCCESS 0
|
||||||
|
#define ISCSI_LOGOUT_RESPONSE_CID_NOT_FOUND 1
|
||||||
|
#define ISCSI_LOGOUT_RESPONSE_RECOVERY_NOT_SUPPORTED 2
|
||||||
|
#define ISCSI_LOGOUT_RESPONSE_CLEANUP_FAILED 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logout Response
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_LOGOUT_RESPONSE {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1;
|
||||||
|
UINT8 Response;
|
||||||
|
UINT8 Reserved2;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT32 Reserved3[2];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 Reserved4;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 Reserved5;
|
||||||
|
UINT16 Time2Wait;
|
||||||
|
UINT16 Time2Retain;
|
||||||
|
UINT32 Reserved6;
|
||||||
|
} ISCSI_LOGOUT_RESPONSE;
|
||||||
|
|
||||||
|
#define ISCSI_SNACK_REQUEST_TYPE_DATA_OR_R2T 0
|
||||||
|
#define ISCSI_SNACK_REQUEST_TYPE_STATUS 1
|
||||||
|
#define ISCSI_SNACK_REQUEST_TYPE_DATA_ACK 2
|
||||||
|
#define ISCSI_SNACK_REQUEST_TYPE_RDATA 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// SNACK Request
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_SNACK_REQUEST {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Type;
|
||||||
|
UINT16 Reserved1;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 Reserved2;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 Reserved[2];
|
||||||
|
UINT32 BegRun;
|
||||||
|
UINT32 RunLength;
|
||||||
|
} ISCSI_SNACK_REQUEST;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reject
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_REJECT {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1;
|
||||||
|
UINT8 Reason;
|
||||||
|
UINT8 Reserved2;
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT32 Reserved3[2];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 Reserved4;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 DataSN;
|
||||||
|
UINT32 Reserved5[2];
|
||||||
|
} ISCSI_REJECT;
|
||||||
|
|
||||||
|
//
|
||||||
|
// NOP-Out
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_NOP_OUT {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1[3];
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 ExpStatSN;
|
||||||
|
UINT32 Reserved2[4];
|
||||||
|
} ISCSI_NOP_OUT;
|
||||||
|
|
||||||
|
//
|
||||||
|
// NOP-In
|
||||||
|
//
|
||||||
|
typedef struct _ISCSI_NOP_IN {
|
||||||
|
UINT8 OpCode;
|
||||||
|
UINT8 Reserved1[3];
|
||||||
|
UINT8 TotalAHSLength;
|
||||||
|
UINT8 DataSegmentLength[3];
|
||||||
|
UINT8 Lun[8];
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 StatSN;
|
||||||
|
UINT32 ExpCmdSN;
|
||||||
|
UINT32 MaxCmdSN;
|
||||||
|
UINT32 Reserved2[3];
|
||||||
|
} ISCSI_NOP_IN;
|
||||||
|
|
||||||
|
#define ISCSI_SECURITY_NEGOTIATION 0
|
||||||
|
#define ISCSI_LOGIN_OPERATIONAL_NEGOTIATION 1
|
||||||
|
#define ISCSI_FULL_FEATURE_PHASE 3
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ISCSI_DIGEST_NONE,
|
||||||
|
ISCSI_DIGEST_CRC32
|
||||||
|
} ISCSI_DIGEST_TYPE;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_XFER_CONTEXT {
|
||||||
|
UINT32 TargetTransferTag;
|
||||||
|
UINT32 Offset;
|
||||||
|
UINT32 DesiredLength;
|
||||||
|
UINT32 ExpDataSN;
|
||||||
|
} ISCSI_XFER_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_IN_BUFFER_CONTEXT {
|
||||||
|
UINT8 *InData;
|
||||||
|
UINT32 InDataLen;
|
||||||
|
} ISCSI_IN_BUFFER_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_TCB {
|
||||||
|
NET_LIST_ENTRY Link;
|
||||||
|
|
||||||
|
BOOLEAN SoFarInOrder;
|
||||||
|
UINT32 ExpDataSN;
|
||||||
|
BOOLEAN FbitReceived;
|
||||||
|
BOOLEAN StatusXferd;
|
||||||
|
UINT32 ActiveR2Ts;
|
||||||
|
UINT32 Response;
|
||||||
|
CHAR8 *Reason;
|
||||||
|
UINT32 InitiatorTaskTag;
|
||||||
|
UINT32 CmdSN;
|
||||||
|
UINT32 SNACKTag;
|
||||||
|
|
||||||
|
ISCSI_XFER_CONTEXT XferContext;
|
||||||
|
|
||||||
|
ISCSI_CONNECTION *Conn;
|
||||||
|
} ISCSI_TCB;
|
||||||
|
|
||||||
|
typedef struct _ISCSI_KEY_VALUE_PAIR {
|
||||||
|
NET_LIST_ENTRY List;
|
||||||
|
|
||||||
|
CHAR8 *Key;
|
||||||
|
CHAR8 *Value;
|
||||||
|
} ISCSI_KEY_VALUE_PAIR;
|
||||||
|
|
||||||
|
//
|
||||||
|
// function prototypes.
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
IScsiAttatchConnection (
|
||||||
|
IN ISCSI_SESSION *Session,
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiDetatchConnection (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiConnLogin (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
ISCSI_CONNECTION *
|
||||||
|
IScsiCreateConnection (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private,
|
||||||
|
IN ISCSI_SESSION *Session
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiDestroyConnection (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiSessionLogin (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiSendLoginReq (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiReceiveLoginRsp (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiAddKeyValuePair (
|
||||||
|
IN NET_BUF *Pdu,
|
||||||
|
IN CHAR8 *Key,
|
||||||
|
IN CHAR8 *Value
|
||||||
|
);
|
||||||
|
|
||||||
|
NET_BUF *
|
||||||
|
IScsiPrepareLoginReq (
|
||||||
|
IN ISCSI_CONNECTION *Conn
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiProcessLoginRsp (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN NET_BUF *Pdu
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiUpdateTargetAddress (
|
||||||
|
IN ISCSI_SESSION *Session,
|
||||||
|
IN CHAR8 *Data,
|
||||||
|
IN UINT32 Len
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiFreeNbufList (
|
||||||
|
VOID *Arg
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiReceivePdu (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
OUT NET_BUF **Pdu,
|
||||||
|
IN ISCSI_IN_BUFFER_CONTEXT *Context, OPTIONAL
|
||||||
|
IN BOOLEAN HeaderDigest,
|
||||||
|
IN BOOLEAN DataDigest,
|
||||||
|
IN EFI_EVENT TimeoutEvent OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiCheckOpParams (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN BOOLEAN Transit
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiFillOpParams (
|
||||||
|
IN ISCSI_CONNECTION *Conn,
|
||||||
|
IN NET_BUF *Pdu
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiPadSegment (
|
||||||
|
IN NET_BUF *Pdu,
|
||||||
|
IN UINT32 Len
|
||||||
|
);
|
||||||
|
|
||||||
|
NET_LIST_ENTRY *
|
||||||
|
IScsiBuildKeyValueList (
|
||||||
|
IN CHAR8 *Data,
|
||||||
|
IN UINT32 Len
|
||||||
|
);
|
||||||
|
|
||||||
|
CHAR8 *
|
||||||
|
IScsiGetValueByKeyFromList (
|
||||||
|
IN NET_LIST_ENTRY *KeyValueList,
|
||||||
|
IN CHAR8 *Key
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiFreeKeyValueList (
|
||||||
|
IN NET_LIST_ENTRY *KeyValueList
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiNormalizeName (
|
||||||
|
IN CHAR8 *Name,
|
||||||
|
IN UINTN Len
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiExecuteScsiCommand (
|
||||||
|
IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru,
|
||||||
|
IN UINT8 *Target,
|
||||||
|
IN UINT64 Lun,
|
||||||
|
IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiSessionReinstatement (
|
||||||
|
IN ISCSI_DRIVER_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IScsiSessionInit (
|
||||||
|
IN ISCSI_SESSION *Session,
|
||||||
|
IN BOOLEAN Recovery
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
IScsiSessionAbort (
|
||||||
|
IN ISCSI_SESSION *Session
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
550
MdeModulePkg/Universal/iScsi/IScsiTcp4Io.c
Normal file
550
MdeModulePkg/Universal/iScsi/IScsiTcp4Io.c
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiTcp4Io.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "IScsiImpl.h"
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
Tcp4IoCommonNotify (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
The common notify function associated with various Tcp4Io events.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Event - The event signaled.
|
||||||
|
Contect - The context.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
*((BOOLEAN *) Context) = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoCreateSocket (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN TCP4_IO_CONFIG_DATA *ConfigData,
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Create a TCP socket with the specified configuration data.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Image - The handle of the driver image.
|
||||||
|
Controller - The handle of the controller.
|
||||||
|
ConfigData - The Tcp4 configuration data.
|
||||||
|
Tcp4Io - The Tcp4Io.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The TCP socket is created and configured.
|
||||||
|
other - Failed to create the TCP socket or configure it.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
|
||||||
|
EFI_TCP4_OPTION ControlOption;
|
||||||
|
EFI_TCP4_ACCESS_POINT *AccessPoint;
|
||||||
|
|
||||||
|
Tcp4Io->Handle = NULL;
|
||||||
|
Tcp4Io->ConnToken.CompletionToken.Event = NULL;
|
||||||
|
Tcp4Io->TxToken.CompletionToken.Event = NULL;
|
||||||
|
Tcp4Io->RxToken.CompletionToken.Event = NULL;
|
||||||
|
Tcp4Io->CloseToken.CompletionToken.Event = NULL;
|
||||||
|
Tcp4 = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the TCP4 child instance and get the TCP4 protocol.
|
||||||
|
//
|
||||||
|
Status = NetLibCreateServiceChild (
|
||||||
|
Controller,
|
||||||
|
Image,
|
||||||
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
|
&Tcp4Io->Handle
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Tcp4Io->Handle,
|
||||||
|
&gEfiTcp4ProtocolGuid,
|
||||||
|
(VOID **)&Tcp4Io->Tcp4,
|
||||||
|
Image,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcp4Io->Image = Image;
|
||||||
|
Tcp4Io->Controller = Controller;
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the configuration parameters.
|
||||||
|
//
|
||||||
|
ControlOption.ReceiveBufferSize = 0x200000;
|
||||||
|
ControlOption.SendBufferSize = 0x200000;
|
||||||
|
ControlOption.MaxSynBackLog = 0;
|
||||||
|
ControlOption.ConnectionTimeout = 0;
|
||||||
|
ControlOption.DataRetries = 6;
|
||||||
|
ControlOption.FinTimeout = 0;
|
||||||
|
ControlOption.TimeWaitTimeout = 0;
|
||||||
|
ControlOption.KeepAliveProbes = 4;
|
||||||
|
ControlOption.KeepAliveTime = 0;
|
||||||
|
ControlOption.KeepAliveInterval = 0;
|
||||||
|
ControlOption.EnableNagle = FALSE;
|
||||||
|
ControlOption.EnableTimeStamp = FALSE;
|
||||||
|
ControlOption.EnableWindowScaling = TRUE;
|
||||||
|
ControlOption.EnableSelectiveAck = FALSE;
|
||||||
|
ControlOption.EnablePathMtuDiscovery = FALSE;
|
||||||
|
|
||||||
|
Tcp4ConfigData.TypeOfService = 8;
|
||||||
|
Tcp4ConfigData.TimeToLive = 255;
|
||||||
|
Tcp4ConfigData.ControlOption = &ControlOption;
|
||||||
|
|
||||||
|
AccessPoint = &Tcp4ConfigData.AccessPoint;
|
||||||
|
|
||||||
|
AccessPoint->UseDefaultAddress = FALSE;
|
||||||
|
AccessPoint->StationPort = 0;
|
||||||
|
AccessPoint->RemotePort = ConfigData->RemotePort;
|
||||||
|
AccessPoint->ActiveFlag = TRUE;
|
||||||
|
|
||||||
|
NetCopyMem (&AccessPoint->StationAddress, &ConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
NetCopyMem (&AccessPoint->SubnetMask, &ConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
NetCopyMem (&AccessPoint->RemoteAddress, &ConfigData->RemoteIp, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure the TCP4 protocol.
|
||||||
|
//
|
||||||
|
Status = Tcp4->Configure (Tcp4, &Tcp4ConfigData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_IP4_EQUAL (&ConfigData->Gateway, &mZeroIp4Addr)) {
|
||||||
|
//
|
||||||
|
// the gateway is not zero, add the default route by hand
|
||||||
|
//
|
||||||
|
Status = Tcp4->Routes (Tcp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &ConfigData->Gateway);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Create events for variuos asynchronous operations.
|
||||||
|
//
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EFI_EVENT_NOTIFY_SIGNAL,
|
||||||
|
NET_TPL_EVENT,
|
||||||
|
Tcp4IoCommonNotify,
|
||||||
|
&Tcp4Io->IsConnDone,
|
||||||
|
&Tcp4Io->ConnToken.CompletionToken.Event
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EFI_EVENT_NOTIFY_SIGNAL,
|
||||||
|
NET_TPL_EVENT,
|
||||||
|
Tcp4IoCommonNotify,
|
||||||
|
&Tcp4Io->IsTxDone,
|
||||||
|
&Tcp4Io->TxToken.CompletionToken.Event
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EFI_EVENT_NOTIFY_SIGNAL,
|
||||||
|
NET_TPL_EVENT,
|
||||||
|
Tcp4IoCommonNotify,
|
||||||
|
&Tcp4Io->IsRxDone,
|
||||||
|
&Tcp4Io->RxToken.CompletionToken.Event
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EFI_EVENT_NOTIFY_SIGNAL,
|
||||||
|
NET_TPL_EVENT,
|
||||||
|
Tcp4IoCommonNotify,
|
||||||
|
&Tcp4Io->IsCloseDone,
|
||||||
|
&Tcp4Io->CloseToken.CompletionToken.Event
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcp4Io->IsTxDone = FALSE;
|
||||||
|
Tcp4Io->IsRxDone = FALSE;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
ON_ERROR:
|
||||||
|
|
||||||
|
if (Tcp4Io->RxToken.CompletionToken.Event != NULL) {
|
||||||
|
gBS->CloseEvent (Tcp4Io->RxToken.CompletionToken.Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tcp4Io->TxToken.CompletionToken.Event != NULL) {
|
||||||
|
gBS->CloseEvent (Tcp4Io->TxToken.CompletionToken.Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tcp4Io->ConnToken.CompletionToken.Event != NULL) {
|
||||||
|
gBS->CloseEvent (Tcp4Io->ConnToken.CompletionToken.Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tcp4 != NULL) {
|
||||||
|
Tcp4->Configure (Tcp4, NULL);
|
||||||
|
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Tcp4Io->Handle,
|
||||||
|
&gEfiTcp4ProtocolGuid,
|
||||||
|
Image,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetLibDestroyServiceChild (
|
||||||
|
Controller,
|
||||||
|
Image,
|
||||||
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
|
Tcp4Io->Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Tcp4IoDestroySocket (
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Destroy the socket.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Tcp4Io - The Tcp4Io which wraps the socket to be destroyeds.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
|
||||||
|
Tcp4->Configure (Tcp4, NULL);
|
||||||
|
|
||||||
|
gBS->CloseEvent (Tcp4Io->TxToken.CompletionToken.Event);
|
||||||
|
gBS->CloseEvent (Tcp4Io->RxToken.CompletionToken.Event);
|
||||||
|
gBS->CloseEvent (Tcp4Io->ConnToken.CompletionToken.Event);
|
||||||
|
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Tcp4Io->Handle,
|
||||||
|
&gEfiTcp4ProtocolGuid,
|
||||||
|
Tcp4Io->Image,
|
||||||
|
Tcp4Io->Controller
|
||||||
|
);
|
||||||
|
|
||||||
|
NetLibDestroyServiceChild (
|
||||||
|
Tcp4Io->Controller,
|
||||||
|
Tcp4Io->Image,
|
||||||
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
|
Tcp4Io->Handle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoConnect (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN EFI_EVENT Timeout
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Connect to the other endpoint of the TCP socket.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Tcp4Io - The Tcp4Io wrapping the TCP socket.
|
||||||
|
Timeout - The time to wait for connection done.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Tcp4Io->IsConnDone = FALSE;
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
Status = Tcp4->Connect (Tcp4, &Tcp4Io->ConnToken);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!Tcp4Io->IsConnDone && EFI_ERROR (gBS->CheckEvent (Timeout))) {
|
||||||
|
Tcp4->Poll (Tcp4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Tcp4Io->IsConnDone) {
|
||||||
|
Status = EFI_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
Status = Tcp4Io->ConnToken.CompletionToken.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Tcp4IoReset (
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Reset the socket.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Tcp4Io - The Tcp4Io wrapping the TCP socket.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
|
||||||
|
Tcp4Io->CloseToken.AbortOnClose = TRUE;
|
||||||
|
Tcp4Io->IsCloseDone = FALSE;
|
||||||
|
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
Status = Tcp4->Close (Tcp4, &Tcp4Io->CloseToken);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!Tcp4Io->IsCloseDone) {
|
||||||
|
Tcp4->Poll (Tcp4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoTransmit (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN NET_BUF *Packet
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Transmit the Packet to the other endpoint of the socket.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Tcp4Io - The Tcp4Io wrapping the TCP socket.
|
||||||
|
Packet - The packet to transmit
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The packet is trasmitted.
|
||||||
|
EFI_OUT_OF_RESOURCES - Failed to allocate memory.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_TCP4_TRANSMIT_DATA *TxData;
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
TxData = NetAllocatePool (sizeof (EFI_TCP4_TRANSMIT_DATA) + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA));
|
||||||
|
if (TxData == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
TxData->Push = TRUE;
|
||||||
|
TxData->Urgent = FALSE;
|
||||||
|
TxData->DataLength = Packet->TotalSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build the fragment table.
|
||||||
|
//
|
||||||
|
TxData->FragmentCount = Packet->BlockOpNum;
|
||||||
|
NetbufBuildExt (Packet, (NET_FRAGMENT *) &TxData->FragmentTable[0], &TxData->FragmentCount);
|
||||||
|
|
||||||
|
Tcp4Io->TxToken.Packet.TxData = TxData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trasnmit the packet.
|
||||||
|
//
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
Status = Tcp4->Transmit (Tcp4, &Tcp4Io->TxToken);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!Tcp4Io->IsTxDone) {
|
||||||
|
Tcp4->Poll (Tcp4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcp4Io->IsTxDone = FALSE;
|
||||||
|
|
||||||
|
Status = Tcp4Io->TxToken.CompletionToken.Status;
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
|
||||||
|
NetFreePool (TxData);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoReceive (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN NET_BUF *Packet,
|
||||||
|
IN BOOLEAN AsyncMode,
|
||||||
|
IN EFI_EVENT Timeout
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Receive data from the socket.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Tcp4Io - The Tcp4Io which wraps the socket to be destroyeds.
|
||||||
|
Packet - The buffer to hold the data copy from the soket rx buffer.
|
||||||
|
AsyncMode - Is this receive asyncronous or not.
|
||||||
|
Timeout - The time to wait for receiving the amount of data the Packet
|
||||||
|
can hold.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - The required amount of data is received from the socket.
|
||||||
|
EFI_OUT_OF_RESOURCES - Failed to allocate momery.
|
||||||
|
EFI_TIMEOUT - Failed to receive the required amount of data in the
|
||||||
|
specified time period.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
EFI_TCP4_RECEIVE_DATA RxData;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
NET_FRAGMENT *Fragment;
|
||||||
|
UINT32 FragmentCount;
|
||||||
|
UINT32 CurrentFragment;
|
||||||
|
|
||||||
|
FragmentCount = Packet->BlockOpNum;
|
||||||
|
Fragment = NetAllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
|
||||||
|
if (Fragment == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Build the fragment table.
|
||||||
|
//
|
||||||
|
NetbufBuildExt (Packet, Fragment, &FragmentCount);
|
||||||
|
|
||||||
|
RxData.FragmentCount = 1;
|
||||||
|
Tcp4Io->RxToken.Packet.RxData = &RxData;
|
||||||
|
CurrentFragment = 0;
|
||||||
|
Tcp4 = Tcp4Io->Tcp4;
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
while (CurrentFragment < FragmentCount) {
|
||||||
|
RxData.DataLength = Fragment[CurrentFragment].Len;
|
||||||
|
RxData.FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
|
||||||
|
RxData.FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
|
||||||
|
|
||||||
|
Status = Tcp4->Receive (Tcp4, &Tcp4Io->RxToken);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!Tcp4Io->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
|
||||||
|
//
|
||||||
|
// Poll until some data is received or something error happens.
|
||||||
|
//
|
||||||
|
Tcp4->Poll (Tcp4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Tcp4Io->IsRxDone) {
|
||||||
|
//
|
||||||
|
// Timeout occurs, cancel the receive request.
|
||||||
|
//
|
||||||
|
Tcp4->Cancel (Tcp4, &Tcp4Io->RxToken.CompletionToken);
|
||||||
|
|
||||||
|
Status = EFI_TIMEOUT;
|
||||||
|
goto ON_EXIT;
|
||||||
|
} else {
|
||||||
|
Tcp4Io->IsRxDone = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Tcp4Io->RxToken.CompletionToken.Status)) {
|
||||||
|
Status = Tcp4Io->RxToken.CompletionToken.Status;
|
||||||
|
goto ON_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fragment[CurrentFragment].Len -= RxData.FragmentTable[0].FragmentLength;
|
||||||
|
if (Fragment[CurrentFragment].Len == 0) {
|
||||||
|
CurrentFragment++;
|
||||||
|
} else {
|
||||||
|
Fragment[CurrentFragment].Bulk += RxData.FragmentTable[0].FragmentLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_EXIT:
|
||||||
|
|
||||||
|
NetFreePool (Fragment);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
93
MdeModulePkg/Universal/iScsi/IScsiTcp4Io.h
Normal file
93
MdeModulePkg/Universal/iScsi/IScsiTcp4Io.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
IScsiTcp4Io.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
iSCSI Tcp4 IO related definitions.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _ISCSI_TCP4_IO_H_
|
||||||
|
#define _ISCSI_TCP4_IO_H_
|
||||||
|
|
||||||
|
#include <Library/NetLib.h>
|
||||||
|
#include <protocol/Tcp4.h>
|
||||||
|
|
||||||
|
typedef struct _TCP4_IO_CONFIG_DATA {
|
||||||
|
EFI_IPv4_ADDRESS LocalIp;
|
||||||
|
EFI_IPv4_ADDRESS SubnetMask;
|
||||||
|
EFI_IPv4_ADDRESS Gateway;
|
||||||
|
|
||||||
|
EFI_IPv4_ADDRESS RemoteIp;
|
||||||
|
UINT16 RemotePort;
|
||||||
|
} TCP4_IO_CONFIG_DATA;
|
||||||
|
|
||||||
|
typedef struct _TCP4_IO {
|
||||||
|
EFI_HANDLE Image;
|
||||||
|
EFI_HANDLE Controller;
|
||||||
|
|
||||||
|
EFI_HANDLE Handle;
|
||||||
|
EFI_TCP4_PROTOCOL *Tcp4;
|
||||||
|
|
||||||
|
EFI_TCP4_CONNECTION_TOKEN ConnToken;
|
||||||
|
EFI_TCP4_IO_TOKEN TxToken;
|
||||||
|
EFI_TCP4_IO_TOKEN RxToken;
|
||||||
|
EFI_TCP4_CLOSE_TOKEN CloseToken;
|
||||||
|
|
||||||
|
BOOLEAN IsConnDone;
|
||||||
|
BOOLEAN IsTxDone;
|
||||||
|
BOOLEAN IsRxDone;
|
||||||
|
BOOLEAN IsCloseDone;
|
||||||
|
} TCP4_IO;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoCreateSocket (
|
||||||
|
IN EFI_HANDLE Image,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN TCP4_IO_CONFIG_DATA *ConfigData,
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Tcp4IoDestroySocket (
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoConnect (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN EFI_EVENT Timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
Tcp4IoReset (
|
||||||
|
IN TCP4_IO *Tcp4Io
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoTransmit (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN NET_BUF *Packet
|
||||||
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
Tcp4IoReceive (
|
||||||
|
IN TCP4_IO *Tcp4Io,
|
||||||
|
IN NET_BUF *Packet,
|
||||||
|
IN BOOLEAN AsyncMode,
|
||||||
|
IN EFI_EVENT Timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
335
MdeModulePkg/Universal/iScsi/Md5.c
Normal file
335
MdeModulePkg/Universal/iScsi/Md5.c
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Md5.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Implementation of MD5 algorithm
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "Md5.h"
|
||||||
|
|
||||||
|
STATIC CONST UINT32 MD5_K[][2] = {
|
||||||
|
{ 0, 1 },
|
||||||
|
{ 1, 5 },
|
||||||
|
{ 5, 3 },
|
||||||
|
{ 0, 7 }
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC CONST UINT32 MD5_S[][4] = {
|
||||||
|
{ 7, 22, 17, 12 },
|
||||||
|
{ 5, 20, 14, 9 },
|
||||||
|
{ 4, 23, 16 ,11 },
|
||||||
|
{ 6, 21, 15, 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC CONST UINT32 MD5_T[] = {
|
||||||
|
0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,
|
||||||
|
0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
|
||||||
|
0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,
|
||||||
|
0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
|
||||||
|
0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
|
||||||
|
0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
|
||||||
|
0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,
|
||||||
|
0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
|
||||||
|
0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,
|
||||||
|
0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
|
||||||
|
0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,
|
||||||
|
0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
|
||||||
|
0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,
|
||||||
|
0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
|
||||||
|
0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
|
||||||
|
0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC CONST UINT8 Md5HashPadding[] =
|
||||||
|
{
|
||||||
|
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// ROTATE_LEFT rotates x left n bits.
|
||||||
|
//
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
|
|
||||||
|
#define SA S[j & 3]
|
||||||
|
#define SB S[(j + 1) & 3]
|
||||||
|
#define SC S[(j + 2) & 3]
|
||||||
|
#define SD S[(j + 3) & 3]
|
||||||
|
|
||||||
|
//
|
||||||
|
// TF1, TF2, TF3, TF4 are basic MD5 transform functions
|
||||||
|
//
|
||||||
|
UINT32 TF1 (UINT32 A, UINT32 B, UINT32 C)
|
||||||
|
{
|
||||||
|
return (A & B) | (~A & C);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 TF2 (UINT32 A, UINT32 B, UINT32 C)
|
||||||
|
{
|
||||||
|
return (A & C) | (B & ~C);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 TF3 (UINT32 A, UINT32 B, UINT32 C)
|
||||||
|
{
|
||||||
|
return A ^ B ^ C;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 TF4 (UINT32 A, UINT32 B, UINT32 C)
|
||||||
|
{
|
||||||
|
return B ^ (A | ~C);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef
|
||||||
|
UINT32
|
||||||
|
(*MD5_TRANSFORM_FUNC) (
|
||||||
|
IN UINT32 A,
|
||||||
|
IN UINT32 B,
|
||||||
|
IN UINT32 C
|
||||||
|
);
|
||||||
|
|
||||||
|
STATIC CONST MD5_TRANSFORM_FUNC MD5_F[] = {
|
||||||
|
TF1,
|
||||||
|
TF2,
|
||||||
|
TF3,
|
||||||
|
TF4
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
MD5Transform (
|
||||||
|
IN MD5_CTX *Md5Ctx
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINT32 i;
|
||||||
|
UINT32 j;
|
||||||
|
UINT32 S[MD5_HASHSIZE >> 2];
|
||||||
|
UINT32 *X;
|
||||||
|
UINT32 k;
|
||||||
|
UINT32 t;
|
||||||
|
|
||||||
|
X = (UINT32 *) Md5Ctx->M;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy MD5 states to S
|
||||||
|
//
|
||||||
|
NetCopyMem (S, Md5Ctx->States, MD5_HASHSIZE);
|
||||||
|
|
||||||
|
t = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
k = MD5_K[i][0];
|
||||||
|
for (j = 16; j > 0; j--) {
|
||||||
|
SA += (*MD5_F[i]) (SB, SC, SD) + X[k] + MD5_T[t];
|
||||||
|
SA = ROTATE_LEFT (SA, MD5_S[i][j & 3]);
|
||||||
|
SA += SB;
|
||||||
|
|
||||||
|
k += MD5_K[i][1];
|
||||||
|
k &= 15;
|
||||||
|
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
Md5Ctx->States[i] += S[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
MD5UpdateBlock (
|
||||||
|
IN MD5_CTX *Md5Ctx,
|
||||||
|
IN CONST UINT8 *Data,
|
||||||
|
IN UINTN DataLen
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
Data - GC_TODO: add argument description
|
||||||
|
DataLen - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
GC_TODO: add return values
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN Limit;
|
||||||
|
|
||||||
|
for (Limit = 64 - Md5Ctx->Count; DataLen >= 64 - Md5Ctx->Count; Limit = 64) {
|
||||||
|
NetCopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, Limit);
|
||||||
|
MD5Transform (Md5Ctx);
|
||||||
|
|
||||||
|
Md5Ctx->Count = 0;
|
||||||
|
Data += Limit;
|
||||||
|
DataLen -= Limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetCopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, DataLen);
|
||||||
|
Md5Ctx->Count += DataLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Init (
|
||||||
|
IN MD5_CTX *Md5Ctx
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
NetZeroMem (Md5Ctx, sizeof (*Md5Ctx));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set magic initialization constants.
|
||||||
|
//
|
||||||
|
Md5Ctx->States[0] = 0x67452301;
|
||||||
|
Md5Ctx->States[1] = 0xefcdab89;
|
||||||
|
Md5Ctx->States[2] = 0x98badcfe;
|
||||||
|
Md5Ctx->States[3] = 0x10325476;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Update (
|
||||||
|
IN MD5_CTX *Md5Ctx,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataLen
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
Data - GC_TODO: add argument description
|
||||||
|
DataLen - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
if (EFI_ERROR (Md5Ctx->Status)) {
|
||||||
|
return Md5Ctx->Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) Data, DataLen);
|
||||||
|
Md5Ctx->Length += DataLen;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Final (
|
||||||
|
IN MD5_CTX *Md5Ctx,
|
||||||
|
OUT UINT8 *HashVal
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
HashVal - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
UINTN PadLength;
|
||||||
|
|
||||||
|
if (Md5Ctx->Status == EFI_ALREADY_STARTED) {
|
||||||
|
//
|
||||||
|
// Store Hashed value & Zeroize sensitive context information.
|
||||||
|
//
|
||||||
|
NetCopyMem (HashVal, (UINT8 *) Md5Ctx->States, MD5_HASHSIZE);
|
||||||
|
NetZeroMem ((UINT8 *)Md5Ctx, sizeof (*Md5Ctx));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Md5Ctx->Status)) {
|
||||||
|
return Md5Ctx->Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
PadLength = Md5Ctx->Count >= 56 ? 120 : 56;
|
||||||
|
PadLength -= Md5Ctx->Count;
|
||||||
|
MD5UpdateBlock (Md5Ctx, Md5HashPadding, PadLength);
|
||||||
|
Md5Ctx->Length = LShiftU64 (Md5Ctx->Length, 3);
|
||||||
|
MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) &Md5Ctx->Length, 8);
|
||||||
|
|
||||||
|
NetZeroMem (Md5Ctx->M, sizeof (Md5Ctx->M));
|
||||||
|
Md5Ctx->Length = 0;
|
||||||
|
Md5Ctx->Status = EFI_ALREADY_STARTED;
|
||||||
|
return MD5Final (Md5Ctx, HashVal);
|
||||||
|
}
|
||||||
|
|
108
MdeModulePkg/Universal/iScsi/Md5.h
Normal file
108
MdeModulePkg/Universal/iScsi/Md5.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2007 Intel Corporation. All rights reserved
|
||||||
|
This software and associated documentation (if any) is furnished
|
||||||
|
under a license and may only be used or copied in accordance
|
||||||
|
with the terms of the license. Except as permitted by such
|
||||||
|
license, no part of this software or documentation may be
|
||||||
|
reproduced, stored in a retrieval system, or transmitted in any
|
||||||
|
form or by any means without the express written consent of
|
||||||
|
Intel Corporation.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
Md5.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Header file for Md5
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _MD5_H_
|
||||||
|
#define _MD5_H_
|
||||||
|
|
||||||
|
#include <uefi/UefiBaseType.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/NetLib.h>
|
||||||
|
|
||||||
|
#define MD5_HASHSIZE 16
|
||||||
|
|
||||||
|
typedef struct _MD5_CTX {
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 Length;
|
||||||
|
UINT32 States[MD5_HASHSIZE / sizeof (UINT32)];
|
||||||
|
UINT8 M[64];
|
||||||
|
UINTN Count;
|
||||||
|
} MD5_CTX;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Init (
|
||||||
|
IN MD5_CTX *Md5Ctx
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Update (
|
||||||
|
IN MD5_CTX *Md5Ctx,
|
||||||
|
IN VOID *Data,
|
||||||
|
IN UINTN DataLen
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
Data - GC_TODO: add argument description
|
||||||
|
DataLen - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
MD5Final (
|
||||||
|
IN MD5_CTX *Md5Ctx,
|
||||||
|
OUT UINT8 *HashVal
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
GC_TODO: Add function description
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Md5Ctx - GC_TODO: add argument description
|
||||||
|
HashVal - GC_TODO: add argument description
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - GC_TODO: Add description for return value
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif // _MD5_H
|
Reference in New Issue
Block a user