mirror of
https://github.com/opnsense/src.git
synced 2026-04-25 08:07:28 -04:00
304 lines
10 KiB
C
304 lines
10 KiB
C
/*******************************************************************************
|
|
*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
|
|
*
|
|
*Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
|
*that the following conditions are met:
|
|
*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
|
*following disclaimer.
|
|
*2. Redistributions in binary form must reproduce the above copyright notice,
|
|
*this list of conditions and the following disclaimer in the documentation and/or other materials provided
|
|
*with the distribution.
|
|
*
|
|
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
|
|
********************************************************************************/
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
#include <dev/pms/config.h>
|
|
|
|
#include <dev/pms/freebsd/driver/common/osenv.h>
|
|
#include <dev/pms/freebsd/driver/common/ostypes.h>
|
|
#include <dev/pms/freebsd/driver/common/osdebug.h>
|
|
|
|
#include <dev/pms/RefTisa/sallsdk/api/sa.h>
|
|
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
|
|
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
|
|
|
|
#ifdef FDS_DM
|
|
#include <dev/pms/RefTisa/discovery/api/dm.h>
|
|
#include <dev/pms/RefTisa/discovery/api/dmapi.h>
|
|
#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
|
|
|
|
#include <dev/pms/RefTisa/discovery/dm/dmdefs.h>
|
|
#include <dev/pms/RefTisa/discovery/dm/dmtypes.h>
|
|
#include <dev/pms/RefTisa/discovery/dm/dmproto.h>
|
|
|
|
/*****************************************************************************/
|
|
/*! \brief dmCreatePort
|
|
*
|
|
*
|
|
* Purpose: A port context is created by this function
|
|
*
|
|
* \param dmRoot: DM context handle.
|
|
* \param dmPortContext: Pointer to this instance of port context
|
|
*
|
|
* \return:
|
|
* DM_RC_SUCCESS
|
|
* DM_RC_FAILURE
|
|
*
|
|
*/
|
|
/*****************************************************************************/
|
|
osGLOBAL bit32
|
|
dmCreatePort(
|
|
dmRoot_t *dmRoot,
|
|
dmPortContext_t *dmPortContext,
|
|
dmPortInfo_t *dmPortInfo)
|
|
{
|
|
dmIntRoot_t *dmIntRoot = agNULL;
|
|
dmIntContext_t *dmAllShared = agNULL;
|
|
dmIntPortContext_t *onePortContext = agNULL;
|
|
dmList_t *PortContextList = agNULL;
|
|
|
|
DM_DBG3(("dmCreatePort: start\n"));
|
|
|
|
if (dmRoot == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmRoot is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
if (dmPortContext == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmPortContext is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
/* the duplicacy of a port is checked */
|
|
if (dmPortContext->dmData != agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmPortContext->dmData is not NULL, wrong, Already created!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
if (dmPortInfo == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmPortInfo is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
dmIntRoot = (dmIntRoot_t *)dmRoot->dmData;
|
|
|
|
if (dmIntRoot == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmIntRoot is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
|
|
|
|
if (dmAllShared == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: dmAllShared is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
|
|
if (DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList)))
|
|
{
|
|
DMLIST_DEQUEUE_FROM_HEAD(&PortContextList, &(dmAllShared->FreePortContextList));
|
|
tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
|
|
onePortContext = DMLIST_OBJECT_BASE(dmIntPortContext_t, FreeLink, PortContextList);
|
|
if (onePortContext == agNULL)
|
|
{
|
|
DM_DBG1(("dmCreatePort: onePortContext is NULL in allocation, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
dmPortContext->dmData = onePortContext;
|
|
onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED;
|
|
onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_FULL_START;
|
|
|
|
onePortContext->dmRoot = dmRoot;
|
|
onePortContext->dmPortContext = dmPortContext;
|
|
onePortContext->valid = agTRUE;
|
|
onePortContext->RegFailed = agFALSE;
|
|
|
|
onePortContext->LinkRate = DM_GET_LINK_RATE(dmPortInfo->flag);
|
|
DM_DBG3(("dmCreatePort: linkrate %0x\n", onePortContext->LinkRate));
|
|
|
|
onePortContext->sasRemoteAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasRemoteAddressHi);
|
|
onePortContext->sasRemoteAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasRemoteAddressLo);
|
|
onePortContext->sasLocalAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasLocalAddressHi);
|
|
onePortContext->sasLocalAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasLocalAddressLo);
|
|
DM_DBG3(("dmCreatePort: pid %d\n", onePortContext->id));
|
|
DM_DBG3(("dmCreatePort: RemoteAddrHi 0x%08x RemoteAddrLo 0x%08x\n", onePortContext->sasRemoteAddressHi, onePortContext->sasRemoteAddressLo));
|
|
DM_DBG3(("dmCreatePort: LocalAddrHi 0x%08x LocaAddrLo 0x%08x\n", onePortContext->sasLocalAddressHi, onePortContext->sasLocalAddressLo));
|
|
|
|
tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
|
|
DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->MainLink), &(dmAllShared->MainPortContextList));
|
|
tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
|
|
}
|
|
else
|
|
{
|
|
tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
|
|
DM_DBG1(("dmCreatePort: Attention. no more free PortContext!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
return DM_RC_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*! \brief dmDestroyPort
|
|
*
|
|
*
|
|
* Purpose: A port context is destroyed by this function
|
|
*
|
|
* \param dmRoot: DM context handle.
|
|
* \param dmPortContext: Pointer to this instance of port context
|
|
*
|
|
* \return:
|
|
* DM_RC_SUCCESS
|
|
* DM_RC_FAILURE
|
|
*
|
|
*/
|
|
/*****************************************************************************/
|
|
osGLOBAL bit32
|
|
dmDestroyPort(
|
|
dmRoot_t *dmRoot,
|
|
dmPortContext_t *dmPortContext,
|
|
dmPortInfo_t *dmPortInfo)
|
|
{
|
|
dmIntRoot_t *dmIntRoot = agNULL;
|
|
dmIntContext_t *dmAllShared = agNULL;
|
|
dmIntPortContext_t *onePortContext = agNULL;
|
|
|
|
DM_DBG1(("dmDestroyPort: start\n"));
|
|
if (dmRoot == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: dmRoot is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
if (dmPortContext == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: dmPortContext is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
if (dmPortInfo == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: dmPortInfo is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
dmIntRoot = (dmIntRoot_t *)dmRoot->dmData;
|
|
|
|
if (dmIntRoot == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: dmIntRoot is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
|
|
|
|
if (dmAllShared == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: dmAllShared is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
/*
|
|
no device(expander) to be removed since all devices should
|
|
be in freelist at the end of discovery
|
|
But if the discovery is in progress, abort it and clean up
|
|
*/
|
|
onePortContext = (dmIntPortContext_t *)dmPortContext->dmData;
|
|
|
|
if (onePortContext == agNULL)
|
|
{
|
|
DM_DBG1(("dmDestroyPort: onePortContext is NULL, wrong!!!\n"));
|
|
return DM_RC_FAILURE;
|
|
}
|
|
|
|
#if 1
|
|
if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED)
|
|
{
|
|
dmDiscoverAbort(dmRoot, onePortContext);
|
|
}
|
|
else
|
|
{
|
|
/* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList; dmDiscoveryDeviceCleanUp()
|
|
move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList; dmDiscoveryExpanderCleanUp()
|
|
*/
|
|
}
|
|
#endif
|
|
|
|
if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED)
|
|
{
|
|
/* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList
|
|
move from dmAllShared->UpdiscoveringExpanderList to dmAllShared->mainExpanderList
|
|
*/
|
|
dmCleanAllExp(dmRoot, onePortContext);
|
|
}
|
|
|
|
/* move mainExpanderList then MainDeviceList */
|
|
DM_DBG3(("dmDestroyPort: before dmDiscoveryExpanderCleanUp\n"));
|
|
dmDumpAllMainExp(dmRoot, onePortContext);
|
|
|
|
/* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */
|
|
dmDiscoveryExpanderCleanUp(dmRoot, onePortContext);
|
|
|
|
DM_DBG3(("dmDestroyPort: after dmDiscoveryExpanderCleanUp\n"));
|
|
dmDumpAllMainExp(dmRoot, onePortContext);
|
|
|
|
DM_DBG3(("dmDestroyPort: before dmDiscoveryDeviceCleanUp\n"));
|
|
dmDumpAllMainDevice(dmRoot, onePortContext);
|
|
/* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */
|
|
dmDiscoveryDeviceCleanUp(dmRoot, onePortContext);
|
|
|
|
DM_DBG3(("dmDestroyPort: after dmDiscoveryDeviceCleanUp\n"));
|
|
dmDumpAllMainDevice(dmRoot, onePortContext);
|
|
|
|
dmPortContextReInit(dmRoot, onePortContext);
|
|
|
|
tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
|
|
|
|
if (DMLIST_NOT_EMPTY(&(onePortContext->MainLink)))
|
|
{
|
|
DMLIST_DEQUEUE_THIS(&(onePortContext->MainLink));
|
|
}
|
|
else
|
|
{
|
|
DM_DBG1(("dmDestroyPort: onePortContext->MainLink is NULL, wrong!!!\n"));
|
|
}
|
|
|
|
if (DMLIST_NOT_EMPTY(&(onePortContext->FreeLink)) && DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList)))
|
|
{
|
|
DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(dmAllShared->FreePortContextList));
|
|
}
|
|
else
|
|
{
|
|
DM_DBG1(("dmDestroyPort: onePortContext->FreeLink or dmAllShared->FreePortContextList is NULL, wrong!!!\n"));
|
|
}
|
|
|
|
tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
|
|
|
|
return DM_RC_SUCCESS;
|
|
}
|
|
#endif /* FDS_ DM */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|