1285809Sscottl/******************************************************************************* 2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285809Sscottl* 4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285809Sscottl*that the following conditions are met: 6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285809Sscottl*following disclaimer. 8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285809Sscottl*with the distribution. 11285809Sscottl* 12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285809Sscottl 21285809Sscottl********************************************************************************/ 22285809Sscottl#include <sys/cdefs.h> 23285809Sscottl__FBSDID("$FreeBSD$"); 24285809Sscottl#include <dev/pms/config.h> 25285809Sscottl 26285809Sscottl#include <dev/pms/freebsd/driver/common/osenv.h> 27285809Sscottl#include <dev/pms/freebsd/driver/common/ostypes.h> 28285809Sscottl#include <dev/pms/freebsd/driver/common/osdebug.h> 29285809Sscottl 30285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/sa.h> 31285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 32285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 33285809Sscottl 34285809Sscottl#ifdef FDS_DM 35285809Sscottl#include <dev/pms/RefTisa/discovery/api/dm.h> 36285809Sscottl#include <dev/pms/RefTisa/discovery/api/dmapi.h> 37285809Sscottl#include <dev/pms/RefTisa/discovery/api/tddmapi.h> 38285809Sscottl 39285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 40285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 41285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmproto.h> 42285809Sscottl 43285809Sscottl/*****************************************************************************/ 44285809Sscottl/*! \brief dmCreatePort 45285809Sscottl * 46285809Sscottl * 47285809Sscottl * Purpose: A port context is created by this function 48285809Sscottl * 49285809Sscottl * \param dmRoot: DM context handle. 50285809Sscottl * \param dmPortContext: Pointer to this instance of port context 51285809Sscottl * 52285809Sscottl * \return: 53285809Sscottl * DM_RC_SUCCESS 54285809Sscottl * DM_RC_FAILURE 55285809Sscottl * 56285809Sscottl */ 57285809Sscottl/*****************************************************************************/ 58285809SscottlosGLOBAL bit32 59285809SscottldmCreatePort( 60285809Sscottl dmRoot_t *dmRoot, 61285809Sscottl dmPortContext_t *dmPortContext, 62285809Sscottl dmPortInfo_t *dmPortInfo) 63285809Sscottl{ 64285809Sscottl dmIntRoot_t *dmIntRoot = agNULL; 65285809Sscottl dmIntContext_t *dmAllShared = agNULL; 66285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 67285809Sscottl dmList_t *PortContextList = agNULL; 68285809Sscottl 69285809Sscottl DM_DBG3(("dmCreatePort: start\n")); 70285809Sscottl 71285809Sscottl if (dmRoot == agNULL) 72285809Sscottl { 73285809Sscottl DM_DBG1(("dmCreatePort: dmRoot is NULL, wrong!!!\n")); 74285809Sscottl return DM_RC_FAILURE; 75285809Sscottl } 76285809Sscottl 77285809Sscottl if (dmPortContext == agNULL) 78285809Sscottl { 79285809Sscottl DM_DBG1(("dmCreatePort: dmPortContext is NULL, wrong!!!\n")); 80285809Sscottl return DM_RC_FAILURE; 81285809Sscottl } 82285809Sscottl 83285809Sscottl /* the duplicacy of a port is checked */ 84285809Sscottl if (dmPortContext->dmData != agNULL) 85285809Sscottl { 86285809Sscottl DM_DBG1(("dmCreatePort: dmPortContext->dmData is not NULL, wrong, Already created!!!\n")); 87285809Sscottl return DM_RC_FAILURE; 88285809Sscottl } 89285809Sscottl 90285809Sscottl if (dmPortInfo == agNULL) 91285809Sscottl { 92285809Sscottl DM_DBG1(("dmCreatePort: dmPortInfo is NULL, wrong!!!\n")); 93285809Sscottl return DM_RC_FAILURE; 94285809Sscottl } 95285809Sscottl 96285809Sscottl dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 97285809Sscottl 98285809Sscottl if (dmIntRoot == agNULL) 99285809Sscottl { 100285809Sscottl DM_DBG1(("dmCreatePort: dmIntRoot is NULL, wrong!!!\n")); 101285809Sscottl return DM_RC_FAILURE; 102285809Sscottl } 103285809Sscottl 104285809Sscottl dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 105285809Sscottl 106285809Sscottl if (dmAllShared == agNULL) 107285809Sscottl { 108285809Sscottl DM_DBG1(("dmCreatePort: dmAllShared is NULL, wrong!!!\n")); 109285809Sscottl return DM_RC_FAILURE; 110285809Sscottl } 111285809Sscottl 112285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 113285809Sscottl if (DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList))) 114285809Sscottl { 115285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&PortContextList, &(dmAllShared->FreePortContextList)); 116285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 117285809Sscottl onePortContext = DMLIST_OBJECT_BASE(dmIntPortContext_t, FreeLink, PortContextList); 118285809Sscottl if (onePortContext == agNULL) 119285809Sscottl { 120285809Sscottl DM_DBG1(("dmCreatePort: onePortContext is NULL in allocation, wrong!!!\n")); 121285809Sscottl return DM_RC_FAILURE; 122285809Sscottl } 123285809Sscottl 124285809Sscottl dmPortContext->dmData = onePortContext; 125285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 126285809Sscottl onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_FULL_START; 127285809Sscottl 128285809Sscottl onePortContext->dmRoot = dmRoot; 129285809Sscottl onePortContext->dmPortContext = dmPortContext; 130285809Sscottl onePortContext->valid = agTRUE; 131285809Sscottl onePortContext->RegFailed = agFALSE; 132285809Sscottl 133285809Sscottl onePortContext->LinkRate = DM_GET_LINK_RATE(dmPortInfo->flag); 134285809Sscottl DM_DBG3(("dmCreatePort: linkrate %0x\n", onePortContext->LinkRate)); 135285809Sscottl 136285809Sscottl onePortContext->sasRemoteAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasRemoteAddressHi); 137285809Sscottl onePortContext->sasRemoteAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasRemoteAddressLo); 138285809Sscottl onePortContext->sasLocalAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasLocalAddressHi); 139285809Sscottl onePortContext->sasLocalAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasLocalAddressLo); 140285809Sscottl DM_DBG3(("dmCreatePort: pid %d\n", onePortContext->id)); 141285809Sscottl DM_DBG3(("dmCreatePort: RemoteAddrHi 0x%08x RemoteAddrLo 0x%08x\n", onePortContext->sasRemoteAddressHi, onePortContext->sasRemoteAddressLo)); 142285809Sscottl DM_DBG3(("dmCreatePort: LocalAddrHi 0x%08x LocaAddrLo 0x%08x\n", onePortContext->sasLocalAddressHi, onePortContext->sasLocalAddressLo)); 143285809Sscottl 144285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 145285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->MainLink), &(dmAllShared->MainPortContextList)); 146285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 147285809Sscottl } 148285809Sscottl else 149285809Sscottl { 150285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 151285809Sscottl DM_DBG1(("dmCreatePort: Attention. no more free PortContext!!!\n")); 152285809Sscottl return DM_RC_FAILURE; 153285809Sscottl } 154285809Sscottl 155285809Sscottl return DM_RC_SUCCESS; 156285809Sscottl} 157285809Sscottl 158285809Sscottl/*****************************************************************************/ 159285809Sscottl/*! \brief dmDestroyPort 160285809Sscottl * 161285809Sscottl * 162285809Sscottl * Purpose: A port context is destroyed by this function 163285809Sscottl * 164285809Sscottl * \param dmRoot: DM context handle. 165285809Sscottl * \param dmPortContext: Pointer to this instance of port context 166285809Sscottl * 167285809Sscottl * \return: 168285809Sscottl * DM_RC_SUCCESS 169285809Sscottl * DM_RC_FAILURE 170285809Sscottl * 171285809Sscottl */ 172285809Sscottl/*****************************************************************************/ 173285809SscottlosGLOBAL bit32 174285809SscottldmDestroyPort( 175285809Sscottl dmRoot_t *dmRoot, 176285809Sscottl dmPortContext_t *dmPortContext, 177285809Sscottl dmPortInfo_t *dmPortInfo) 178285809Sscottl{ 179285809Sscottl dmIntRoot_t *dmIntRoot = agNULL; 180285809Sscottl dmIntContext_t *dmAllShared = agNULL; 181285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 182285809Sscottl 183285809Sscottl DM_DBG1(("dmDestroyPort: start\n")); 184285809Sscottl if (dmRoot == agNULL) 185285809Sscottl { 186285809Sscottl DM_DBG1(("dmDestroyPort: dmRoot is NULL, wrong!!!\n")); 187285809Sscottl return DM_RC_FAILURE; 188285809Sscottl } 189285809Sscottl 190285809Sscottl if (dmPortContext == agNULL) 191285809Sscottl { 192285809Sscottl DM_DBG1(("dmDestroyPort: dmPortContext is NULL, wrong!!!\n")); 193285809Sscottl return DM_RC_FAILURE; 194285809Sscottl } 195285809Sscottl 196285809Sscottl if (dmPortInfo == agNULL) 197285809Sscottl { 198285809Sscottl DM_DBG1(("dmDestroyPort: dmPortInfo is NULL, wrong!!!\n")); 199285809Sscottl return DM_RC_FAILURE; 200285809Sscottl } 201285809Sscottl 202285809Sscottl dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 203285809Sscottl 204285809Sscottl if (dmIntRoot == agNULL) 205285809Sscottl { 206285809Sscottl DM_DBG1(("dmDestroyPort: dmIntRoot is NULL, wrong!!!\n")); 207285809Sscottl return DM_RC_FAILURE; 208285809Sscottl } 209285809Sscottl 210285809Sscottl dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 211285809Sscottl 212285809Sscottl if (dmAllShared == agNULL) 213285809Sscottl { 214285809Sscottl DM_DBG1(("dmDestroyPort: dmAllShared is NULL, wrong!!!\n")); 215285809Sscottl return DM_RC_FAILURE; 216285809Sscottl } 217285809Sscottl 218285809Sscottl /* 219285809Sscottl no device(expander) to be removed since all devices should 220285809Sscottl be in freelist at the end of discovery 221285809Sscottl But if the discovery is in progress, abort it and clean up 222285809Sscottl */ 223285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 224285809Sscottl 225285809Sscottl if (onePortContext == agNULL) 226285809Sscottl { 227285809Sscottl DM_DBG1(("dmDestroyPort: onePortContext is NULL, wrong!!!\n")); 228285809Sscottl return DM_RC_FAILURE; 229285809Sscottl } 230285809Sscottl 231285809Sscottl#if 1 232285809Sscottl if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 233285809Sscottl { 234285809Sscottl dmDiscoverAbort(dmRoot, onePortContext); 235285809Sscottl } 236285809Sscottl else 237285809Sscottl { 238285809Sscottl /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList; dmDiscoveryDeviceCleanUp() 239285809Sscottl move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList; dmDiscoveryExpanderCleanUp() 240285809Sscottl */ 241285809Sscottl } 242285809Sscottl#endif 243285809Sscottl 244285809Sscottl if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 245285809Sscottl { 246285809Sscottl /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList 247285809Sscottl move from dmAllShared->UpdiscoveringExpanderList to dmAllShared->mainExpanderList 248285809Sscottl */ 249285809Sscottl dmCleanAllExp(dmRoot, onePortContext); 250285809Sscottl } 251285809Sscottl 252285809Sscottl /* move mainExpanderList then MainDeviceList */ 253285809Sscottl DM_DBG3(("dmDestroyPort: before dmDiscoveryExpanderCleanUp\n")); 254285809Sscottl dmDumpAllMainExp(dmRoot, onePortContext); 255285809Sscottl 256285809Sscottl /* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */ 257285809Sscottl dmDiscoveryExpanderCleanUp(dmRoot, onePortContext); 258285809Sscottl 259285809Sscottl DM_DBG3(("dmDestroyPort: after dmDiscoveryExpanderCleanUp\n")); 260285809Sscottl dmDumpAllMainExp(dmRoot, onePortContext); 261285809Sscottl 262285809Sscottl DM_DBG3(("dmDestroyPort: before dmDiscoveryDeviceCleanUp\n")); 263285809Sscottl dmDumpAllMainDevice(dmRoot, onePortContext); 264285809Sscottl /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */ 265285809Sscottl dmDiscoveryDeviceCleanUp(dmRoot, onePortContext); 266285809Sscottl 267285809Sscottl DM_DBG3(("dmDestroyPort: after dmDiscoveryDeviceCleanUp\n")); 268285809Sscottl dmDumpAllMainDevice(dmRoot, onePortContext); 269285809Sscottl 270285809Sscottl dmPortContextReInit(dmRoot, onePortContext); 271285809Sscottl 272285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 273285809Sscottl 274285809Sscottl if (DMLIST_NOT_EMPTY(&(onePortContext->MainLink))) 275285809Sscottl { 276285809Sscottl DMLIST_DEQUEUE_THIS(&(onePortContext->MainLink)); 277285809Sscottl } 278285809Sscottl else 279285809Sscottl { 280285809Sscottl DM_DBG1(("dmDestroyPort: onePortContext->MainLink is NULL, wrong!!!\n")); 281285809Sscottl } 282285809Sscottl 283285809Sscottl if (DMLIST_NOT_EMPTY(&(onePortContext->FreeLink)) && DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList))) 284285809Sscottl { 285285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(dmAllShared->FreePortContextList)); 286285809Sscottl } 287285809Sscottl else 288285809Sscottl { 289285809Sscottl DM_DBG1(("dmDestroyPort: onePortContext->FreeLink or dmAllShared->FreePortContextList is NULL, wrong!!!\n")); 290285809Sscottl } 291285809Sscottl 292285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 293285809Sscottl 294285809Sscottl return DM_RC_SUCCESS; 295285809Sscottl} 296285809Sscottl#endif /* FDS_ DM */ 297285809Sscottl 298285809Sscottl 299285809Sscottl 300285809Sscottl 301285809Sscottl 302285809Sscottl 303285809Sscottl 304285809Sscottl 305