mirror of https://github.com/acidanthera/audk.git
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:
parent
e3b1115ed8
commit
6a690e23d7
|
@ -24,6 +24,8 @@ Abstract:
|
|||
#define _NET_LIB_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ComponentName.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_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.
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
|
||||
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
|
||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||
FrameworkIfrSupportLib|IntelFrameworkPkg/Library/FrameworkIfrSupportLib/IfrSupportLib.inf
|
||||
|
||||
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
|
||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||
|
@ -257,6 +258,8 @@
|
|||
MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf
|
||||
MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf
|
||||
|
||||
MdeModulePkg/Universal/iScsi/IScsi.inf
|
||||
|
||||
MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
|
||||
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
|
||||
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||
|
Binary file not shown.
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue