Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*******************************************************************************
*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 */