dmdisc.c revision 285809
141120Sjdp/******************************************************************************* 2103976Spst** 341120Sjdp*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 441120Sjdp* 541120Sjdp*Redistribution and use in source and binary forms, with or without modification, are permitted provided 641120Sjdp*that the following conditions are met: 741120Sjdp*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 841120Sjdp*following disclaimer. 941120Sjdp*2. Redistributions in binary form must reproduce the above copyright notice, 1041120Sjdp*this list of conditions and the following disclaimer in the documentation and/or other materials provided 1141120Sjdp*with the distribution. 1241120Sjdp* 1341120Sjdp*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 1441120Sjdp*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1541120Sjdp*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1641120Sjdp*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1741120Sjdp*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 1841120Sjdp*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1941120Sjdp*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2041120Sjdp*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 2141120Sjdp** 2241120Sjdp********************************************************************************/ 2341120Sjdp#include <sys/cdefs.h> 2441120Sjdp__FBSDID("$FreeBSD$"); 2541120Sjdp#include <dev/pms/config.h> 2641120Sjdp 2784222Sdillon#include <dev/pms/freebsd/driver/common/osenv.h> 2884222Sdillon#include <dev/pms/freebsd/driver/common/ostypes.h> 2984222Sdillon#include <dev/pms/freebsd/driver/common/osdebug.h> 3041120Sjdp 3141120Sjdp#include <dev/pms/RefTisa/sallsdk/api/sa.h> 3241120Sjdp#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 3341120Sjdp#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 3441120Sjdp 3541120Sjdp#ifdef FDS_DM 3641120Sjdp#include <dev/pms/RefTisa/discovery/api/dm.h> 3741120Sjdp#include <dev/pms/RefTisa/discovery/api/dmapi.h> 3841120Sjdp#include <dev/pms/RefTisa/discovery/api/tddmapi.h> 3941120Sjdp 4041120Sjdp#include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 4141120Sjdp#include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 4241120Sjdp#include <dev/pms/RefTisa/discovery/dm/dmproto.h> 4341120Sjdp 4441120Sjdp/*****************************************************************************/ 4541120Sjdp/*! \brief dmDiscover 4641120Sjdp * 4741120Sjdp * 4841120Sjdp * Purpose: A discovery is started by this function 4941120Sjdp * 5041120Sjdp * \param dmRoot: DM context handle. 5141120Sjdp * \param dmPortContext: Pointer to this instance of port context 5241120Sjdp * \param option: Discovery option 5341120Sjdp * 54103976Spst * \return: 5541120Sjdp * DM_RC_SUCCESS 5641120Sjdp * DM_RC_FAILURE 5741120Sjdp * 5841120Sjdp */ 5941120Sjdp/*****************************************************************************/ 6041120SjdposGLOBAL bit32 6141120SjdpdmDiscover( 6241120Sjdp dmRoot_t *dmRoot, 6341120Sjdp dmPortContext_t *dmPortContext, 6441120Sjdp bit32 option) 6541120Sjdp{ 66103976Spst dmIntPortContext_t *onePortContext = agNULL; 67103976Spst bit32 ret = DM_RC_FAILURE; 6841120Sjdp 6941120Sjdp DM_DBG3(("dmDiscover: start\n")); 7041120Sjdp onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 7141120Sjdp 7241120Sjdp if (onePortContext == agNULL) 7341120Sjdp { 7441120Sjdp DM_DBG1(("dmDiscover: onePortContext is NULL!!!\n")); 7541120Sjdp return DM_RC_FAILURE; 7641120Sjdp } 7741120Sjdp 7841120Sjdp if (onePortContext->valid == agFALSE) 79103976Spst { 80103976Spst DM_DBG1(("dmDiscover: invalid port!!!\n")); 8141120Sjdp return DM_RC_FAILURE; 8241120Sjdp } 8341120Sjdp 8441120Sjdp if (onePortContext->RegFailed == agTRUE) 8541120Sjdp { 8641120Sjdp DM_DBG1(("dmDiscover: Registration failed!!!\n")); 8741120Sjdp return DM_RC_FAILURE; 8841120Sjdp } 8941120Sjdp 9041120Sjdp switch ( option ) 9141120Sjdp { 9241120Sjdp case DM_DISCOVERY_OPTION_FULL_START: 9341120Sjdp DM_DBG3(("dmDiscover: full, pid %d\n", onePortContext->id)); 9441120Sjdp onePortContext->discovery.type = DM_DISCOVERY_OPTION_FULL_START; 9541120Sjdp dmDiscoveryResetMCN(dmRoot, onePortContext); 9641120Sjdp ret = dmFullDiscover(dmRoot, onePortContext); 9741120Sjdp break; 9841120Sjdp case DM_DISCOVERY_OPTION_INCREMENTAL_START: 9941120Sjdp DM_DBG3(("dmDiscover: incremental, pid %d\n", onePortContext->id)); 10041120Sjdp onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 10141120Sjdp dmDiscoveryResetMCN(dmRoot, onePortContext); 10241120Sjdp ret = dmIncrementalDiscover(dmRoot, onePortContext, agFALSE); 10341120Sjdp break; 10441120Sjdp case DM_DISCOVERY_OPTION_ABORT: 10541120Sjdp DM_DBG3(("dmDiscover: abort\n")); 10641120Sjdp if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 10741120Sjdp { 10841120Sjdp if (onePortContext->discovery.pendingSMP == 0) 10941120Sjdp { 11041120Sjdp dmDiscoverAbort(dmRoot, onePortContext); 11141120Sjdp tddmDiscoverCB( 11241120Sjdp dmRoot, 11341120Sjdp onePortContext->dmPortContext, 11441120Sjdp dmDiscAborted 11541120Sjdp ); 11641120Sjdp } 11741120Sjdp else 11841120Sjdp { 11941120Sjdp DM_DBG3(("dmDiscover: abortInProgress\n")); 12041120Sjdp onePortContext->DiscoveryAbortInProgress = agTRUE; 12141120Sjdp tddmDiscoverCB( 12241120Sjdp dmRoot, 12341120Sjdp dmPortContext, 12441120Sjdp dmDiscAbortInProgress 12541120Sjdp ); 12641120Sjdp } 12741120Sjdp } 12841120Sjdp else 12941120Sjdp { 13041120Sjdp DM_DBG3(("dmDiscover: no discovery to abort\n")); 13141120Sjdp tddmDiscoverCB( 13241120Sjdp dmRoot, 13341120Sjdp dmPortContext, 13441120Sjdp dmDiscAbortInvalid 13541120Sjdp ); 13641120Sjdp } 13741120Sjdp ret = DM_RC_SUCCESS; 13841120Sjdp break; 13941120Sjdp default: 14041120Sjdp break; 14141120Sjdp } 14241120Sjdp return ret; 143103976Spst} 14441120Sjdp 145103976SpstosGLOBAL bit32 14641120SjdpdmFullDiscover( 147103976Spst dmRoot_t *dmRoot, 148103976Spst dmIntPortContext_t *onePortContext 149103976Spst ) 150103976Spst{ 151103976Spst dmExpander_t *oneExpander = agNULL; 152103976Spst dmSASSubID_t dmSASSubID; 15341120Sjdp dmDeviceData_t *oneExpDeviceData = agNULL; 154103976Spst 155103976Spst DM_DBG1(("dmFullDiscover: start\n")); 156103976Spst 157103976Spst if (onePortContext->valid == agFALSE) 158103976Spst { 159103976Spst DM_DBG1(("dmFullDiscover: invalid port!!!\n")); 16041120Sjdp return DM_RC_FAILURE; 161103976Spst } 162103976Spst 16341120Sjdp if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 164103976Spst { 165103976Spst DM_DBG1(("dmFullDiscover: no two instances of discovery allowed!!!\n")); 16641120Sjdp return DM_RC_FAILURE; 167103976Spst } 168103976Spst 169103976Spst onePortContext->DiscoveryState = DM_DSTATE_STARTED; 170103976Spst 17141120Sjdp dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 172103976Spst dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 17341120Sjdp 174103976Spst /* check OnePortContext->discovery.discoveringExpanderList */ 175103976Spst oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 17641120Sjdp if (oneExpander != agNULL) 177103976Spst { 178103976Spst oneExpDeviceData = oneExpander->dmDevice; 179103976Spst } 180103976Spst else 181103976Spst { 182103976Spst /* check dmAllShared->mainExpanderList */ 183103976Spst oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 184103976Spst if (oneExpander != agNULL) 185103976Spst { 186103976Spst oneExpDeviceData = oneExpander->dmDevice; 187103976Spst } 188103976Spst } 189103976Spst 190103976Spst if (oneExpDeviceData != agNULL) 191103976Spst { 192103976Spst dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 193103976Spst dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 194103976Spst oneExpDeviceData->registered = agTRUE; 195103976Spst dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 196103976Spst } 197103976Spst else 198103976Spst { 199103976Spst DM_DBG1(("dmFullDiscover:oneExpDeviceData is NULL!!!\n")); 200103976Spst return DM_RC_FAILURE; 201103976Spst } 202103976Spst 203103976Spst dmUpStreamDiscoverStart(dmRoot, onePortContext); 204103976Spst 205103976Spst return DM_RC_SUCCESS; 206103976Spst} 207103976Spst 208103976SpstosGLOBAL bit32 209103976SpstdmIncrementalDiscover( 21041120Sjdp dmRoot_t *dmRoot, 211103976Spst dmIntPortContext_t *onePortContext, 212103976Spst bit32 flag 21341120Sjdp ) 214200399Ssyrinx{ 215200399Ssyrinx dmExpander_t *oneExpander = agNULL; 21641120Sjdp dmSASSubID_t dmSASSubID; 217103976Spst dmDeviceData_t *oneExpDeviceData = agNULL; 218103976Spst 219103976Spst DM_DBG1(("dmIncrementalDiscover: start\n")); 22041120Sjdp 221103976Spst if (onePortContext->valid == agFALSE) 22241120Sjdp { 22341120Sjdp DM_DBG1(("dmIncrementalDiscover: invalid port!!!\n")); 224103976Spst return DM_RC_FAILURE; 22541120Sjdp } 22641120Sjdp 22741120Sjdp /* TDM triggerred; let go DM triggerred */ 22841120Sjdp if (flag == agFALSE) 22941120Sjdp { 23041120Sjdp if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 23141120Sjdp { 23241120Sjdp DM_DBG1(("dmIncrementalDiscover: no two instances of discovery allowed!!!\n")); 23341120Sjdp return DM_RC_FAILURE; 23441120Sjdp } 23541120Sjdp } 23641120Sjdp 23741120Sjdp onePortContext->DiscoveryState = DM_DSTATE_STARTED; 23841120Sjdp onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 23941120Sjdp 24041120Sjdp dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 24141120Sjdp dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 24241120Sjdp 24341120Sjdp /* check OnePortContext->discovery.discoveringExpanderList */ 24441120Sjdp oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 24541120Sjdp if (oneExpander != agNULL) 24641120Sjdp { 24741120Sjdp oneExpDeviceData = oneExpander->dmDevice; 24841120Sjdp } 24941120Sjdp else 25041120Sjdp { 25141120Sjdp /* check dmAllShared->mainExpanderList */ 25241120Sjdp oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 25341120Sjdp if (oneExpander != agNULL) 25441120Sjdp { 25541120Sjdp oneExpDeviceData = oneExpander->dmDevice; 25641120Sjdp } 25741120Sjdp } 25841120Sjdp 25941120Sjdp if (oneExpDeviceData != agNULL) 26041120Sjdp { 261141918Sstefanf dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 26241120Sjdp dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 26341120Sjdp oneExpDeviceData->registered = agTRUE; 26441120Sjdp dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 26541120Sjdp } 26641120Sjdp else 26741120Sjdp { 26841120Sjdp DM_DBG1(("dmIncrementalDiscover:oneExpDeviceData is NULL!!!\n")); 26941120Sjdp return DM_RC_FAILURE; 27041120Sjdp } 27141120Sjdp 27241120Sjdp dmUpStreamDiscoverStart(dmRoot, onePortContext); 27341120Sjdp 27441120Sjdp return DM_RC_SUCCESS; 27541120Sjdp} 27641120Sjdp 27741120SjdposGLOBAL void 27841120SjdpdmUpStreamDiscoverStart( 27941120Sjdp dmRoot_t *dmRoot, 28041120Sjdp dmIntPortContext_t *onePortContext 28141120Sjdp ) 28241120Sjdp{ 28341120Sjdp// dmExpander_t *oneExpander = agNULL; 28441120Sjdp bit32 sasAddressHi, sasAddressLo; 28541120Sjdp dmDeviceData_t *oneDeviceData; 28641120Sjdp dmExpander_t *oneExpander = agNULL; 28741120Sjdp 28841120Sjdp DM_DBG3(("dmUpStreamDiscoverStart: start\n")); 28941120Sjdp if (onePortContext->valid == agFALSE) 29041120Sjdp { 29141120Sjdp DM_DBG1(("dmUpStreamDiscoverStart: invalid port!!!\n")); 29241120Sjdp return; 29341120Sjdp } 29441120Sjdp /* 29541120Sjdp at this point, the 1st expander should have been registered. 29641120Sjdp find an expander from onePortContext 29741120Sjdp */ 29841120Sjdp sasAddressHi = onePortContext->sasRemoteAddressHi; 29941120Sjdp sasAddressLo = onePortContext->sasRemoteAddressLo; 30041120Sjdp DM_DBG3(("dmUpStreamDiscoverStart: Port Remote AddrHi 0x%08x Remote AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 30141120Sjdp 30241120Sjdp oneDeviceData = dmDeviceFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 30341120Sjdp 30441120Sjdp// oneDeviceData = oneExpander->dmDevice; 30541120Sjdp// start here 30641120Sjdp onePortContext->discovery.status = DISCOVERY_UP_STREAM; 30741120Sjdp if (oneDeviceData == agNULL) 30841120Sjdp { 30941120Sjdp DM_DBG1(("dmUpStreamDiscoverStart: oneExpander is NULL, wrong!!!\n")); 31041120Sjdp return; 31141120Sjdp } 31241120Sjdp else 31341120Sjdp { 31441120Sjdp if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 31541120Sjdp || 31641120Sjdp (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 31741120Sjdp || 31841120Sjdp DEVICE_IS_SMP_TARGET(oneDeviceData) 31941120Sjdp ) 32041120Sjdp { 32141120Sjdp#if 1 /* for incremental discovery */ 32241120Sjdp /* start here: if not on discoveringExpanderList, alloc and add 32341120Sjdp dmNewEXPorNot() 32441120Sjdp */ 32541120Sjdp oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 32641120Sjdp if ( oneExpander == agNULL) 32741120Sjdp { 32841120Sjdp /* alloc and add */ 32941120Sjdp oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 33041120Sjdp if ( oneExpander != agNULL) 33141120Sjdp { 33241120Sjdp dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 33341120Sjdp } 33441120Sjdp else 33541120Sjdp { 33641120Sjdp DM_DBG1(("dmUpStreamDiscoverStart: failed to allocate expander or discovey aborted!!!\n")); 33741120Sjdp return; 33841120Sjdp } 33941120Sjdp } 34041120Sjdp#endif 34141120Sjdp 34241120Sjdp dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 34341120Sjdp } 34441120Sjdp else 34541120Sjdp { 34641120Sjdp DM_DBG1(("dmUpStreamDiscoverStart: oneDeviceData is not an Expander did %d, wrong!!!\n", oneDeviceData->id)); 34741120Sjdp return; 34841120Sjdp } 34941120Sjdp } 35041120Sjdp return; 35141120Sjdp} 35241120Sjdp 35341120Sjdp/* sends report general */ 35441120SjdposGLOBAL void 35541120SjdpdmUpStreamDiscovering( 35641120Sjdp dmRoot_t *dmRoot, 35741120Sjdp dmIntPortContext_t *onePortContext, 35841120Sjdp dmDeviceData_t *oneDeviceData 35941120Sjdp ) 36041120Sjdp{ 36141120Sjdp dmList_t *ExpanderList; 36241120Sjdp dmExpander_t *oneNextExpander = agNULL; 36341120Sjdp 36441120Sjdp DM_DBG3(("dmUpStreamDiscovering: start\n")); 36541120Sjdp 36641120Sjdp if (onePortContext->valid == agFALSE) 36741120Sjdp { 36841120Sjdp DM_DBG1(("dmUpStreamDiscovering: invalid port!!!\n")); 36941120Sjdp return; 37041120Sjdp } 37141120Sjdp 37241120Sjdp tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 37341120Sjdp if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 37441120Sjdp { 37541120Sjdp tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 37641120Sjdp DM_DBG3(("dmUpStreamDiscovering: should be the end\n")); 37741120Sjdp oneNextExpander = agNULL; 37841120Sjdp } 37941120Sjdp else 38041120Sjdp { 38141120Sjdp DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList)); 38241120Sjdp oneNextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 38341120Sjdp if ( oneNextExpander != agNULL) 38441120Sjdp { 38541120Sjdp DMLIST_ENQUEUE_AT_HEAD(&(oneNextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 38641120Sjdp DM_DBG3(("dmUpStreamDiscovering tdsaSASUpStreamDiscovering: dequeue head\n")); 38741120Sjdp DM_DBG3(("dmUpStreamDiscovering: expander id %d\n", oneNextExpander->id)); 38841120Sjdp } 38941120Sjdp else 39041120Sjdp { 39141120Sjdp DM_DBG1(("dmUpStreamDiscovering: oneNextExpander is NULL!!!\n")); 39241120Sjdp } 39341120Sjdp tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 39441120Sjdp 39541120Sjdp } 39641120Sjdp 39741120Sjdp if (oneNextExpander != agNULL) 39841120Sjdp { 39941120Sjdp dmReportGeneralSend(dmRoot, oneNextExpander->dmDevice); 40041120Sjdp } 40141120Sjdp else 40241120Sjdp { 40341120Sjdp DM_DBG3(("dmUpStreamDiscovering: No more expander list\n")); 40441120Sjdp dmDownStreamDiscoverStart(dmRoot, onePortContext, oneDeviceData); 40541120Sjdp } 40641120Sjdp 40741120Sjdp return; 40841120Sjdp} 40941120Sjdp 41041120SjdposGLOBAL void 41141120SjdpdmDownStreamDiscoverStart( 41241120Sjdp dmRoot_t *dmRoot, 41341120Sjdp dmIntPortContext_t *onePortContext, 41441120Sjdp dmDeviceData_t *oneDeviceData 41541120Sjdp ) 41641120Sjdp{ 41741120Sjdp dmExpander_t *UpStreamExpander; 41841120Sjdp dmExpander_t *oneExpander; 41941120Sjdp 42041120Sjdp DM_DBG3(("dmDownStreamDiscoverStart: start\n")); 42141120Sjdp 42241120Sjdp if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 42341120Sjdp { 42441120Sjdp DM_DBG1(("dmDownStreamDiscoverStart: invalid port or aborted discovery!!!\n")); 42541120Sjdp return; 42641120Sjdp } 42741120Sjdp 42841120Sjdp /* set discovery status */ 42941120Sjdp onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 43041120Sjdp 43141120Sjdp /* If it's an expander */ 43241120Sjdp if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 43341120Sjdp || (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 43441120Sjdp || DEVICE_IS_SMP_TARGET(oneDeviceData) 43541120Sjdp ) 43641120Sjdp { 43741120Sjdp oneExpander = oneDeviceData->dmExpander; 43841120Sjdp UpStreamExpander = oneExpander->dmUpStreamExpander; 43941120Sjdp 44041120Sjdp /* If the two expanders are the root of two edge sets; sub-to-sub */ 44141120Sjdp if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->dmUpStreamExpander == oneExpander ) ) 44241120Sjdp { 44341120Sjdp DM_DBG3(("dmDownStreamDiscoverStart: Root found pExpander=%p pUpStreamExpander=%p\n", 44441120Sjdp oneExpander, UpStreamExpander)); 445103976Spst //Saves the root expander 446103976Spst onePortContext->discovery.RootExp = oneExpander; 447103976Spst DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 448103976Spst DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 449103976Spst 450103976Spst /* reset up stream inform for pExpander */ 451103976Spst oneExpander->dmUpStreamExpander = agNULL; 452103976Spst /* Add the pExpander to discovering list */ 45341120Sjdp dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 45441120Sjdp 45541120Sjdp /* reset up stream inform for oneExpander */ 45641120Sjdp UpStreamExpander->dmUpStreamExpander = agNULL; 45741120Sjdp /* Add the UpStreamExpander to discovering list */ 45841120Sjdp dmDiscoveringExpanderAdd(dmRoot, onePortContext, UpStreamExpander); 459103976Spst } 460103976Spst /* If the two expanders are not the root of two edge sets. eg) one root */ 46141120Sjdp else 46241120Sjdp { 463103976Spst //Saves the root expander 464103976Spst onePortContext->discovery.RootExp = oneExpander; 465103976Spst 46641120Sjdp DM_DBG3(("dmDownStreamDiscoverStart: NO Root pExpander=%p\n", oneExpander)); 46741120Sjdp DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 46841120Sjdp DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 46941120Sjdp 47041120Sjdp /* (2.2.2.1) Add the pExpander to discovering list */ 47141120Sjdp dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 47241120Sjdp } 47341120Sjdp } 47441120Sjdp 47541120Sjdp /* Continue down stream discovering */ 47641120Sjdp dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 47741120Sjdp 47841120Sjdp return; 47941120Sjdp} 48041120Sjdp 48141120SjdposGLOBAL void 48241120SjdpdmDownStreamDiscovering( 48341120Sjdp dmRoot_t *dmRoot, 48441120Sjdp dmIntPortContext_t *onePortContext, 48541120Sjdp dmDeviceData_t *oneDeviceData 48641120Sjdp ) 48741120Sjdp{ 48841120Sjdp dmExpander_t *NextExpander = agNULL; 48941120Sjdp dmList_t *ExpanderList; 49041120Sjdp 49141120Sjdp DM_DBG3(("dmDownStreamDiscovering: start\n")); 49241120Sjdp 49341120Sjdp if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 49441120Sjdp { 49541120Sjdp DM_DBG1(("dmDownStreamDiscovering: invalid port or aborted discovery!!!\n")); 49641120Sjdp return; 49741120Sjdp } 49841120Sjdp 49941120Sjdp tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 50041120Sjdp if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 50141120Sjdp { 50241120Sjdp tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 50341120Sjdp DM_DBG3(("dmDownStreamDiscovering: should be the end\n")); 50441120Sjdp NextExpander = agNULL; 50541120Sjdp } 50641120Sjdp else 50741120Sjdp { 50841120Sjdp DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList));; 50941120Sjdp NextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 51041120Sjdp if ( NextExpander != agNULL) 51141120Sjdp { 51241120Sjdp DMLIST_ENQUEUE_AT_HEAD(&(NextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList));; 51341120Sjdp DM_DBG3(("dmDownStreamDiscovering tdsaSASDownStreamDiscovering: dequeue head\n")); 51441120Sjdp DM_DBG3(("dmDownStreamDiscovering: expander id %d\n", NextExpander->id)); 51541120Sjdp } 51641120Sjdp else 51741120Sjdp { 51841120Sjdp DM_DBG1(("dmDownStreamDiscovering: NextExpander is NULL!!!\n")); 51941120Sjdp } 52041120Sjdp tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 52141120Sjdp 52241120Sjdp } 52341120Sjdp 52441120Sjdp /* If there is an expander for continue discoving */ 52541120Sjdp if ( NextExpander != agNULL) 52641120Sjdp { 52741120Sjdp DM_DBG3(("dmDownStreamDiscovering: Found pNextExpander=%p discoveryStatus=0x%x\n", 52841120Sjdp NextExpander, onePortContext->discovery.status)); 52941120Sjdp 53041120Sjdp switch (onePortContext->discovery.status) 53141120Sjdp { 53241120Sjdp /* If the discovery status is DISCOVERY_DOWN_STREAM */ 53341120Sjdp case DISCOVERY_DOWN_STREAM: 53441120Sjdp /* Send report general for the next expander */ 53541120Sjdp DM_DBG3(("dmDownStreamDiscovering: DownStream pNextExpander=%p\n", NextExpander)); 53641120Sjdp DM_DBG3(("dmDownStreamDiscovering: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 53741120Sjdp DM_DBG3(("dmDownStreamDiscovering: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 53841120Sjdp 53941120Sjdp DM_DBG3(("dmDownStreamDiscovering: 2nd oneDeviceData %p did %d\n", NextExpander->dmDevice, NextExpander->dmDevice->id)); 54041120Sjdp DM_DBG3(("dmDownStreamDiscovering: 2nd oneExpander %p did %d\n", NextExpander, NextExpander->id)); 54141120Sjdp DM_DBG3(("dmDownStreamDiscovering: 2nd used oneExpander %p did %d\n", NextExpander->dmDevice->dmExpander, NextExpander->dmDevice->dmExpander->id)); 54241120Sjdp 54341120Sjdp if (NextExpander != NextExpander->dmDevice->dmExpander) 54441120Sjdp { 54541120Sjdp DM_DBG3(("dmDownStreamDiscovering: wrong!!!\n")); 54641120Sjdp } 54741120Sjdp 54841120Sjdp 54941120Sjdp dmReportGeneralSend(dmRoot, NextExpander->dmDevice); 550103976Spst break; 55141120Sjdp /* If the discovery status is DISCOVERY_CONFIG_ROUTING */ 55241120Sjdp case DISCOVERY_CONFIG_ROUTING: 55341120Sjdp case DISCOVERY_REPORT_PHY_SATA: 55441120Sjdp 55541120Sjdp /* set discovery status */ 55641120Sjdp onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 55741120Sjdp 55841120Sjdp DM_DBG3(("dmDownStreamDiscovering: pPort->discovery.status=DISCOVERY_CONFIG_ROUTING, make it DOWN_STREAM\n")); 55941120Sjdp /* If not the last phy */ 56041120Sjdp if ( NextExpander->discoveringPhyId < NextExpander->dmDevice->numOfPhys ) 56141120Sjdp { 56241120Sjdp DM_DBG3(("dmDownStreamDiscovering: pNextExpander->discoveringPhyId=0x%x pNextExpander->numOfPhys=0x%x. Send More Discover\n", 56341120Sjdp NextExpander->discoveringPhyId, NextExpander->dmDevice->numOfPhys)); 56441120Sjdp /* Send discover for the next expander */ 565103976Spst dmDiscoverSend(dmRoot, NextExpander->dmDevice); 566103976Spst } 567103976Spst /* If it's the last phy */ 56841120Sjdp else 56941120Sjdp { 57041120Sjdp DM_DBG3(("dmDownStreamDiscovering: Last Phy, remove expander%p start DownStream=%p\n", 57141120Sjdp NextExpander, NextExpander->dmDevice)); 572103976Spst dmDiscoveringExpanderRemove(dmRoot, onePortContext, NextExpander); 573103976Spst dmDownStreamDiscovering(dmRoot, onePortContext, NextExpander->dmDevice); 57441120Sjdp } 57541120Sjdp break; 57641120Sjdp 577103976Spst default: 578103976Spst DM_DBG3(("dmDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status)); 579103976Spst } 58041120Sjdp } 58141120Sjdp /* If no expander for continue discoving */ 58241120Sjdp else 58341120Sjdp { 58441120Sjdp DM_DBG3(("dmDownStreamDiscovering: No more expander DONE\n")); 58541120Sjdp /* discover done */ 58641120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_SUCCESS); 58741120Sjdp } 58841120Sjdp 58941120Sjdp 59041120Sjdp return; 59141120Sjdp} 59241120Sjdp 59341120SjdposGLOBAL void 59441120SjdpdmUpStreamDiscoverExpanderPhy( 59541120Sjdp dmRoot_t *dmRoot, 59641120Sjdp dmIntPortContext_t *onePortContext, 59741120Sjdp dmExpander_t *oneExpander, 59841120Sjdp smpRespDiscover_t *pDiscoverResp 59941120Sjdp ) 60041120Sjdp{ 60141120Sjdp agsaSASIdentify_t sasIdentify; 60241120Sjdp dmSASSubID_t dmSASSubID; 60341120Sjdp bit32 attachedSasHi, attachedSasLo; 60441120Sjdp dmExpander_t *AttachedExpander = agNULL; 60541120Sjdp bit8 connectionRate; 60641120Sjdp dmDeviceData_t *oneDeviceData = agNULL; 60741120Sjdp dmDeviceData_t *AttachedDevice = agNULL; 60841120Sjdp dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 60941120Sjdp dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 61041120Sjdp 61141120Sjdp 61241120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: start\n")); 61341120Sjdp 61441120Sjdp if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 61541120Sjdp { 61641120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 61741120Sjdp return; 61841120Sjdp } 61941120Sjdp 62041120Sjdp if (oneExpander != oneExpander->dmDevice->dmExpander) 62141120Sjdp { 62241120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: wrong!!!\n")); 62341120Sjdp } 62441120Sjdp 62541120Sjdp dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 62641120Sjdp 62741120Sjdp oneDeviceData = oneExpander->dmDevice; 62841120Sjdp 62941120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 630103976Spst oneExpander->discoveringPhyId, 631103976Spst oneDeviceData->SASAddressID.sasAddressHi, 632103976Spst oneDeviceData->SASAddressID.sasAddressLo)); 63341120Sjdp 63441120Sjdp DM_DBG3((" Attached device: %s\n", 63541120Sjdp ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 63641120Sjdp (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 63741120Sjdp (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 63841120Sjdp 63941120Sjdp 64041120Sjdp if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 64141120Sjdp { 64241120Sjdp DM_DBG3((" SAS address : %08x-%08x\n", 64341120Sjdp DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 64441120Sjdp DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 64541120Sjdp DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 64641120Sjdp DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 64741120Sjdp DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 64841120Sjdp DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 64941120Sjdp DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 65041120Sjdp DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 65141120Sjdp DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 65241120Sjdp DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 65341120Sjdp DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 65441120Sjdp } 65541120Sjdp 65641120Sjdp /* for debugging */ 65741120Sjdp if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 65841120Sjdp { 65941120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 66041120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 66141120Sjdp dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 66241120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 66341120Sjdp return; 66441120Sjdp } 66541120Sjdp 66641120Sjdp /* saving routing attribute for non self-configuring expanders */ 66741120Sjdp oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = (bit8)DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 66841120Sjdp 66941120Sjdp if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 67041120Sjdp { 67141120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 67241120Sjdp if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 67341120Sjdp { 67441120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 67541120Sjdp 67641120Sjdp /* discovery error */ 67741120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 67841120Sjdp = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 67941120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 68041120Sjdp = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 68141120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 68241120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 68341120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 68441120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 68541120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 68641120Sjdp 68741120Sjdp /* (2.1.3) discovery done */ 68841120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 68941120Sjdp return; 69041120Sjdp } 69141120Sjdp } 69241120Sjdp else 69341120Sjdp { 69441120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 69541120Sjdp if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 69641120Sjdp { 69741120Sjdp /* Setup sasIdentify for the attached device */ 69841120Sjdp sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 69941120Sjdp sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70); 70041120Sjdp sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 70141120Sjdp sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 70241120Sjdp *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 70341120Sjdp *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 70441120Sjdp 70541120Sjdp /* incremental discovery */ 70641120Sjdp dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 70741120Sjdp dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 70841120Sjdp dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 70941120Sjdp dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 71041120Sjdp 71141120Sjdp attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 71241120Sjdp attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 71341120Sjdp 71441120Sjdp /* If the phy has subtractive routing attribute */ 71541120Sjdp if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 71641120Sjdp { 71741120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 71841120Sjdp /* Setup upstream phys */ 71941120Sjdp dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 72041120Sjdp /* If the expander already has an upsteam device set up */ 72141120Sjdp if (oneExpander->hasUpStreamDevice == agTRUE) 72241120Sjdp { 72341120Sjdp /* just to update MCN */ 72441120Sjdp dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 72541120Sjdp /* If the sas address doesn't match */ 72641120Sjdp if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 72741120Sjdp (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 72841120Sjdp (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 72941120Sjdp DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 73041120Sjdp ) 73141120Sjdp { 73241120Sjdp /* TODO: discovery error, callback */ 73341120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 73441120Sjdp /* call back to notify discovery error */ 73541120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 73641120Sjdp = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 73741120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 73841120Sjdp = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 73941120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 74041120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 74141120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 74241120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 74341120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 74441120Sjdp /* discovery done */ 74541120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 74641120Sjdp } 74741120Sjdp } 74841120Sjdp else 74941120Sjdp { 75041120Sjdp /* Setup SAS address for up stream device */ 75141120Sjdp oneExpander->hasUpStreamDevice = agTRUE; 75241120Sjdp oneExpander->upStreamSASAddressHi = attachedSasHi; 75341120Sjdp oneExpander->upStreamSASAddressLo = attachedSasLo; 75441120Sjdp if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 75541120Sjdp || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 75641120Sjdp { 75741120Sjdp /* Find the device from the discovered list */ 75841120Sjdp AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 75941120Sjdp /* New device, If the device has been discovered before */ 76041120Sjdp if ( AttachedDevice != agNULL) /* old device */ 76141120Sjdp { 76241120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Seen This Device Before\n")); 76341120Sjdp /* If attached device is an edge expander */ 76441120Sjdp if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 76541120Sjdp { 76641120Sjdp /* The attached device is an expander */ 76741120Sjdp AttachedExpander = AttachedDevice->dmExpander; 76841120Sjdp /* If the two expanders are the root of the two edge expander sets */ 76941120Sjdp if ( (AttachedExpander->upStreamSASAddressHi == 77056141Sjdp DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 77141120Sjdp && (AttachedExpander->upStreamSASAddressLo == 77241120Sjdp DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 77341120Sjdp { 77441120Sjdp /* Setup upstream expander for the pExpander */ 77541120Sjdp oneExpander->dmUpStreamExpander = AttachedExpander; 77641120Sjdp } 77741120Sjdp /* If the two expanders are not the root of the two edge expander sets */ 77841120Sjdp else 77941120Sjdp { 78041120Sjdp /* TODO: loop found, discovery error, callback */ 78141120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error loop detection!!!\n")); 78241120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 78341120Sjdp = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 78441120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 78541120Sjdp = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 78641120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 78741120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 78841120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 78941120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 79041120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 79141120Sjdp /* discovery done */ 79241120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 79341120Sjdp } 79441120Sjdp } 79541120Sjdp /* If attached device is not an edge expander */ 79641120Sjdp else 79741120Sjdp { 79841120Sjdp /*TODO: should not happen, ASSERT */ 79941120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 800103976Spst } 80141120Sjdp } /* AttachedExpander != agNULL */ 80241120Sjdp /* New device, If the device has not been discovered before */ 80341120Sjdp else /* new device */ 80441120Sjdp { 80541120Sjdp /* Add the device */ 80641120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: New device\n")); 80741120Sjdp /* read minimum rate from the configuration 80841120Sjdp onePortContext->LinkRate is SPC's local link rate 80941120Sjdp */ 81041120Sjdp connectionRate = (bit8)MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 81141120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 81241120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 81341120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 814103976Spst if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 815103976Spst { 816103976Spst /* incremental discovery */ 817103976Spst if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 818103976Spst { 81941120Sjdp AttachedDevice = dmPortSASDeviceAdd( 82041120Sjdp dmRoot, 82141120Sjdp onePortContext, 82241120Sjdp sasIdentify, 82341120Sjdp agFALSE, 82441120Sjdp connectionRate, 82541120Sjdp dmAllShared->itNexusTimeout, 82641120Sjdp 0, 82741120Sjdp STP_DEVICE_TYPE, 82841120Sjdp oneDeviceData, 82941120Sjdp oneExpander, 83041120Sjdp pDiscoverResp->phyIdentifier 83141120Sjdp ); 83241120Sjdp } 83341120Sjdp else 83441120Sjdp { 83541120Sjdp /* incremental discovery */ 83641120Sjdp AttachedDevice = dmFindRegNValid( 83741120Sjdp dmRoot, 83841120Sjdp onePortContext, 83941120Sjdp &dmSASSubID 84041120Sjdp ); 84141120Sjdp /* not registered and not valid; add this*/ 84241120Sjdp if (AttachedDevice == agNULL) 84365222Sache { 84441120Sjdp AttachedDevice = dmPortSASDeviceAdd( 84541120Sjdp dmRoot, 84641120Sjdp onePortContext, 84741120Sjdp sasIdentify, 84841120Sjdp agFALSE, 84941120Sjdp connectionRate, 85041120Sjdp dmAllShared->itNexusTimeout, 85141120Sjdp 0, 85241120Sjdp STP_DEVICE_TYPE, 85341120Sjdp oneDeviceData, 85441120Sjdp oneExpander, 85541120Sjdp pDiscoverResp->phyIdentifier 85641120Sjdp ); 857103976Spst } 85841120Sjdp } 85941120Sjdp } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 86041120Sjdp else 86141120Sjdp { 86241120Sjdp /* incremental discovery */ 86341120Sjdp if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 86441120Sjdp { 86541120Sjdp AttachedDevice = dmPortSASDeviceAdd( 86641120Sjdp dmRoot, 86741120Sjdp onePortContext, 86841120Sjdp sasIdentify, 86941120Sjdp agFALSE, 87041120Sjdp connectionRate, 87141120Sjdp dmAllShared->itNexusTimeout, 87241120Sjdp 0, 87341120Sjdp SAS_DEVICE_TYPE, 87441120Sjdp oneDeviceData, 87541120Sjdp oneExpander, 87641120Sjdp pDiscoverResp->phyIdentifier 87741120Sjdp ); 87841120Sjdp } 87941120Sjdp else 88041120Sjdp { 88141120Sjdp /* incremental discovery */ 88241120Sjdp AttachedDevice = dmFindRegNValid( 88341120Sjdp dmRoot, 88441120Sjdp onePortContext, 88541120Sjdp &dmSASSubID 88641120Sjdp ); 88741120Sjdp /* not registered and not valid; add this*/ 88841120Sjdp if (AttachedDevice == agNULL) 88965222Sache { 89065222Sache AttachedDevice = dmPortSASDeviceAdd( 89165222Sache dmRoot, 89241120Sjdp onePortContext, 89341120Sjdp sasIdentify, 89441120Sjdp agFALSE, 89541120Sjdp connectionRate, 89641120Sjdp dmAllShared->itNexusTimeout, 89741120Sjdp 0, 89841120Sjdp SAS_DEVICE_TYPE, 89941120Sjdp oneDeviceData, 90041120Sjdp oneExpander, 90141120Sjdp pDiscoverResp->phyIdentifier 90241120Sjdp ); 90341120Sjdp } 90441120Sjdp } 90541120Sjdp } 90641120Sjdp /* If the device is added successfully */ 90741120Sjdp if ( AttachedDevice != agNULL) 90841120Sjdp { 90941120Sjdp 91041120Sjdp /* (3.1.2.3.2.3.2.1) callback about new device */ 91141120Sjdp if ( DISCRSP_IS_SSP_TARGET(pDiscoverResp) 91241120Sjdp || DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 91341120Sjdp || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 91441120Sjdp || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 91541120Sjdp { 91641120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 91741120Sjdp attachedSasHi, attachedSasLo)); 91841120Sjdp } 91941120Sjdp else 92041120Sjdp { 92141120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n")); 92241120Sjdp } 92341120Sjdp /* If the attached device is an expander */ 92441120Sjdp if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 92541120Sjdp || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 92641120Sjdp { 92741120Sjdp /* Allocate an expander data structure */ 92841120Sjdp AttachedExpander = dmDiscoveringExpanderAlloc( 92941120Sjdp dmRoot, 93041120Sjdp onePortContext, 93141120Sjdp AttachedDevice 93241120Sjdp ); 93341120Sjdp 93441120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander)); 93541120Sjdp /* If allocate successfully */ 93641120Sjdp if ( AttachedExpander != agNULL) 93741120Sjdp { 93841120Sjdp /* Add the pAttachedExpander to discovering list */ 93941120Sjdp dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 94041120Sjdp /* Setup upstream expander for the pExpander */ 94141120Sjdp oneExpander->dmUpStreamExpander = AttachedExpander; 94241120Sjdp } 94341120Sjdp /* If failed to allocate */ 94441120Sjdp else 945103976Spst { 94641120Sjdp DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 947103976Spst dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 94841120Sjdp } 94941120Sjdp } 95041120Sjdp /* If the attached device is an end device */ 95141120Sjdp else 95241120Sjdp { 953103976Spst DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found end device\n")); 954103976Spst /* LP2006-05-26 added upstream device to the newly found device */ 955103976Spst AttachedDevice->dmExpander = oneExpander; 956103976Spst oneExpander->dmUpStreamExpander = agNULL; 957103976Spst } 958103976Spst } 959103976Spst else 960103976Spst { 961103976Spst DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 962103976Spst dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 963103976Spst } 964103976Spst 965103976Spst 966103976Spst 967103976Spst } /* else, new device */ 968103976Spst } /* onePortContext->sasLocalAddressLo != attachedSasLo */ 969103976Spst } /* else */ 970103976Spst } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 971103976Spst } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 972200399Ssyrinx } /* big else */ 973200399Ssyrinx 974200399Ssyrinx 975200399Ssyrinx 976200399Ssyrinx oneExpander->discoveringPhyId ++; 977200399Ssyrinx if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 978200399Ssyrinx { 979200399Ssyrinx if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 980200399Ssyrinx { 981200399Ssyrinx DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 982200399Ssyrinx /* continue discovery for the next phy */ 983200399Ssyrinx dmDiscoverSend(dmRoot, oneDeviceData); 984200399Ssyrinx } 985200399Ssyrinx else 986200399Ssyrinx { 987200399Ssyrinx DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 988200399Ssyrinx 989103976Spst /* for MCN */ 990103976Spst dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 991103976Spst /* remove the expander from the discovering list */ 992103976Spst dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 993103976Spst /* continue upstream discovering */ 994103976Spst dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 995103976Spst } 996103976Spst } 997103976Spst else 998103976Spst { 999103976Spst DM_DBG3(("dmUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1000103976Spst 1001103976Spst } 100241120Sjdp 100341120Sjdp DM_DBG3(("dmUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 100441120Sjdp 100541120Sjdp return; 100641120Sjdp} 100741120Sjdp 1008103976SpstosGLOBAL void 1009103976SpstdmUpStreamDiscover2ExpanderPhy( 101041120Sjdp dmRoot_t *dmRoot, 101141120Sjdp dmIntPortContext_t *onePortContext, 101241120Sjdp dmExpander_t *oneExpander, 101341120Sjdp smpRespDiscover2_t *pDiscoverResp 101441120Sjdp ) 101541120Sjdp{ 101641120Sjdp dmDeviceData_t *oneDeviceData; 101741120Sjdp dmDeviceData_t *AttachedDevice = agNULL; 101841120Sjdp dmExpander_t *AttachedExpander; 101941120Sjdp agsaSASIdentify_t sasIdentify; 102041120Sjdp bit8 connectionRate; 1021103976Spst bit32 attachedSasHi, attachedSasLo; 102241120Sjdp dmSASSubID_t dmSASSubID; 102341120Sjdp dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 102441120Sjdp dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 102541120Sjdp 102641120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: start\n")); 102741120Sjdp 102841120Sjdp if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 102941120Sjdp { 103041120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 103141120Sjdp return; 1032103976Spst } 103341120Sjdp 103441120Sjdp if (oneExpander != oneExpander->dmDevice->dmExpander) 103541120Sjdp { 103641120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: wrong!!!\n")); 103741120Sjdp } 103841120Sjdp 103941120Sjdp dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 104041120Sjdp 104141120Sjdp oneDeviceData = oneExpander->dmDevice; 104241120Sjdp 104341120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 104441120Sjdp oneExpander->discoveringPhyId, 104541120Sjdp oneDeviceData->SASAddressID.sasAddressHi, 1046103976Spst oneDeviceData->SASAddressID.sasAddressLo)); 1047103976Spst 1048103976Spst DM_DBG2((" Attached device: %s\n", 1049103976Spst ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 105041120Sjdp (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 105141120Sjdp (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 105241120Sjdp 105341120Sjdp 105441120Sjdp if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 105541120Sjdp { 105641120Sjdp DM_DBG2((" SAS address : %08x-%08x\n", 105741120Sjdp SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 105841120Sjdp SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 105941120Sjdp DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 106041120Sjdp DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 106141120Sjdp DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1062103976Spst DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1063103976Spst DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1064103976Spst DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 106541120Sjdp DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 106641120Sjdp DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 106741120Sjdp DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 106841120Sjdp } 106941120Sjdp 107041120Sjdp if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 107141120Sjdp { 107241120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 107341120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 107441120Sjdp dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 107541120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 107641120Sjdp return; 107741120Sjdp } 107841120Sjdp 107941120Sjdp /* saving routing attribute for non self-configuring expanders */ 108041120Sjdp oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 108141120Sjdp 108241120Sjdp if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 108341120Sjdp { 108441120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 108541120Sjdp if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 108641120Sjdp { 108741120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 108841120Sjdp 108941120Sjdp /* discovery error */ 109041120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 109141120Sjdp = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 109241120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 109341120Sjdp = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 109441120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1095103976Spst DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1096103976Spst onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 109741120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 109841120Sjdp onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 109941120Sjdp 110041120Sjdp /* (2.1.3) discovery done */ 110141120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 110241120Sjdp return; 110341120Sjdp } 110441120Sjdp } 110541120Sjdp else 110641120Sjdp { 110741120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 110841120Sjdp 110941120Sjdp if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1110103976Spst { 1111103976Spst /* Setup sasIdentify for the attached device */ 1112103976Spst sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1113103976Spst sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 1114103976Spst sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1115103976Spst sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1116103976Spst *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1117103976Spst *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1118103976Spst 1119103976Spst /* incremental discovery */ 1120103976Spst dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1121103976Spst dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1122103976Spst dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1123103976Spst dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1124103976Spst 1125103976Spst attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1126103976Spst attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1127103976Spst 1128103976Spst /* If the phy has subtractive routing attribute */ 1129103976Spst if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1130103976Spst { 1131103976Spst DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 1132103976Spst /* Setup upstream phys */ 1133103976Spst dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 1134103976Spst /* If the expander already has an upsteam device set up */ 1135103976Spst if (oneExpander->hasUpStreamDevice == agTRUE) 1136103976Spst { 1137103976Spst /* just to update MCN */ 1138103976Spst dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1139103976Spst /* If the sas address doesn't match */ 1140103976Spst if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 1141103976Spst (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 1142103976Spst (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1143103976Spst SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1144103976Spst ) 1145103976Spst { 1146103976Spst /* TODO: discovery error, callback */ 1147103976Spst DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1148103976Spst /* call back to notify discovery error */ 1149103976Spst onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1150103976Spst = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1151103976Spst onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1152103976Spst = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1153103976Spst onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1154103976Spst DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1155103976Spst onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1156103976Spst onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1157103976Spst onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1158103976Spst /* discovery done */ 1159103976Spst dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1160103976Spst } 1161103976Spst } 1162103976Spst else 1163103976Spst { 1164103976Spst /* Setup SAS address for up stream device */ 1165103976Spst oneExpander->hasUpStreamDevice = agTRUE; 1166103976Spst oneExpander->upStreamSASAddressHi = attachedSasHi; 1167103976Spst oneExpander->upStreamSASAddressLo = attachedSasLo; 1168103976Spst 1169103976Spst if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 1170103976Spst || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 1171103976Spst { 1172103976Spst /* Find the device from the discovered list */ 1173103976Spst AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1174103976Spst /* If the device has been discovered before */ 1175103976Spst if ( AttachedDevice != agNULL) 1176103976Spst { 1177103976Spst DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Seen This Device Before\n")); 1178103976Spst /* If attached device is an edge expander */ 1179103976Spst if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 1180200399Ssyrinx { 1181200399Ssyrinx /* The attached device is an expander */ 1182200399Ssyrinx AttachedExpander = AttachedDevice->dmExpander; 1183200399Ssyrinx /* If the two expanders are the root of the two edge expander sets */ 1184200399Ssyrinx if ( (AttachedExpander->upStreamSASAddressHi == 1185200399Ssyrinx DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1186200399Ssyrinx && (AttachedExpander->upStreamSASAddressLo == 1187200399Ssyrinx DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 1188200399Ssyrinx { 1189200399Ssyrinx /* Setup upstream expander for the pExpander */ 1190200399Ssyrinx oneExpander->dmUpStreamExpander = AttachedExpander; 1191200399Ssyrinx } 1192200399Ssyrinx /* If the two expanders are not the root of the two edge expander sets */ 1193200399Ssyrinx else 1194200399Ssyrinx { 1195200399Ssyrinx /* TODO: loop found, discovery error, callback */ 1196200399Ssyrinx DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error loop detection!!!\n")); 1197200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1198200399Ssyrinx = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1199200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1200200399Ssyrinx = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1201200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1202200399Ssyrinx DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1203200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1204200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1205200399Ssyrinx onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1206200399Ssyrinx /* discovery done */ 1207200399Ssyrinx dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1208200399Ssyrinx } 1209200399Ssyrinx } 1210200399Ssyrinx /* If attached device is not an edge expander */ 1211200399Ssyrinx else 1212200399Ssyrinx { 1213200399Ssyrinx /*TODO: should not happen, ASSERT */ 1214200399Ssyrinx DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 1215200399Ssyrinx } 1216200399Ssyrinx } 1217200399Ssyrinx /* If the device has not been discovered before */ 1218200399Ssyrinx else 1219200399Ssyrinx { 1220200399Ssyrinx /* Add the device */ 1221200399Ssyrinx DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: New device\n")); 1222200399Ssyrinx /* read minimum rate from the configuration 122341120Sjdp onePortContext->LinkRate is SPC's local link rate 122441120Sjdp */ 122541120Sjdp connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 122641120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 122741120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 122841120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 122941120Sjdp //hhhhhhhh 123041120Sjdp if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 123141120Sjdp { 123241120Sjdp /* incremental discovery */ 123341120Sjdp if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 123441120Sjdp { 123541120Sjdp AttachedDevice = dmPortSASDeviceAdd( 123641120Sjdp dmRoot, 123741120Sjdp onePortContext, 123841120Sjdp sasIdentify, 123941120Sjdp agFALSE, 124041120Sjdp connectionRate, 124141120Sjdp dmAllShared->itNexusTimeout, 124241120Sjdp 0, 124341120Sjdp STP_DEVICE_TYPE, 124441120Sjdp oneDeviceData, 124541120Sjdp oneExpander, 124641120Sjdp pDiscoverResp->phyIdentifier 124741120Sjdp ); 124841120Sjdp } 124941120Sjdp else 125041120Sjdp { 125141120Sjdp /* incremental discovery */ 125241120Sjdp AttachedDevice = dmFindRegNValid( 125341120Sjdp dmRoot, 125441120Sjdp onePortContext, 125541120Sjdp &dmSASSubID 125641120Sjdp ); 125741120Sjdp /* not registered and not valid; add this*/ 125841120Sjdp if (AttachedDevice == agNULL) 125941120Sjdp { 126041120Sjdp AttachedDevice = dmPortSASDeviceAdd( 126141120Sjdp dmRoot, 126241120Sjdp onePortContext, 1263103976Spst sasIdentify, 1264103976Spst agFALSE, 1265103976Spst connectionRate, 1266103976Spst dmAllShared->itNexusTimeout, 1267103976Spst 0, 1268103976Spst STP_DEVICE_TYPE, 1269103976Spst oneDeviceData, 1270103976Spst oneExpander, 1271103976Spst pDiscoverResp->phyIdentifier 1272103976Spst ); 1273103976Spst } 1274103976Spst } 1275103976Spst } 1276103976Spst else 1277103976Spst { 1278103976Spst /* incremental discovery */ 1279103976Spst if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1280103976Spst { 1281103976Spst AttachedDevice = dmPortSASDeviceAdd( 1282103976Spst dmRoot, 1283103976Spst onePortContext, 1284103976Spst sasIdentify, 1285103976Spst agFALSE, 1286103976Spst connectionRate, 1287103976Spst dmAllShared->itNexusTimeout, 1288103976Spst 0, 1289103976Spst SAS_DEVICE_TYPE, 1290103976Spst oneDeviceData, 1291103976Spst oneExpander, 1292103976Spst pDiscoverResp->phyIdentifier 1293103976Spst ); 1294103976Spst } 1295103976Spst else 1296103976Spst { 1297103976Spst /* incremental discovery */ 1298103976Spst AttachedDevice = dmFindRegNValid( 1299103976Spst dmRoot, 1300103976Spst onePortContext, 1301103976Spst &dmSASSubID 1302103976Spst ); 1303103976Spst /* not registered and not valid; add this*/ 1304103976Spst if (AttachedDevice == agNULL) 1305103976Spst { 1306103976Spst AttachedDevice = dmPortSASDeviceAdd( 1307103976Spst dmRoot, 1308103976Spst onePortContext, 1309103976Spst sasIdentify, 1310103976Spst agFALSE, 1311103976Spst connectionRate, 1312103976Spst dmAllShared->itNexusTimeout, 1313103976Spst 0, 1314103976Spst SAS_DEVICE_TYPE, 1315103976Spst oneDeviceData, 1316103976Spst oneExpander, 1317103976Spst pDiscoverResp->phyIdentifier 1318103976Spst ); 1319103976Spst } 1320103976Spst } 1321103976Spst } 1322103976Spst /* If the device is added successfully */ 1323103976Spst if ( AttachedDevice != agNULL) 1324103976Spst { 1325103976Spst 1326103976Spst /* (3.1.2.3.2.3.2.1) callback about new device */ 1327103976Spst if ( SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp) 1328199802Sattilio || SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 1329199802Sattilio || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 1330199802Sattilio || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 1331199802Sattilio { 1332202751Semaste DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 1333103976Spst attachedSasHi, attachedSasLo)); 1334199802Sattilio } 1335103976Spst else 1336103976Spst { 1337103976Spst DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found a SAS STP device.\n")); 1338103976Spst } 1339103976Spst /* If the attached device is an expander */ 1340103976Spst if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1341103976Spst || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 1342103976Spst { 1343103976Spst /* Allocate an expander data structure */ 1344103976Spst AttachedExpander = dmDiscoveringExpanderAlloc( 1345103976Spst dmRoot, 1346103976Spst onePortContext, 1347103976Spst AttachedDevice 1348103976Spst ); 1349103976Spst 1350103976Spst DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found expander=%p\n", AttachedExpander)); 1351103976Spst /* If allocate successfully */ 1352103976Spst if ( AttachedExpander != agNULL) 1353103976Spst { 1354103976Spst /* Add the pAttachedExpander to discovering list */ 1355103976Spst dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1356103976Spst /* Setup upstream expander for the pExpander */ 1357103976Spst oneExpander->dmUpStreamExpander = AttachedExpander; 1358103976Spst } 1359103976Spst /* If failed to allocate */ 1360103976Spst else 136141120Sjdp { 136241120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 136341120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 136441120Sjdp } 136541120Sjdp } 136641120Sjdp /* If the attached device is an end device */ 136741120Sjdp else 136841120Sjdp { 136941120Sjdp DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found end device\n")); 137041120Sjdp /* LP2006-05-26 added upstream device to the newly found device */ 137141120Sjdp AttachedDevice->dmExpander = oneExpander; 137241120Sjdp oneExpander->dmUpStreamExpander = agNULL; 137341120Sjdp } 137441120Sjdp } 137541120Sjdp else 137641120Sjdp { 137741120Sjdp DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 137841120Sjdp dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 137941120Sjdp } 138041120Sjdp } 138141120Sjdp } 138241120Sjdp } 138341120Sjdp } /* substractive routing */ 138441120Sjdp } 138541120Sjdp } 1386 1387 oneExpander->discoveringPhyId ++; 1388 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 1389 { 1390 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 1391 { 1392 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 1393 /* continue discovery for the next phy */ 1394 dmDiscoverSend(dmRoot, oneDeviceData); 1395 } 1396 else 1397 { 1398 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 1399 1400 /* for MCN */ 1401 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 1402 /* remove the expander from the discovering list */ 1403 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 1404 /* continue upstream discovering */ 1405 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 1406 } 1407 } 1408 else 1409 { 1410 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1411 1412 } 1413 1414 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 1415 1416 return; 1417} 1418 1419 1420osGLOBAL void 1421dmDownStreamDiscoverExpanderPhy( 1422 dmRoot_t *dmRoot, 1423 dmIntPortContext_t *onePortContext, 1424 dmExpander_t *oneExpander, 1425 smpRespDiscover_t *pDiscoverResp 1426 ) 1427{ 1428 agsaSASIdentify_t sasIdentify; 1429 dmSASSubID_t dmSASSubID; 1430 bit32 attachedSasHi, attachedSasLo; 1431 dmExpander_t *AttachedExpander; 1432 dmExpander_t *UpStreamExpander; 1433 dmExpander_t *ConfigurableExpander = agNULL; 1434 bit8 connectionRate, negotiatedPhyLinkRate; 1435 bit32 configSASAddressHi; 1436 bit32 configSASAddressLo; 1437 bit32 dupConfigSASAddr = agFALSE; 1438 dmDeviceData_t *oneDeviceData; 1439 dmDeviceData_t *AttachedDevice = agNULL; 1440 bit32 SAS2SAS11Check = agFALSE; 1441 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1442 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1443 1444 1445 1446 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: start\n")); 1447 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1448 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1449 1450 DM_ASSERT(dmRoot, "(dmDownStreamDiscoverExpanderPhy) dmRoot NULL"); 1451 DM_ASSERT(onePortContext, "(dmDownStreamDiscoverExpanderPhy) pPort NULL"); 1452 DM_ASSERT(oneExpander, "(dmDownStreamDiscoverExpanderPhy) pExpander NULL"); 1453 DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscoverExpanderPhy) pDiscoverResp NULL"); 1454 1455 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p\n", onePortContext, oneExpander)); 1456 1457 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1458 { 1459 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 1460 return; 1461 } 1462 1463 if (oneExpander != oneExpander->dmDevice->dmExpander) 1464 { 1465 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: wrong!!!\n")); 1466 } 1467 1468 /* (1) Find the device structure of the expander */ 1469 oneDeviceData = oneExpander->dmDevice; 1470 1471 DM_ASSERT(oneDeviceData, "(dmDownStreamDiscoverExpanderPhy) pDevice NULL"); 1472 1473 /* for debugging */ 1474 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 1475 oneExpander->discoveringPhyId, 1476 oneDeviceData->SASAddressID.sasAddressHi, 1477 oneDeviceData->SASAddressID.sasAddressLo)); 1478 1479 DM_DBG3((" Attached device: %s\n", 1480 ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 1481 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 1482 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 1483 1484 1485 /* for debugging */ 1486 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 1487 { 1488 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 1489 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 1490 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 1491 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1492 return; 1493 } 1494 1495 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1496 { 1497 DM_DBG3((" SAS address : %08x-%08x\n", 1498 DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 1499 DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 1500 DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 1501 DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 1502 DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1503 DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1504 DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1505 DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 1506 DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 1507 DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 1508 DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 1509 1510 } 1511 /* end for debugging */ 1512 1513 /* saving routing attribute for non self-configuring expanders */ 1514 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 1515 1516 oneExpander->discoverSMPAllowed = agTRUE; 1517 1518 /* If a device is attached */ 1519 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1520 { 1521 /* Setup sasIdentify for the attached device */ 1522 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1523 sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceType & 0x70; 1524 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1525 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1526 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1527 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1528 1529 /* incremental discovery */ 1530 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1531 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1532 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1533 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1534 1535 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1536 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1537 1538 /* If it's a direct routing */ 1539 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 1540 { 1541 /* If the attached device is an expander */ 1542 if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1543 || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 1544 1545 { 1546 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 1547 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1548 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1549 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1550 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1551 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1552 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1553 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1554 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1555 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1556 1557 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1558 return; 1559 } 1560 } 1561 1562 /* If the expander's attached device is not myself */ 1563 if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 1564 || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 1565 { 1566 /* Find the attached device from discovered list */ 1567 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1568 /* If the device has not been discovered before */ 1569 if ( AttachedDevice == agNULL) //11 1570 { 1571 /* If the phy has subtractive routing attribute */ 1572 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 1573 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1574 DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1575 ) 1576 { 1577 /* TODO: discovery error, callback */ 1578 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Deferred!!! **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1579 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1580 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1581 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1582 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1583 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1584 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1585 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1586 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1587 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1588 1589 onePortContext->discovery.DeferredError = agTRUE; 1590 } 1591 else /* 11 */ 1592 { 1593 /* Add the device */ 1594 /* read minimum rate from the configuration 1595 onePortContext->LinkRate is SPC's local link rate 1596 */ 1597 connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 1598 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 1599 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 1600 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 1601 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 1602 { 1603 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1604 { 1605 AttachedDevice = dmPortSASDeviceAdd( 1606 dmRoot, 1607 onePortContext, 1608 sasIdentify, 1609 agFALSE, 1610 connectionRate, 1611 dmAllShared->itNexusTimeout, 1612 0, 1613 STP_DEVICE_TYPE, 1614 oneDeviceData, 1615 oneExpander, 1616 pDiscoverResp->phyIdentifier 1617 ); 1618 } 1619 else 1620 { 1621 /* incremental discovery */ 1622 AttachedDevice = dmFindRegNValid( 1623 dmRoot, 1624 onePortContext, 1625 &dmSASSubID 1626 ); 1627 /* not registered and not valid; add this*/ 1628 if (AttachedDevice == agNULL) 1629 { 1630 AttachedDevice = dmPortSASDeviceAdd( 1631 dmRoot, 1632 onePortContext, 1633 sasIdentify, 1634 agFALSE, 1635 connectionRate, 1636 dmAllShared->itNexusTimeout, 1637 0, 1638 STP_DEVICE_TYPE, 1639 oneDeviceData, 1640 oneExpander, 1641 pDiscoverResp->phyIdentifier 1642 ); 1643 } 1644 } 1645 } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 1646 else /* 22 */ 1647 { 1648 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1649 { 1650 AttachedDevice = dmPortSASDeviceAdd( 1651 dmRoot, 1652 onePortContext, 1653 sasIdentify, 1654 agFALSE, 1655 connectionRate, 1656 dmAllShared->itNexusTimeout, 1657 0, 1658 SAS_DEVICE_TYPE, 1659 oneDeviceData, 1660 oneExpander, 1661 pDiscoverResp->phyIdentifier 1662 ); 1663 } 1664 else 1665 { 1666 /* incremental discovery */ 1667 AttachedDevice = dmFindRegNValid( 1668 dmRoot, 1669 onePortContext, 1670 &dmSASSubID 1671 ); 1672 /* not registered and not valid; add this*/ 1673 if (AttachedDevice == agNULL) 1674 { 1675 AttachedDevice = dmPortSASDeviceAdd( 1676 dmRoot, 1677 onePortContext, 1678 sasIdentify, 1679 agFALSE, 1680 connectionRate, 1681 dmAllShared->itNexusTimeout, 1682 0, 1683 SAS_DEVICE_TYPE, 1684 oneDeviceData, 1685 oneExpander, 1686 pDiscoverResp->phyIdentifier 1687 ); 1688 } 1689 } 1690 } /* else 22 */ 1691 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 1692 /* If the device is added successfully */ 1693 if ( AttachedDevice != agNULL) 1694 { 1695 if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 1696 || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 1697 || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 1698 || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 1699 { 1700 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n")); 1701 1702 } 1703 else 1704 { 1705 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 1706 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 1707 { 1708 1709 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n")); 1710 } 1711 else 1712 { 1713 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Other type of device.\n")); 1714 } 1715 } 1716 1717 /* LP2006-05-26 added upstream device to the newly found device */ 1718 AttachedDevice->dmExpander = oneExpander; 1719 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 1720 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 1721 1722 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 1723 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 1724 1725 /* If the phy has table routing attribute */ 1726 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1727 { 1728 /* If the attached device is a fan out expander */ 1729 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1730 { 1731 /* TODO: discovery error, callback */ 1732 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 1733 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1734 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1735 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1736 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1737 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1738 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1739 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1740 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1741 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1742 /* discovery done */ 1743 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1744 } 1745 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1746 { 1747 /* Allocate an expander data structure */ 1748 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 1749 1750 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 1751 /* If allocate successfully */ 1752 if ( AttachedExpander != agNULL) 1753 { 1754 /* set up downstream information on configurable expander */ 1755 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1756 /* Setup upstream information */ 1757 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1758 AttachedExpander->hasUpStreamDevice = agTRUE; 1759 AttachedExpander->upStreamSASAddressHi 1760 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1761 AttachedExpander->upStreamSASAddressLo 1762 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1763 AttachedExpander->dmUpStreamExpander = oneExpander; 1764 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 1765 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1766 } 1767 /* If failed to allocate */ 1768 else 1769 { 1770 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 1771 /* discovery done */ 1772 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1773 } 1774 } 1775 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1776 /* If status is still DISCOVERY_DOWN_STREAM */ 1777 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1778 { 1779 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before\n")); 1780 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1781 UpStreamExpander = oneExpander->dmUpStreamExpander; 1782 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1783 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1784 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1785 if (ConfigurableExpander) 1786 { 1787 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1788 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1789 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1790 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1791 ) 1792 { /* directly attached between oneExpander and ConfigurableExpander */ 1793 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 1\n")); 1794 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1795 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1796 } 1797 else 1798 { 1799 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 2\n")); 1800 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1801 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1802 } 1803 } /* if !ConfigurableExpander */ 1804 1805 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 1806 ConfigurableExpander, 1807 configSASAddressHi, 1808 configSASAddressLo 1809 ); 1810 1811 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 1812 { 1813 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st q123\n")); 1814 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 1815 ConfigurableExpander->currentDownStreamPhyIndex = 1816 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 1817 ConfigurableExpander->dmReturnginExpander = oneExpander; 1818 dmRoutingEntryAdd(dmRoot, 1819 ConfigurableExpander, 1820 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 1821 configSASAddressHi, 1822 configSASAddressLo 1823 ); 1824 } 1825 } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 1826 } /* AttachedDevice != agNULL */ 1827 /* If fail to add the device */ 1828 else 1829 { 1830 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 1831 /* discovery done */ 1832 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1833 } 1834 } /* else 11 */ 1835 } /* AttachedDevice == agNULL */ 1836 /* If the device has been discovered before */ 1837 else /* haha discovered before 33 */ 1838 { 1839 /* If the phy has subtractive routing attribute */ 1840 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1841 { 1842 /* If the expander doesn't have up stream device */ 1843 if ( oneExpander->hasUpStreamDevice == agFALSE) 1844 { 1845 /* TODO: discovery error, callback */ 1846 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 1847 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1848 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1849 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1850 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1851 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1852 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1853 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1854 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1855 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1856 /* discovery done */ 1857 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1858 } 1859 /* If the expander has up stream device */ 1860 else /* 44 */ 1861 { 1862 /* If sas address doesn't match */ 1863 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 1864 || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 1865 { 1866 /* TODO: discovery error, callback */ 1867 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two subtractive phys!!!\n")); 1868 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1869 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1870 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1871 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1872 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1873 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1874 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1875 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1876 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1877 /* discovery done */ 1878 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1879 } 1880 } /* else 44 */ 1881 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 1882 /* If the phy has table routing attribute */ 1883 else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1884 { 1885 /* If the attached device is a fan out expander */ 1886 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1887 { 1888 /* (2.3.3.2.1.1) TODO: discovery error, callback */ 1889 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 1890 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1891 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1892 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1893 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1894 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1895 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1896 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1897 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1898 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1899 /* discovery done */ 1900 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1901 } 1902 /* If the attached device is an edge expander */ 1903 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1904 { 1905 /* Setup up stream inform */ 1906 AttachedExpander = AttachedDevice->dmExpander; 1907 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 1908 /* If the attached expander has up stream device */ 1909 if ( AttachedExpander->hasUpStreamDevice == agTRUE) 1910 { 1911 /* compare the sas address */ 1912 if ( (AttachedExpander->upStreamSASAddressHi 1913 != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1914 || (AttachedExpander->upStreamSASAddressLo 1915 != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 1916 { 1917 /* TODO: discovery error, callback */ 1918 SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander, oneExpander, oneExpander); 1919 if (SAS2SAS11Check == agTRUE) 1920 { 1921 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 1922 } 1923 else 1924 { 1925 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 1926 } 1927 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1928 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1929 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1930 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1931 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1932 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1933 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1934 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1935 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1936 /* discovery done */ 1937 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1938 } 1939 else 1940 { 1941 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 1942 /* set up downstream information on configurable expander */ 1943 1944 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1945 /* haha */ 1946 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1947 /* Add the pAttachedExpander to discovering list */ 1948 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1949 } 1950 } /* AttachedExpander->hasUpStreamDevice == agTRUE */ 1951 /* If the attached expander doesn't have up stream device */ 1952 else 1953 { 1954 /* TODO: discovery error, callback */ 1955 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 1956 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1957 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1958 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1959 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1960 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1961 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1962 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1963 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1964 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1965 /* discovery done */ 1966 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1967 } 1968 } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE */ 1969 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1970 /* do this regradless of sub or table */ 1971 /* If status is still DISCOVERY_DOWN_STREAM */ 1972 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1973 { 1974 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before\n")); 1975 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1976 1977 UpStreamExpander = oneExpander->dmUpStreamExpander; 1978 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1979 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1980 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1981 if (ConfigurableExpander) 1982 { 1983 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1984 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1985 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1986 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1987 ) 1988 { /* directly attached between oneExpander and ConfigurableExpander */ 1989 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 1\n")); 1990 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1991 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1992 } 1993 else 1994 { 1995 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 2\n")); 1996 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1997 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1998 } 1999 } /* if !ConfigurableExpander */ 2000 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2001 ConfigurableExpander, 2002 configSASAddressHi, 2003 configSASAddressLo 2004 ); 2005 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2006 { 2007 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd q123 \n")); 2008 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2009 ConfigurableExpander->currentDownStreamPhyIndex = 2010 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2011 ConfigurableExpander->dmReturnginExpander = oneExpander; 2012 dmRoutingEntryAdd(dmRoot, 2013 ConfigurableExpander, 2014 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2015 configSASAddressHi, 2016 configSASAddressLo 2017 ); 2018 } 2019 } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 2020 /* incremental discovery */ 2021 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2022 { 2023 connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 2024 2025 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2026 { 2027 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SATA_STP\n")); 2028 2029 dmPortSASDeviceAdd( 2030 dmRoot, 2031 onePortContext, 2032 sasIdentify, 2033 agFALSE, 2034 connectionRate, 2035 dmAllShared->itNexusTimeout, 2036 0, 2037 STP_DEVICE_TYPE, 2038 oneDeviceData, 2039 oneExpander, 2040 pDiscoverResp->phyIdentifier 2041 ); 2042 } 2043 else 2044 { 2045 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SAS\n")); 2046 2047 2048 dmPortSASDeviceAdd( 2049 dmRoot, 2050 onePortContext, 2051 sasIdentify, 2052 agFALSE, 2053 connectionRate, 2054 dmAllShared->itNexusTimeout, 2055 0, 2056 SAS_DEVICE_TYPE, 2057 oneDeviceData, 2058 oneExpander, 2059 pDiscoverResp->phyIdentifier 2060 ); 2061 2062 } 2063 } /* onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START */ 2064 } /* else 33 */ 2065 } /* (attachedSasLo != onePortContext->sasLocalAddressLo) */ 2066 2067 else /* else 44 */ 2068 { 2069 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Self\n")); 2070 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd before\n")); 2071 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2072 2073 UpStreamExpander = oneExpander->dmUpStreamExpander; 2074 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2075 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2076 ConfigurableExpander, 2077 onePortContext->sasLocalAddressHi, 2078 onePortContext->sasLocalAddressLo 2079 ); 2080 2081 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2082 { 2083 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd q123 Setup routing table\n")); 2084 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2085 ConfigurableExpander->currentDownStreamPhyIndex = 2086 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2087 ConfigurableExpander->dmReturnginExpander = oneExpander; 2088 dmRoutingEntryAdd(dmRoot, 2089 ConfigurableExpander, 2090 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2091 onePortContext->sasLocalAddressHi, 2092 onePortContext->sasLocalAddressLo 2093 ); 2094 } 2095 } /* else 44 */ 2096 } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 2097 /* If no device is attached */ 2098 else 2099 { 2100 2101 DM_DBG2(("!!!!!!!!!!!!!!!!!!!!! SPIN SATA !!!!!!!!!!!!!!!!!!!!!!!!!!!\n")); 2102 negotiatedPhyLinkRate = DISCRSP_GET_LINKRATE(pDiscoverResp); // added by thenil 2103 2104 if (negotiatedPhyLinkRate == 0x03) 2105 { 2106 2107 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: SPIN SATA sent reset\n")); 2108 dmPhyControlSend(dmRoot, 2109 oneDeviceData, 2110 SMP_PHY_CONTROL_HARD_RESET, 2111 pDiscoverResp->phyIdentifier 2112 ); 2113 } 2114 2115 /* do nothing */ 2116 } 2117 2118 2119 /* Increment the discovering phy id */ 2120 oneExpander->discoveringPhyId ++; 2121 2122 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 2123 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 2124 { 2125 /* If not the last phy */ 2126 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 2127 { 2128 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: More Phys to discover\n")); 2129 /* continue discovery for the next phy */ 2130 dmDiscoverSend(dmRoot, oneDeviceData); 2131 } 2132 /* If the last phy */ 2133 else 2134 { 2135 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: No More Phys\n")); 2136 2137 /* for MCN */ 2138 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 2139 /* remove the expander from the discovering list */ 2140 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 2141 /* continue downstream discovering */ 2142 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 2143 } 2144 } 2145 else 2146 { 2147 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 2148 } 2149 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 2150 2151 return; 2152} 2153 2154 2155/* works at SAS2 expander (called in dmDownStreamDiscover2ExpanderPhy()) 2156 if currentExpander is SAS2, called in dmDownStreamDiscover2ExpanderPhy() 2157 if currentExpander is SAS1.1, called in dmDownStreamDiscoverExpanderPhy() 2158*/ 2159osGLOBAL bit32 2160dmSAS2SAS11ErrorCheck( 2161 dmRoot_t *dmRoot, 2162 dmIntPortContext_t *onePortContext, 2163 dmExpander_t *topExpander, 2164 dmExpander_t *bottomExpander, 2165 dmExpander_t *currentExpander 2166 ) 2167{ 2168 bit32 result = agFALSE, i = 0; 2169 bit8 downStreamPhyID, upStreamPhyID; 2170 2171 DM_DBG2(("dmSAS2SAS11ErrorCheck: start\n")); 2172 2173 if (topExpander == agNULL) 2174 { 2175 DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander is NULL\n")); 2176 return result; 2177 } 2178 if (bottomExpander == agNULL) 2179 { 2180 DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander is NULL\n")); 2181 return result; 2182 } 2183 2184 if (currentExpander == agNULL) 2185 { 2186 DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander is NULL\n")); 2187 return result; 2188 } 2189 2190 DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander addrHi 0x%08x addrLo 0x%08x\n", 2191 topExpander->dmDevice->SASAddressID.sasAddressHi, topExpander->dmDevice->SASAddressID.sasAddressLo)); 2192 DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander addrHi 0x%08x addrLo 0x%08x\n", 2193 bottomExpander->dmDevice->SASAddressID.sasAddressHi, bottomExpander->dmDevice->SASAddressID.sasAddressLo)); 2194 DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander addrHi 0x%08x addrLo 0x%08x\n", 2195 currentExpander->dmDevice->SASAddressID.sasAddressHi, currentExpander->dmDevice->SASAddressID.sasAddressLo)); 2196 2197 for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2198 { 2199 downStreamPhyID = topExpander->downStreamPhys[i]; 2200 upStreamPhyID = bottomExpander->upStreamPhys[i]; 2201 if (currentExpander->SAS2 == 1) 2202 { 2203 if ( downStreamPhyID == upStreamPhyID && 2204 topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_TABLE && 2205 bottomExpander->routingAttribute[i] == SAS_ROUTING_SUBTRACTIVE && 2206 topExpander->SAS2 == 0 && 2207 bottomExpander->SAS2 == 1 2208 ) 2209 { 2210 result = agTRUE; 2211 break; 2212 } 2213 } 2214 else if (currentExpander->SAS2 == 0) 2215 { 2216 if ( downStreamPhyID == upStreamPhyID && 2217 topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_SUBTRACTIVE && 2218 bottomExpander->routingAttribute[i] == SAS_ROUTING_TABLE && 2219 topExpander->SAS2 == 1 && 2220 bottomExpander->SAS2 == 0 2221 ) 2222 { 2223 result = agTRUE; 2224 break; 2225 } 2226 } 2227 } 2228 return result; 2229} 2230 2231osGLOBAL void 2232dmDownStreamDiscover2ExpanderPhy( 2233 dmRoot_t *dmRoot, 2234 dmIntPortContext_t *onePortContext, 2235 dmExpander_t *oneExpander, 2236 smpRespDiscover2_t *pDiscoverResp 2237 ) 2238{ 2239 dmDeviceData_t *oneDeviceData; 2240 dmExpander_t *UpStreamExpander; 2241 dmDeviceData_t *AttachedDevice = agNULL; 2242 dmExpander_t *AttachedExpander; 2243 agsaSASIdentify_t sasIdentify; 2244 bit8 connectionRate; 2245 bit32 attachedSasHi, attachedSasLo; 2246 dmSASSubID_t dmSASSubID; 2247 dmExpander_t *ConfigurableExpander = agNULL; 2248 bit32 dupConfigSASAddr = agFALSE; 2249 bit32 configSASAddressHi; 2250 bit32 configSASAddressLo; 2251 bit32 SAS2SAS11Check = agFALSE; 2252 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 2253 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 2254 2255 2256 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: start\n")); 2257 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 2258 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 2259 2260 DM_ASSERT(dmRoot, "(dmDownStreamDiscover2ExpanderPhy) dmRoot NULL"); 2261 DM_ASSERT(onePortContext, "(dmDownStreamDiscover2ExpanderPhy) pPort NULL"); 2262 DM_ASSERT(oneExpander, "(dmDownStreamDiscover2ExpanderPhy) pExpander NULL"); 2263 DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscover2ExpanderPhy) pDiscoverResp NULL"); 2264 2265 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->dmDevice)); 2266 2267 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 2268 { 2269 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 2270 return; 2271 } 2272 2273 if (oneExpander != oneExpander->dmDevice->dmExpander) 2274 { 2275 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: wrong!!!\n")); 2276 } 2277 2278 2279 /* (1) Find the device structure of the expander */ 2280 oneDeviceData = oneExpander->dmDevice; 2281 2282 DM_ASSERT(oneDeviceData, "(dmDownStreamDiscover2ExpanderPhy) pDevice NULL"); 2283 2284 /* for debugging */ 2285 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 2286 oneExpander->discoveringPhyId, 2287 oneDeviceData->SASAddressID.sasAddressHi, 2288 oneDeviceData->SASAddressID.sasAddressLo)); 2289 2290 DM_DBG2((" Attached device: %s\n", 2291 ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 2292 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 2293 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 2294 2295 2296 /* for debugging */ 2297 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 2298 { 2299 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 2300 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 2301 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 2302 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2303 return; 2304 } 2305 2306 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2307 { 2308 DM_DBG2((" SAS address : %08x-%08x\n", 2309 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 2310 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 2311 DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 2312 DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 2313 DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 2314 DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 2315 DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 2316 DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 2317 DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 2318 DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 2319 DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 2320 2321 } 2322 2323 /* saving routing attribute for non self-configuring expanders */ 2324 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 2325 2326 2327 oneExpander->discoverSMPAllowed = agTRUE; 2328 2329 /* If a device is attached */ 2330 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2331 { 2332 /* Setup sasIdentify for the attached device */ 2333 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 2334 sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 2335 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 2336 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 2337 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 2338 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 2339 2340 /* incremental discovery */ 2341 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 2342 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 2343 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 2344 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 2345 2346 attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 2347 attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 2348 2349 /* If it's a direct routing */ 2350 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 2351 { 2352 /* If the attached device is an expander */ 2353 if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2354 || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 2355 2356 { 2357 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 2358 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2359 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2360 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2361 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2362 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2363 2364 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2365 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2366 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2367 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2368 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2369 2370 return; 2371 } 2372 } 2373 2374 /* If the expander's attached device is not myself */ 2375 if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 2376 || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 2377 { 2378 /* Find the attached device from discovered list */ 2379 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 2380 /* If the device has not been discovered before */ 2381 if ( AttachedDevice == agNULL) //11 2382 { 2383 //qqqqqq 2384 if (0) 2385 { 2386 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 2387 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2388 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2389 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2390 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2391 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2392 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2393 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2394 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2395 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2396 /* discovery done */ 2397 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2398 } 2399 else 2400 { 2401 /* Add the device */ 2402 /* read minimum rate from the configuration 2403 onePortContext->LinkRate is SPC's local link rate 2404 */ 2405 connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2406 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 2407 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 2408 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 2409 2410 if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2411 { 2412 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2413 { 2414 AttachedDevice = dmPortSASDeviceAdd( 2415 dmRoot, 2416 onePortContext, 2417 sasIdentify, 2418 agFALSE, 2419 connectionRate, 2420 dmAllShared->itNexusTimeout, 2421 0, 2422 STP_DEVICE_TYPE, 2423 oneDeviceData, 2424 oneExpander, 2425 pDiscoverResp->phyIdentifier 2426 ); 2427 } 2428 else 2429 { 2430 /* incremental discovery */ 2431 AttachedDevice = dmFindRegNValid( 2432 dmRoot, 2433 onePortContext, 2434 &dmSASSubID 2435 ); 2436 /* not registered and not valid; add this*/ 2437 if (AttachedDevice == agNULL) 2438 { 2439 AttachedDevice = dmPortSASDeviceAdd( 2440 dmRoot, 2441 onePortContext, 2442 sasIdentify, 2443 agFALSE, 2444 connectionRate, 2445 dmAllShared->itNexusTimeout, 2446 0, 2447 STP_DEVICE_TYPE, 2448 oneDeviceData, 2449 oneExpander, 2450 pDiscoverResp->phyIdentifier 2451 ); 2452 } 2453 } 2454 } 2455 else 2456 { 2457 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2458 { 2459 AttachedDevice = dmPortSASDeviceAdd( 2460 dmRoot, 2461 onePortContext, 2462 sasIdentify, 2463 agFALSE, 2464 connectionRate, 2465 dmAllShared->itNexusTimeout, 2466 0, 2467 SAS_DEVICE_TYPE, 2468 oneDeviceData, 2469 oneExpander, 2470 pDiscoverResp->phyIdentifier 2471 ); 2472 } 2473 else 2474 { 2475 /* incremental discovery */ 2476 AttachedDevice = dmFindRegNValid( 2477 dmRoot, 2478 onePortContext, 2479 &dmSASSubID 2480 ); 2481 /* not registered and not valid; add this*/ 2482 if (AttachedDevice == agNULL) 2483 { 2484 AttachedDevice = dmPortSASDeviceAdd( 2485 dmRoot, 2486 onePortContext, 2487 sasIdentify, 2488 agFALSE, 2489 connectionRate, 2490 dmAllShared->itNexusTimeout, 2491 0, 2492 SAS_DEVICE_TYPE, 2493 oneDeviceData, 2494 oneExpander, 2495 pDiscoverResp->phyIdentifier 2496 ); 2497 } 2498 } 2499 } 2500 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 2501 /* If the device is added successfully */ 2502 if ( AttachedDevice != agNULL) 2503 { 2504 if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 2505 || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 2506 || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 2507 || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 2508 { 2509 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Report a new SAS device !!\n")); 2510 2511 } 2512 else 2513 { 2514 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 2515 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 2516 { 2517 2518 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found an STP or SATA device.\n")); 2519 } 2520 else 2521 { 2522 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Other type of device.\n")); 2523 } 2524 } 2525 2526 /* LP2006-05-26 added upstream device to the newly found device */ 2527 AttachedDevice->dmExpander = oneExpander; 2528 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 2529 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 2530 2531 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 2532 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 2533 2534 /* If the phy has table routing attribute */ 2535 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2536 { 2537 /* If the attached device is a fan out expander */ 2538 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2539 { 2540 /* TODO: discovery error, callback */ 2541 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 2542 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2543 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2544 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2545 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2546 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2547 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2548 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2549 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2550 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2551 /* discovery done */ 2552 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2553 } 2554 else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2555 { 2556 /* Allocate an expander data structure */ 2557 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2558 2559 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 2560 /* If allocate successfully */ 2561 if ( AttachedExpander != agNULL) 2562 { 2563 /* set up downstream information on configurable expander */ 2564 2565 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2566 2567 /* Setup upstream information */ 2568 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2569//qqqqq 2570 AttachedExpander->hasUpStreamDevice = agTRUE; 2571 AttachedExpander->upStreamSASAddressHi 2572 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2573 AttachedExpander->upStreamSASAddressLo 2574 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2575 AttachedExpander->dmUpStreamExpander = oneExpander; 2576 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2577 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2578 } 2579 /* If failed to allocate */ 2580 else 2581 { 2582 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 2583 /* discovery done */ 2584 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2585 } 2586 } 2587 } 2588 //qqqqq 2589 else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 2590 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE || 2591 SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2592 ) 2593 { 2594 /* Allocate an expander data structure */ 2595 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2596 2597 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE/FANOUT exp device.%p\n", AttachedExpander)); 2598 /* If allocate successfully */ 2599 if ( AttachedExpander != agNULL) 2600 { 2601 /* set up downstream information on configurable expander */ 2602 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2603 2604 /* Setup upstream information */ 2605 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2606 AttachedExpander->hasUpStreamDevice = agTRUE; 2607 AttachedExpander->upStreamSASAddressHi 2608 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2609 AttachedExpander->upStreamSASAddressLo 2610 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2611 AttachedExpander->dmUpStreamExpander = oneExpander; 2612 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2613 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2614 } 2615 /* If failed to allocate */ 2616 else 2617 { 2618 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure (2)!!!\n")); 2619 /* discovery done */ 2620 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2621 } 2622 2623 2624 } 2625 /* If status is still DISCOVERY_DOWN_STREAM */ 2626 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2627 onePortContext->discovery.ConfiguresOthers == agFALSE) 2628 { 2629 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before\n")); 2630 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2631 UpStreamExpander = oneExpander->dmUpStreamExpander; 2632 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2633 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2634 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2635 if (ConfigurableExpander) 2636 { 2637 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2638 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2639 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2640 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2641 ) 2642 { /* directly attached between oneExpander and ConfigurableExpander */ 2643 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 1\n")); 2644 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2645 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2646 } 2647 else 2648 { 2649 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 2\n")); 2650 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2651 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2652 } 2653 } /* if !ConfigurableExpander */ 2654 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2655 ConfigurableExpander, 2656 configSASAddressHi, 2657 configSASAddressLo 2658 ); 2659 2660 2661 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2662 { 2663 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st q123\n")); 2664 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2665 ConfigurableExpander->currentDownStreamPhyIndex = 2666 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2667 ConfigurableExpander->dmReturnginExpander = oneExpander; 2668 dmRoutingEntryAdd(dmRoot, 2669 ConfigurableExpander, 2670 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2671 configSASAddressHi, 2672 configSASAddressLo 2673 ); 2674 } 2675 } 2676 } 2677 /* If fail to add the device */ 2678 else 2679 { 2680 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 2681 /* discovery done */ 2682 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2683 } 2684 } 2685 } 2686 /* If the device has been discovered before */ 2687 else /* discovered before */ 2688 { 2689 /* If the phy has subtractive routing attribute */ 2690 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 2691 { 2692 /* If the expander doesn't have up stream device */ 2693 if ( oneExpander->hasUpStreamDevice == agFALSE) 2694 { 2695 /* TODO: discovery error, callback */ 2696 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 2697 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2698 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2699 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2700 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2701 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2702 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2703 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2704 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2705 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2706 /* discovery done */ 2707 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2708 } 2709 /* If the expander has up stream device */ 2710 else 2711 { 2712 2713//qqqqq 2714 /* If sas address doesn't match */ 2715 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 2716 || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 2717 { 2718 /* TODO: discovery error, callback */ 2719 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** two subtractive phys!!! Allowed in SAS2!!!\n")); 2720 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2721 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2722 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2723 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2724 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2725 onePortContext->discovery.DeferredError = agTRUE; 2726 2727 } 2728 } 2729 } 2730 /* If the phy has table routing attribute */ 2731 else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2732 { 2733 /* If the attached device is a fan out expander */ 2734 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2735 { 2736 /* (2.3.3.2.1.1) TODO: discovery error, callback */ 2737 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 2738 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2739 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2740 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2741 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2742 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2743 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2744 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2745 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2746 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2747 /* discovery done */ 2748 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2749 } 2750 /* If the attached device is an edge expander */ 2751 else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2752 { 2753 /* Setup up stream inform */ 2754 AttachedExpander = AttachedDevice->dmExpander; 2755 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 2756 //hhhhhh 2757 /* If the attached expander has up stream device */ 2758 if ( AttachedExpander->hasUpStreamDevice == agTRUE) 2759 { 2760 /* compare the sas address */ 2761 if ( (AttachedExpander->upStreamSASAddressHi 2762 != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 2763 || (AttachedExpander->upStreamSASAddressLo 2764 != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 2765 { 2766 if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2767 { 2768 /* 2769 needs further error checking 2770 UpstreamExpanderOfAttachedExpander = AttachedExpander->UpStreamExpander 2771 for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2772 { 2773 if (UpstreamExpanderOfAttachedExpander->downStreamPhys[i] != 0 && 2774 } 2775 */ 2776 SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander->dmUpStreamExpander, AttachedExpander, oneExpander); 2777 if (SAS2SAS11Check == agTRUE) 2778 { 2779 2780 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 2781 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2782 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2783 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2784 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2785 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2786 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2787 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2788 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2789 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2790 /* discovery done */ 2791 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2792 } 2793 else 2794 { 2795 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (1)\n")); 2796 /* move on to the next phys but should be not proceed after oneExpander */ 2797 oneExpander->UndoDueToTTTSupported = agTRUE; 2798 onePortContext->discovery.DeferredError = agFALSE; 2799 } 2800 } 2801 else 2802 { 2803 /* TODO: discovery error, callback */ 2804 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 2805 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2806 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2807 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2808 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2809 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2810 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2811 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2812 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2813 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2814 /* discovery done */ 2815 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2816 } 2817 } 2818 else 2819 { 2820 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 2821 /* set up downstream information on configurable expander */ 2822 2823 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2824 /* haha */ 2825 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2826 /* Add the pAttachedExpander to discovering list */ 2827 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2828 } 2829 } 2830 /* If the attached expander doesn't have up stream device */ 2831 else 2832 { 2833 if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2834 { 2835 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (2)\n")); 2836 /* move on to the next phys but should be not proceed after oneExpander */ 2837 oneExpander->UndoDueToTTTSupported = agTRUE; 2838 onePortContext->discovery.DeferredError = agFALSE; 2839 } 2840 else 2841 { 2842 /* TODO: discovery error, callback */ 2843 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 2844 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2845 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2846 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2847 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2848 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2849 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2850 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2851 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2852 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2853 /* discovery done */ 2854 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2855 } 2856 } 2857 } 2858 } /* for else if (SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) */ 2859 2860 /* do this regradless of sub or table */ 2861 /* If status is still DISCOVERY_DOWN_STREAM */ 2862 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2863 onePortContext->discovery.ConfiguresOthers == agFALSE) 2864 { 2865 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before\n")); 2866 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2867 2868 UpStreamExpander = oneExpander->dmUpStreamExpander; 2869 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2870 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2871 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2872 if (ConfigurableExpander) 2873 { 2874 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2875 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2876 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2877 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2878 ) 2879 { /* directly attached between oneExpander and ConfigurableExpander */ 2880 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 1\n")); 2881 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2882 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2883 } 2884 else 2885 { 2886 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 2\n")); 2887 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2888 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2889 } 2890 } /* if !ConfigurableExpander */ 2891 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2892 ConfigurableExpander, 2893 configSASAddressHi, 2894 configSASAddressLo 2895 ); 2896 2897 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2898 { 2899 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd q123 \n")); 2900 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2901 ConfigurableExpander->currentDownStreamPhyIndex = 2902 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2903 ConfigurableExpander->dmReturnginExpander = oneExpander; 2904 dmRoutingEntryAdd(dmRoot, 2905 ConfigurableExpander, 2906 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2907 configSASAddressHi, 2908 configSASAddressLo 2909 ); 2910 } 2911 } /* if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) */ 2912 /* incremental discovery */ 2913 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2914 { 2915 connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2916 2917 if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2918 { 2919 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SATA_STP\n")); 2920 2921 dmPortSASDeviceAdd( 2922 dmRoot, 2923 onePortContext, 2924 sasIdentify, 2925 agFALSE, 2926 connectionRate, 2927 dmAllShared->itNexusTimeout, 2928 0, 2929 STP_DEVICE_TYPE, 2930 oneDeviceData, 2931 oneExpander, 2932 pDiscoverResp->phyIdentifier 2933 ); 2934 } 2935 else 2936 { 2937 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SAS\n")); 2938 2939 dmPortSASDeviceAdd( 2940 dmRoot, 2941 onePortContext, 2942 sasIdentify, 2943 agFALSE, 2944 connectionRate, 2945 dmAllShared->itNexusTimeout, 2946 0, 2947 SAS_DEVICE_TYPE, 2948 oneDeviceData, 2949 oneExpander, 2950 pDiscoverResp->phyIdentifier 2951 ); 2952 2953 } 2954 } 2955 2956 2957 }/* else; existing devce */ 2958 } /* not attached to myself */ 2959 /* If the attached device is myself */ 2960 else 2961 { 2962 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Self\n")); 2963 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd before\n")); 2964 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2965 2966 if (onePortContext->discovery.ConfiguresOthers == agFALSE) 2967 { 2968 UpStreamExpander = oneExpander->dmUpStreamExpander; 2969 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2970 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2971 ConfigurableExpander, 2972 onePortContext->sasLocalAddressHi, 2973 onePortContext->sasLocalAddressLo 2974 ); 2975 2976 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2977 { 2978 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd q123 Setup routing table\n")); 2979 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2980 ConfigurableExpander->currentDownStreamPhyIndex = 2981 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2982 ConfigurableExpander->dmReturnginExpander = oneExpander; 2983 dmRoutingEntryAdd(dmRoot, 2984 ConfigurableExpander, 2985 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2986 onePortContext->sasLocalAddressHi, 2987 onePortContext->sasLocalAddressLo 2988 ); 2989 } 2990 } 2991 } 2992 } 2993 /* If no device is attached */ 2994 else 2995 { 2996 } 2997 2998 2999 /* Increment the discovering phy id */ 3000 oneExpander->discoveringPhyId ++; 3001 3002 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3003 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3004 { 3005 /* If not the last phy */ 3006 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3007 { 3008 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: More Phys to discover\n")); 3009 /* continue discovery for the next phy */ 3010 dmDiscoverSend(dmRoot, oneDeviceData); 3011 } 3012 /* If the last phy */ 3013 else 3014 { 3015 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: No More Phys\n")); 3016 3017 /* for MCN */ 3018 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3019 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 3020 if (oneExpander->UndoDueToTTTSupported == agTRUE && ConfigurableExpander != agNULL) 3021// if (oneExpander->UndoDueToTTTSupported == agTRUE) 3022 { 3023 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Not sure!!!\n")); 3024 dmDiscoveringUndoAdd(dmRoot, onePortContext, oneExpander); 3025 oneExpander->UndoDueToTTTSupported = agFALSE; 3026 } 3027 3028 /* remove the expander from the discovering list */ 3029 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3030 /* continue downstream discovering */ 3031 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3032 } 3033 } 3034 else 3035 { 3036 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3037 } 3038 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3039 3040 return; 3041} 3042 3043 3044osGLOBAL void 3045dmDiscoveringUndoAdd( 3046 dmRoot_t *dmRoot, 3047 dmIntPortContext_t *onePortContext, 3048 dmExpander_t *oneExpander 3049 ) 3050{ 3051 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3052 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3053 dmList_t *ExpanderList; 3054 dmExpander_t *tempExpander; 3055 dmIntPortContext_t *tmpOnePortContext = onePortContext; 3056 3057 DM_DBG2(("dmDiscoveringUndoAdd: start\n")); 3058 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3059 { 3060 DM_DBG2(("dmDiscoveringUndoAdd: empty discoveringExpanderList\n")); 3061 return; 3062 } 3063 3064// DM_DBG2(("dmDiscoveringUndoAdd: before\n")); 3065// dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3066 3067 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3068 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 3069 { 3070 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3071 if ( tempExpander == agNULL) 3072 { 3073 DM_DBG1(("dmDiscoveringUndoAdd: tempExpander is NULL!!!\n")); 3074 return; 3075 } 3076 if (tempExpander->dmUpStreamExpander == oneExpander) 3077 { 3078 DM_DBG2(("dmDiscoveringUndoAdd: match!!! expander id %d\n", tempExpander->id)); 3079 DM_DBG2(("dmDiscoveringUndoAdd: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 3080 DM_DBG2(("dmDiscoveringUndoAdd: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 3081 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 3082 DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 3083// DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 3084 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 3085 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 3086 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3087 } 3088 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3089 { 3090 DM_DBG2(("dmDiscoveringUndoAdd: hitting break\n")); 3091 break; 3092 } 3093 ExpanderList = ExpanderList->flink; 3094 } 3095 3096// DM_DBG2(("dmDiscoveringUndoAdd: after\n")); 3097// dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3098 return; 3099} 3100 3101osGLOBAL void 3102dmHandleZoneViolation( 3103 dmRoot_t *dmRoot, 3104 agsaRoot_t *agRoot, 3105 agsaIORequest_t *agIORequest, 3106 dmDeviceData_t *oneDeviceData, 3107 dmSMPFrameHeader_t *frameHeader, 3108 agsaFrameHandle_t frameHandle 3109 ) 3110{ 3111 dmIntPortContext_t *onePortContext = agNULL; 3112 dmExpander_t *oneExpander = agNULL; 3113 3114 DM_DBG1(("dmHandleZoneViolation: start\n")); 3115 DM_DBG1(("dmHandleZoneViolation: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3116 DM_DBG1(("dmHandleZoneViolation: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3117 onePortContext = oneDeviceData->dmPortContext; 3118 oneExpander = oneDeviceData->dmExpander; 3119 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 3120 { 3121 DM_DBG1(("dmHandleZoneViolation: invalid port or aborted discovery!!!\n")); 3122 return; 3123 } 3124 /* for MCN */ 3125 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3126 /* remove the expander from the discovering list */ 3127 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3128 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3129 { 3130 /* continue upstream discovering */ 3131 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3132 } 3133 else /* DISCOVERY_DOWN_STREAM or DISCOVERY_CONFIG_ROUTING */ 3134 { 3135 /* continue downstream discovering */ 3136 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3137 } 3138 return; 3139} 3140 3141 3142osGLOBAL void 3143dmUpStreamDiscoverExpanderPhySkip( 3144 dmRoot_t *dmRoot, 3145 dmIntPortContext_t *onePortContext, 3146 dmExpander_t *oneExpander 3147 ) 3148 3149{ 3150 dmDeviceData_t *oneDeviceData; 3151 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: start\n")); 3152 3153 oneDeviceData = oneExpander->dmDevice; 3154 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3155 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3156 3157 oneExpander->discoveringPhyId++; 3158 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3159 { 3160 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3161 { 3162 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3163 /* continue discovery for the next phy */ 3164 dmDiscoverSend(dmRoot, oneDeviceData); 3165 } 3166 else 3167 { 3168 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: No More Phys\n")); 3169 3170 /* for MCN */ 3171 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3172 /* remove the expander from the discovering list */ 3173 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3174 /* continue upstream discovering */ 3175 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3176 } 3177 } 3178 else 3179 { 3180 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3181 3182 } 3183 3184 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3185 3186 return; 3187} 3188 3189 3190osGLOBAL void 3191dmUpStreamDiscover2ExpanderPhySkip( 3192 dmRoot_t *dmRoot, 3193 dmIntPortContext_t *onePortContext, 3194 dmExpander_t *oneExpander 3195 ) 3196{ 3197 dmDeviceData_t *oneDeviceData; 3198 3199 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: start\n")); 3200 oneDeviceData = oneExpander->dmDevice; 3201 3202 oneExpander->discoveringPhyId++; 3203 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3204 { 3205 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3206 { 3207 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM find more ...\n")); 3208 /* continue discovery for the next phy */ 3209 dmDiscoverSend(dmRoot, oneDeviceData); 3210 } 3211 else 3212 { 3213 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 3214 3215 /* for MCN */ 3216 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3217 /* remove the expander from the discovering list */ 3218 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3219 /* continue upstream discovering */ 3220 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3221 } 3222 } 3223 else 3224 { 3225 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3226 } 3227 3228 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3229 3230 3231 return; 3232} 3233 3234osGLOBAL void 3235dmDownStreamDiscoverExpanderPhySkip( 3236 dmRoot_t *dmRoot, 3237 dmIntPortContext_t *onePortContext, 3238 dmExpander_t *oneExpander 3239 ) 3240{ 3241 dmDeviceData_t *oneDeviceData; 3242 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: start\n")); 3243 3244 oneDeviceData = oneExpander->dmDevice; 3245 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3246 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3247 3248 /* Increment the discovering phy id */ 3249 oneExpander->discoveringPhyId ++; 3250 3251 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3252 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3253 { 3254 /* If not the last phy */ 3255 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3256 { 3257 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3258 /* continue discovery for the next phy */ 3259 dmDiscoverSend(dmRoot, oneDeviceData); 3260 } 3261 /* If the last phy */ 3262 else 3263 { 3264 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: No More Phys\n")); 3265 3266 /* for MCN */ 3267 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3268 /* remove the expander from the discovering list */ 3269 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3270 /* continue downstream discovering */ 3271 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3272 } 3273 } 3274 else 3275 { 3276 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3277 } 3278 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3279 3280 3281 return; 3282} 3283 3284osGLOBAL void 3285dmDownStreamDiscover2ExpanderPhySkip( 3286 dmRoot_t *dmRoot, 3287 dmIntPortContext_t *onePortContext, 3288 dmExpander_t *oneExpander 3289 ) 3290{ 3291 dmDeviceData_t *oneDeviceData; 3292 3293 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: start\n")); 3294 3295 oneDeviceData = oneExpander->dmDevice; 3296 /* Increment the discovering phy id */ 3297 oneExpander->discoveringPhyId ++; 3298 3299 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3300 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3301 { 3302 /* If not the last phy */ 3303 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3304 { 3305 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: More Phys to discover\n")); 3306 /* continue discovery for the next phy */ 3307 dmDiscoverSend(dmRoot, oneDeviceData); 3308 } 3309 /* If the last phy */ 3310 else 3311 { 3312 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: No More Phys\n")); 3313 3314 /* for MCN */ 3315 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3316 /* remove the expander from the discovering list */ 3317 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3318 /* continue downstream discovering */ 3319 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3320 } 3321 } 3322 else 3323 { 3324 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3325 } 3326 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3327 return; 3328} 3329 3330osGLOBAL void 3331dmExpanderUpStreamPhyAdd( 3332 dmRoot_t *dmRoot, 3333 dmExpander_t *oneExpander, 3334 bit8 phyId 3335 ) 3336{ 3337 bit32 i; 3338 bit32 hasSet = agFALSE; 3339 3340 DM_DBG3(("dmExpanderUpStreamPhyAdd: start, phyid %d\n", phyId)); 3341 DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3342 DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3343 DM_DBG3(("dmExpanderUpStreamPhyAdd: phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3344 3345 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3346 { 3347 if ( oneExpander->upStreamPhys[i] == phyId ) 3348 { 3349 hasSet = agTRUE; 3350 break; 3351 } 3352 } 3353 3354 if ( hasSet == agFALSE ) 3355 { 3356 oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId; 3357 } 3358 3359 DM_DBG3(("dmExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3360 3361 /* for debugging */ 3362 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3363 { 3364 DM_DBG3(("dmExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i])); 3365 } 3366 return; 3367} 3368 3369osGLOBAL void 3370dmExpanderDownStreamPhyAdd( 3371 dmRoot_t *dmRoot, 3372 dmExpander_t *oneExpander, 3373 bit8 phyId 3374 ) 3375{ 3376 bit32 i; 3377 bit32 hasSet = agFALSE; 3378 3379 DM_DBG3(("dmExpanderDownStreamPhyAdd: start, phyid %d\n", phyId)); 3380 DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3381 DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3382 DM_DBG3(("dmExpanderDownStreamPhyAdd: phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3383 3384 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3385 { 3386 if ( oneExpander->downStreamPhys[i] == phyId ) 3387 { 3388 hasSet = agTRUE; 3389 break; 3390 } 3391 } 3392 3393 if ( hasSet == agFALSE ) 3394 { 3395 oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId; 3396 } 3397 3398 DM_DBG3(("dmExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3399 3400 /* for debugging */ 3401 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3402 { 3403 DM_DBG3(("dmExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i])); 3404 } 3405 return; 3406} 3407 3408osGLOBAL void 3409dmDiscoveryReportMCN( 3410 dmRoot_t *dmRoot, 3411 dmIntPortContext_t *onePortContext 3412 ) 3413{ 3414 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3415 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3416 dmDeviceData_t *oneDeviceData = agNULL; 3417 dmList_t *DeviceListList; 3418 bit16 extension = 0; 3419 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3420 3421 DM_DBG2(("dmDiscoveryReportMCN: start\n")); 3422 3423/* 3424 if full disocvery, report all devices using MCN 3425 if incremental discovery, 3426 1. compare MCN and PrevMCN 3427 2. report the changed ones; report MCN 3428 3. set PrevMCN to MCN 3429 PrevMCN = MCN 3430*/ 3431 3432 DeviceListList = dmAllShared->MainDeviceList.flink; 3433 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3434 { 3435 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3436 if ( oneDeviceData == agNULL) 3437 { 3438 DM_DBG1(("dmDiscoveryReportMCN: oneDeviceData is NULL!!!\n")); 3439 return; 3440 } 3441 DM_DBG3(("dmDiscoveryReportMCN: loop did %d\n", oneDeviceData->id)); 3442 if (oneDeviceData->dmPortContext == onePortContext) 3443 { 3444 DM_DBG2(("dmDiscoveryReportMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3445 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3446 DM_DBG2(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3447 3448 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3449 { 3450 DM_DBG2(("dmDiscoveryReportMCN: FULL_START\n")); 3451 } 3452 else 3453 { 3454 DM_DBG2(("dmDiscoveryReportMCN: INCREMENTAL_START\n")); 3455 } 3456 /* 3457 if MCN is 0, the device is removed 3458 */ 3459 if (oneDeviceData->MCN != oneDeviceData->PrevMCN && oneDeviceData->MCN != 0) 3460 { 3461 DM_DBG2(("dmDiscoveryReportMCN: reporting \n")); 3462 extension = oneDeviceData->dmDeviceInfo.ext; 3463 /* zero out MCN in extension */ 3464 extension = extension & 0x7FF; 3465 /* sets MCN in extension */ 3466 extension = extension | (oneDeviceData->MCN << 11); 3467 DEVINFO_PUT_EXT(&(oneDeviceData->dmDeviceInfo), extension); 3468 DM_DBG5(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", DEVINFO_GET_EXT_MCN(&(oneDeviceData->dmDeviceInfo)), oneDeviceData->PrevMCN)); 3469 if (oneDeviceData->ExpDevice != agNULL) 3470 { 3471 DM_DBG2(("dmDiscoveryReportMCN: attached expander case\n")); 3472 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3473 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceMCNChange); 3474 } 3475 else 3476 { 3477 DM_DBG2(("dmDiscoveryReportMCN: No attached expander case\n")); 3478 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceMCNChange); 3479 } 3480 oneDeviceData->PrevMCN = oneDeviceData->MCN; 3481 } 3482 else 3483 { 3484 DM_DBG2(("dmDiscoveryReportMCN: No change; no reporting \n")); 3485 if (oneDeviceData->MCN == 0) 3486 { 3487 oneDeviceData->PrevMCN = oneDeviceData->MCN; 3488 } 3489 } 3490 3491 } 3492 DeviceListList = DeviceListList->flink; 3493 } 3494 3495 return; 3496} 3497 3498osGLOBAL void 3499dmDiscoveryDumpMCN( 3500 dmRoot_t *dmRoot, 3501 dmIntPortContext_t *onePortContext 3502 ) 3503{ 3504 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3505 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3506 dmDeviceData_t *oneDeviceData = agNULL; 3507 dmList_t *DeviceListList; 3508 3509 DM_DBG3(("dmDiscoveryDumpMCN: start\n")); 3510 3511 DeviceListList = dmAllShared->MainDeviceList.flink; 3512 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3513 { 3514 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3515 if (oneDeviceData == agNULL) 3516 { 3517 DM_DBG1(("dmDiscoveryDumpMCN: oneDeviceData is NULL!!!\n")); 3518 return; 3519 } 3520 DM_DBG3(("dmDiscoveryDumpMCN: loop did %d\n", oneDeviceData->id)); 3521 if (oneDeviceData->dmPortContext == onePortContext) 3522 { 3523 DM_DBG3(("dmDiscoveryDumpMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3524 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3525 DM_DBG3(("dmDiscoveryDumpMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3526 } 3527 DeviceListList = DeviceListList->flink; 3528 } 3529 3530 return; 3531} 3532 3533osGLOBAL void 3534dmDiscoveryResetMCN( 3535 dmRoot_t *dmRoot, 3536 dmIntPortContext_t *onePortContext 3537 ) 3538{ 3539 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3540 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3541 dmDeviceData_t *oneDeviceData = agNULL; 3542 dmList_t *DeviceListList; 3543 3544 DM_DBG2(("dmDiscoveryResetMCN: start\n")); 3545 3546 /* reinitialize the device data belonging to this portcontext */ 3547 DeviceListList = dmAllShared->MainDeviceList.flink; 3548 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3549 { 3550 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3551 if (oneDeviceData == agNULL) 3552 { 3553 DM_DBG1(("dmDiscoveryResetMCN: oneDeviceData is NULL!!!\n")); 3554 return; 3555 } 3556 DM_DBG3(("dmDiscoveryResetMCN: loop did %d\n", oneDeviceData->id)); 3557 if (oneDeviceData->dmPortContext == onePortContext) 3558 { 3559 if (oneDeviceData->ExpDevice != agNULL) 3560 { 3561 DM_DBG2(("dmDiscoveryResetMCN: resetting oneDeviceData->ExpDevice\n")); 3562 oneDeviceData->ExpDevice = agNULL; 3563 } 3564 DM_DBG3(("dmDiscoveryResetMCN: resetting MCN and MCNdone\n")); 3565 oneDeviceData->MCN = 0; 3566 3567 oneDeviceData->MCNDone = agFALSE; 3568 DM_DBG2(("dmDiscoveryResetMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3569 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3570 } 3571 DeviceListList = DeviceListList->flink; 3572 } 3573 3574 return; 3575} 3576 3577 3578/* 3579do min(oneDeviceData, found-one) in all upstream and downstream 3580find ajcanent expanders and mark it done; sees only ajcacent targets 3581*/ 3582osGLOBAL void 3583dmUpdateAllAdjacent( 3584 dmRoot_t *dmRoot, 3585 dmIntPortContext_t *onePortContext, 3586 dmDeviceData_t *oneDeviceData /* current one */ 3587 ) 3588{ 3589 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3590 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3591 dmDeviceData_t *tmponeDeviceData = agNULL; 3592 dmList_t *DeviceListList; 3593 3594 DM_DBG2(("dmUpdateAllAdjacent: start\n")); 3595 if (oneDeviceData == agNULL) 3596 { 3597 DM_DBG1(("dmUpdateAllAdjacent: oneDeviceData is NULL!!!\n")); 3598 return; 3599 } 3600 3601 oneDeviceData->MCNDone = agTRUE; 3602 3603 DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3604 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3605 3606 3607 DeviceListList = dmAllShared->MainDeviceList.flink; 3608 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3609 { 3610 tmponeDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3611 if ( tmponeDeviceData == agNULL) 3612 { 3613 DM_DBG1(("dmUpdateAllAdjacent: tmponeDeviceData is NULL!!!\n")); 3614 return; 3615 } 3616 DM_DBG3(("dmUpdateAllAdjacent: loop did %d\n", tmponeDeviceData->id)); 3617 if (tmponeDeviceData->dmPortContext == onePortContext && tmponeDeviceData->ExpDevice == oneDeviceData) 3618 { 3619 DM_DBG2(("dmUpdateAllAdjacent: setting MCN DONE\n")); 3620 DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3621 tmponeDeviceData->SASAddressID.sasAddressHi, tmponeDeviceData->SASAddressID.sasAddressLo)); 3622 tmponeDeviceData->MCNDone = agTRUE; 3623 if (oneDeviceData->directlyAttached == agFALSE) 3624 { 3625 DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData MCN 0x%x\n", tmponeDeviceData->MCN)); 3626 DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3627 tmponeDeviceData->MCN = MIN(oneDeviceData->MCN, tmponeDeviceData->MCN); 3628 } 3629 3630 } 3631 DeviceListList = DeviceListList->flink; 3632 } 3633 3634 return; 3635 3636} 3637 3638osGLOBAL void 3639dmUpdateMCN( 3640 dmRoot_t *dmRoot, 3641 dmIntPortContext_t *onePortContext, 3642 dmDeviceData_t *AdjacentDeviceData, /* adjacent expander */ 3643 dmDeviceData_t *oneDeviceData /* current one */ 3644 ) 3645{ 3646 3647 DM_DBG2(("dmUpdateMCN: start\n")); 3648 3649 if (AdjacentDeviceData == agNULL) 3650 { 3651 DM_DBG1(("dmUpdateMCN: AdjacentDeviceData is NULL!!!\n")); 3652 return; 3653 } 3654 3655 if (oneDeviceData == agNULL) 3656 { 3657 DM_DBG1(("dmUpdateMCN: oneDeviceData is NULL!!!\n")); 3658 return; 3659 } 3660 3661 DM_DBG2(("dmUpdateMCN: Current sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3662 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3663 3664 DM_DBG2(("dmUpdateMCN: AdjacentDeviceData one sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3665 AdjacentDeviceData->SASAddressID.sasAddressHi, AdjacentDeviceData->SASAddressID.sasAddressLo)); 3666 3667 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3668 { 3669 DM_DBG2(("dmUpdateMCN: DISCOVERY_UP_STREAM\n")); 3670 } 3671 3672 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3673 { 3674 DM_DBG2(("dmUpdateMCN: DISCOVERY_DOWN_STREAM\n")); 3675 } 3676 3677 3678 /* MCN */ 3679 3680 /* directly attached one does not have MCN 3681 update only adjacent device data 3682 */ 3683 3684 if (oneDeviceData->directlyAttached == agTRUE && AdjacentDeviceData->MCNDone == agFALSE) 3685 { 3686 AdjacentDeviceData->MCN++; 3687 DM_DBG2(("dmUpdateMCN: case 1 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3688 DM_DBG2(("dmUpdateMCN: case 1 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3689 } 3690 else if (AdjacentDeviceData->MCNDone == agFALSE) 3691 { 3692 AdjacentDeviceData->MCN++; 3693 AdjacentDeviceData->MCN = MIN(oneDeviceData->MCN, AdjacentDeviceData->MCN); 3694 DM_DBG2(("dmUpdateMCN: case 2 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3695 DM_DBG2(("dmUpdateMCN: case 2 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3696 } 3697 3698 3699 return; 3700} 3701/* go through expander list and device list array ??? */ 3702osGLOBAL dmDeviceData_t * 3703dmPortSASDeviceFind( 3704 dmRoot_t *dmRoot, 3705 dmIntPortContext_t *onePortContext, 3706 bit32 sasAddrLo, 3707 bit32 sasAddrHi, 3708 dmDeviceData_t *CurrentDeviceData /* current expander */ 3709 ) 3710{ 3711 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3712 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3713 dmDeviceData_t *oneDeviceData, *RetDeviceData=agNULL; 3714 dmList_t *DeviceListList; 3715 3716 DM_DBG3(("dmPortSASDeviceFind: start\n")); 3717 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", sasAddrHi, sasAddrLo)); 3718 3719 DM_ASSERT((agNULL != dmRoot), ""); 3720 DM_ASSERT((agNULL != onePortContext), ""); 3721 3722 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 3723 3724 /* find a device's existence */ 3725 DeviceListList = dmAllShared->MainDeviceList.flink; 3726 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3727 { 3728 DM_DBG3(("dmPortSASDeviceFind: Full discovery\n")); 3729 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3730 { 3731 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3732 if (oneDeviceData == agNULL) 3733 { 3734 DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3735 return agNULL; 3736 } 3737 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3738 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3739 (oneDeviceData->valid == agTRUE) && 3740 (oneDeviceData->dmPortContext == onePortContext) 3741 ) 3742 { 3743 DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3744 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3745 DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3746 RetDeviceData = oneDeviceData; 3747 dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3748 break; 3749 } 3750 DeviceListList = DeviceListList->flink; 3751 } 3752 } 3753 else 3754 { 3755 /* incremental discovery */ 3756 DM_DBG3(("dmPortSASDeviceFind: Incremental discovery\n")); 3757 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3758 { 3759 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3760 if (oneDeviceData == agNULL) 3761 { 3762 DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3763 return agNULL; 3764 } 3765 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3766 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3767 (oneDeviceData->valid2 == agTRUE) && 3768 (oneDeviceData->dmPortContext == onePortContext) 3769 ) 3770 { 3771 DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3772 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3773 DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3774 RetDeviceData = oneDeviceData; 3775 dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3776 break; 3777 } 3778 DeviceListList = DeviceListList->flink; 3779 } 3780 } 3781 3782 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 3783 3784 return RetDeviceData; 3785} 3786 3787bit32 3788dmNewEXPorNot( 3789 dmRoot_t *dmRoot, 3790 dmIntPortContext_t *onePortContext, 3791 dmSASSubID_t *dmSASSubID 3792 ) 3793{ 3794// dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3795// dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3796 dmExpander_t *oneExpander = agNULL; 3797 dmList_t *ExpanderList; 3798 bit32 ret = agTRUE; 3799 dmDeviceData_t *oneDeviceData = agNULL; 3800 3801 DM_DBG3(("dmNewEXPorNot: start\n")); 3802 3803 /* find a device's existence */ 3804 ExpanderList = onePortContext->discovery.discoveringExpanderList.flink; 3805 while (ExpanderList != &(onePortContext->discovery.discoveringExpanderList)) 3806 { 3807 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3808 if ( oneExpander == agNULL) 3809 { 3810 DM_DBG1(("dmNewEXPorNot: oneExpander is NULL!!!\n")); 3811 return agFALSE; 3812 } 3813 oneDeviceData = oneExpander->dmDevice; 3814 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3815 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3816 (oneDeviceData->dmPortContext == onePortContext) 3817 ) 3818 { 3819 DM_DBG3(("dmNewEXPorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3820 ret = agFALSE; 3821 break; 3822 } 3823 ExpanderList = ExpanderList->flink; 3824 } 3825 3826 return ret; 3827} 3828 3829 3830bit32 3831dmNewSASorNot( 3832 dmRoot_t *dmRoot, 3833 dmIntPortContext_t *onePortContext, 3834 dmSASSubID_t *dmSASSubID 3835 ) 3836{ 3837 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3838 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3839 dmDeviceData_t *oneDeviceData = agNULL; 3840 dmList_t *DeviceListList; 3841 bit32 ret = agTRUE; 3842 3843 DM_DBG3(("dmNewSASorNot: start\n")); 3844 3845 /* find a device's existence */ 3846 DeviceListList = dmAllShared->MainDeviceList.flink; 3847 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3848 { 3849 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3850 if (oneDeviceData == agNULL) 3851 { 3852 DM_DBG1(("dmNewSASorNot: oneDeviceData is NULL!!!\n")); 3853 return agFALSE; 3854 } 3855 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3856 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3857 (oneDeviceData->dmPortContext == onePortContext) && 3858 (oneDeviceData->registered == agTRUE) 3859 ) 3860 { 3861 DM_DBG3(("dmNewSASorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3862 ret = agFALSE; 3863 break; 3864 } 3865 DeviceListList = DeviceListList->flink; 3866 } 3867 3868 return ret; 3869} 3870/* 3871call 3872osGLOBAL bit32 3873tddmReportDevice( 3874 dmRoot_t *dmRoot, 3875 dmPortContext_t *dmPortContext, 3876 dmDeviceInfo_t *dmDeviceInfo 3877 ) 3878if not reported, report Device to TDM 3879*/ 3880osGLOBAL dmDeviceData_t * 3881dmPortSASDeviceAdd( 3882 dmRoot_t *dmRoot, 3883 dmIntPortContext_t *onePortContext, 3884 agsaSASIdentify_t sasIdentify, 3885 bit32 sasInitiator, 3886 bit8 connectionRate, 3887 bit32 itNexusTimeout, 3888 bit32 firstBurstSize, 3889 bit32 deviceType, 3890 dmDeviceData_t *oneExpDeviceData, 3891 dmExpander_t *dmExpander, 3892 bit8 phyID 3893 ) 3894{ 3895 dmDeviceData_t *oneDeviceData = agNULL; 3896 bit8 dev_s_rate = 0; 3897 bit8 sasorsata = 1; 3898 dmSASSubID_t dmSASSubID; 3899 bit8 ExpanderConnectionRate = connectionRate; 3900 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3901 bit16 extension = 0; 3902 bit32 current_link_rate = 0; 3903 3904 DM_DBG3(("dmPortSASDeviceAdd: start\n")); 3905 DM_DBG3(("dmPortSASDeviceAdd: connectionRate %d\n", connectionRate)); 3906 3907 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 3908 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 3909 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 3910 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 3911 3912 if (oneExpDeviceData != agNULL) 3913 { 3914 ExpanderConnectionRate = DEVINFO_GET_LINKRATE(&oneExpDeviceData->agDeviceInfo); 3915 DM_DBG3(("dmPortSASDeviceAdd: ExpanderConnectionRate 0x%x\n", ExpanderConnectionRate)); 3916 } 3917 if (oneExpDeviceData != agNULL) 3918 { 3919 if (oneExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 3920 oneExpDeviceData->SASAddressID.sasAddressLo == 0x0) 3921 { 3922 DM_DBG1(("dmPortSASDeviceAdd: 1st Wrong expander!!!\n")); 3923 } 3924 } 3925 /* old device and already reported to TDM */ 3926 if ( agFALSE == dmNewSASorNot( 3927 dmRoot, 3928 onePortContext, 3929 &dmSASSubID 3930 ) 3931 ) /* old device */ 3932 { 3933 DM_DBG3(("dmPortSASDeviceAdd: OLD qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", dmSASSubID.initiator_ssp_stp_smp, dmSASSubID.target_ssp_stp_smp)); 3934 /* allocate a new device and set the valid bit */ 3935 oneDeviceData = dmAddSASToSharedcontext( 3936 dmRoot, 3937 onePortContext, 3938 &dmSASSubID, 3939 oneExpDeviceData, 3940 phyID 3941 ); 3942 if (oneDeviceData == agNULL) 3943 { 3944 DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null!!!\n")); 3945 } 3946 /* If a device is allocated */ 3947 if ( oneDeviceData != agNULL ) 3948 { 3949 3950 3951 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3952 { 3953 DM_DBG3(("dmPortSASDeviceAdd: OLD, UP_STREAM\n")); 3954 } 3955 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3956 { 3957 DM_DBG3(("dmPortSASDeviceAdd: OLD, DOWN_STREAM\n")); 3958 } 3959 3960 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3961 { 3962 DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 3963 oneDeviceData->MCN++; 3964 } 3965 else 3966 { 3967 /* incremental */ 3968 DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 3969 if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 3970 { 3971 oneDeviceData->MCN++; 3972 } 3973 } 3974 3975 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 3976 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3977 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3978 3979 3980 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 3981 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 3982 3983// oneDeviceData->sasIdentify = sasIdentify; 3984 dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 3985 3986 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 3987 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 3988 3989 /* parse sasIDframe to fill in agDeviceInfo */ 3990 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 3991 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 3992 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 3993 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 3994 3995 oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 3996 3997 /* adjusting connectionRate */ 3998 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3999 if (oneAttachedExpDeviceData != agNULL) 4000 { 4001 connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4002 DM_DBG3(("dmPortSASDeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4003 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4004 } 4005 else 4006 { 4007 DM_DBG3(("dmPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n")); 4008 } 4009 4010 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4011 sasorsata = (bit8)deviceType; 4012 /* sTSDK spec device typ */ 4013 dev_s_rate = dev_s_rate | (sasorsata << 4); 4014 dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4015 /* detect link rate change */ 4016 current_link_rate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); 4017 if (current_link_rate != (bit32)MIN(connectionRate, ExpanderConnectionRate)) 4018 { 4019 DM_DBG1(("dmPortSASDeviceAdd: link rate changed current 0x%x new 0x%x\n", current_link_rate, MIN(connectionRate, ExpanderConnectionRate))); 4020 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4021 if (oneDeviceData->ExpDevice != agNULL) 4022 { 4023 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4024 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceRateChange); 4025 } 4026 else 4027 { 4028 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4029 } 4030 } 4031 4032 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4033 4034 4035 DEVINFO_PUT_SAS_ADDRESSLO( 4036 &oneDeviceData->agDeviceInfo, 4037 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4038 ); 4039 DEVINFO_PUT_SAS_ADDRESSHI( 4040 &oneDeviceData->agDeviceInfo, 4041 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4042 ); 4043 oneDeviceData->agContext.osData = oneDeviceData; 4044 oneDeviceData->agContext.sdkData = agNULL; 4045 4046 4047 } 4048 return oneDeviceData; 4049 } /* old device */ 4050 4051 4052 /* new device */ 4053 4054 DM_DBG3(("dmPortSASDeviceAdd: NEW qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", dmSASSubID.initiator_ssp_stp_smp, dmSASSubID.target_ssp_stp_smp)); 4055 4056 /* allocate a new device and set the valid bit */ 4057 oneDeviceData = dmAddSASToSharedcontext( 4058 dmRoot, 4059 onePortContext, 4060 &dmSASSubID, 4061 oneExpDeviceData, 4062 phyID 4063 ); 4064 if (oneDeviceData == agNULL) 4065 { 4066 DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null !!!\n")); 4067 } 4068 4069 /* If a device is allocated */ 4070 if ( oneDeviceData != agNULL ) 4071 { 4072 4073// DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 4074// DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 4075 4076// oneDeviceData->sasIdentify = sasIdentify; 4077 dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 4078 4079 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4080 { 4081 DM_DBG3(("dmPortSASDeviceAdd: NEW, UP_STREAM\n")); 4082 } 4083 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4084 { 4085 DM_DBG3(("dmPortSASDeviceAdd: NEW, DOWN_STREAM\n")); 4086 } 4087 4088 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4089 { 4090 DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 4091 oneDeviceData->MCN++; 4092 } 4093 else 4094 { 4095 /* incremental */ 4096 DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 4097 if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 4098 { 4099 oneDeviceData->MCN++; 4100 } 4101 } 4102 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 4103 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 4104 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 4105 4106 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 4107 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 4108 4109 /* parse sasIDframe to fill in agDeviceInfo */ 4110 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 4111 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 4112 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 4113 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 4114 4115 oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 4116 4117 /* adjusting connectionRate */ 4118 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4119 if (oneAttachedExpDeviceData != agNULL) 4120 { 4121 connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4122 DM_DBG3(("dmPortSASDeviceAdd: 2nd connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4123 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4124 } 4125 else 4126 { 4127 DM_DBG3(("dmPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n")); 4128 } 4129 4130 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4131 sasorsata = (bit8)deviceType; 4132 dev_s_rate = dev_s_rate | (sasorsata << 4); 4133 dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4134 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4135 4136 4137 DEVINFO_PUT_SAS_ADDRESSLO( 4138 &oneDeviceData->agDeviceInfo, 4139 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4140 ); 4141 DEVINFO_PUT_SAS_ADDRESSHI( 4142 &oneDeviceData->agDeviceInfo, 4143 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4144 ); 4145 oneDeviceData->agContext.osData = oneDeviceData; 4146 oneDeviceData->agContext.sdkData = agNULL; 4147 4148 DM_DBG3(("dmPortSASDeviceAdd: did %d\n", oneDeviceData->id)); 4149 4150 4151 /* reporting to TDM; setting dmDeviceInfo */ 4152 DEVINFO_PUT_SMPTO(&oneDeviceData->dmDeviceInfo, DEFAULT_SMP_TIMEOUT); 4153 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->dmDeviceInfo, (bit16)itNexusTimeout); 4154 DEVINFO_PUT_FBS(&oneDeviceData->dmDeviceInfo, (bit16)firstBurstSize); 4155 DEVINFO_PUT_FLAG(&oneDeviceData->dmDeviceInfo, 1); 4156 DEVINFO_PUT_INITIATOR_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.initiator_ssp_stp_smp); 4157 DEVINFO_PUT_TARGET_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.target_ssp_stp_smp); 4158 extension = phyID; 4159 4160 /* setting 6th bit of dev_s_rate */ 4161 if (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE || 4162 oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 4163 { 4164 extension = (bit16)(extension | (1 << 8)); 4165 } 4166 DEVINFO_PUT_EXT(&oneDeviceData->dmDeviceInfo, extension); 4167 4168 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4169 4170 DEVINFO_PUT_SAS_ADDRESSLO( 4171 &oneDeviceData->dmDeviceInfo, 4172 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4173 ); 4174 DEVINFO_PUT_SAS_ADDRESSHI( 4175 &oneDeviceData->dmDeviceInfo, 4176 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4177 ); 4178 4179 if (oneDeviceData->ExpDevice != agNULL) 4180 { 4181 DM_DBG3(("dmPortSASDeviceAdd: attached expander case\n")); 4182 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4183 /* 4184 Puts attached expander's SAS address into dmDeviceInfo 4185 */ 4186 DEVINFO_PUT_SAS_ADDRESSLO( 4187 &oneAttachedExpDeviceData->dmDeviceInfo, 4188 oneAttachedExpDeviceData->SASAddressID.sasAddressLo 4189 ); 4190 DEVINFO_PUT_SAS_ADDRESSHI( 4191 &oneAttachedExpDeviceData->dmDeviceInfo, 4192 oneAttachedExpDeviceData->SASAddressID.sasAddressHi 4193 ); 4194 DM_DBG3(("dmPortSASDeviceAdd: oneAttachedExpDeviceData addrHi 0x%08x addrLo 0x%08x PhyID 0x%x ext 0x%x\n", 4195 DM_GET_SAS_ADDRESSHI(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressHi), 4196 DM_GET_SAS_ADDRESSLO(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressLo), 4197 phyID, extension)); 4198 4199 if (oneAttachedExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 4200 oneAttachedExpDeviceData->SASAddressID.sasAddressLo == 0x0) 4201 { 4202 DM_DBG1(("dmPortSASDeviceAdd: 2nd Wrong expander!!!\n")); 4203 } 4204 if (oneDeviceData->reported == agFALSE) 4205 { 4206 oneDeviceData->registered = agTRUE; 4207 oneDeviceData->reported = agTRUE; 4208 if (deviceType == STP_DEVICE_TYPE) 4209 { 4210 /*STP device, DM need send SMP Report Phy SATA to get the SATA device type */ 4211 oneAttachedExpDeviceData->dmExpander->dmDeviceToProcess = oneDeviceData; 4212 dmReportPhySataSend(dmRoot, oneAttachedExpDeviceData, phyID); 4213 } 4214 else 4215 { 4216 /* SAS or SMP device */ 4217 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceArrival); 4218 } 4219 } 4220 } 4221 else 4222 { 4223 DM_DBG3(("dmPortSASDeviceAdd: NO attached expander case\n")); 4224 if (oneDeviceData->reported == agFALSE) 4225 { 4226 oneDeviceData->registered = agTRUE; 4227 oneDeviceData->reported = agTRUE; 4228 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4229 } 4230 } 4231 } 4232 4233 return oneDeviceData; 4234} 4235 4236osGLOBAL dmDeviceData_t * 4237dmFindRegNValid( 4238 dmRoot_t *dmRoot, 4239 dmIntPortContext_t *onePortContext, 4240 dmSASSubID_t *dmSASSubID 4241 ) 4242{ 4243 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4244 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4245 dmDeviceData_t *oneDeviceData = agNULL; 4246 dmList_t *DeviceListList; 4247 bit32 found = agFALSE; 4248 DM_DBG3(("dmFindRegNValid: start\n")); 4249 4250 /* find a device's existence */ 4251 DeviceListList = dmAllShared->MainDeviceList.flink; 4252 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4253 { 4254 DM_DBG3(("dmFindRegNValid: Full discovery\n")); 4255 while (DeviceListList != &(dmAllShared->MainDeviceList)) 4256 { 4257 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4258 if (oneDeviceData == agNULL) 4259 { 4260 DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4261 return agFALSE; 4262 } 4263 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4264 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4265 (oneDeviceData->valid == agTRUE) && 4266 (oneDeviceData->dmPortContext == onePortContext) 4267 ) 4268 { 4269 DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4270 DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4271 DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4272 found = agTRUE; 4273 break; 4274 } 4275 DeviceListList = DeviceListList->flink; 4276 } 4277 } 4278 else 4279 { 4280 /* incremental discovery */ 4281 DM_DBG3(("dmFindRegNValid: Incremental discovery\n")); 4282 while (DeviceListList != &(dmAllShared->MainDeviceList)) 4283 { 4284 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4285 if (oneDeviceData == agNULL) 4286 { 4287 DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4288 return agFALSE; 4289 } 4290 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4291 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4292 (oneDeviceData->valid2 == agTRUE) && 4293 (oneDeviceData->dmPortContext == onePortContext) 4294 ) 4295 { 4296 DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4297 DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4298 DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4299 found = agTRUE; 4300 break; 4301 } 4302 DeviceListList = DeviceListList->flink; 4303 } 4304 } 4305 4306 4307 4308 if (found == agFALSE) 4309 { 4310 DM_DBG3(("dmFindRegNValid: end returning NULL\n")); 4311 return agNULL; 4312 } 4313 else 4314 { 4315 DM_DBG3(("dmFindRegNValid: end returning NOT NULL\n")); 4316 return oneDeviceData; 4317 } 4318} 4319 4320osGLOBAL void 4321dmNotifyBC( 4322 dmRoot_t *dmRoot, 4323 dmPortContext_t *dmPortContext, 4324 bit32 type) 4325{ 4326 dmIntPortContext_t *onePortContext = agNULL; 4327 4328 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4329 4330 DM_DBG3(("dmNotifyBC: start\n")); 4331 4332 if (onePortContext == agNULL) 4333 { 4334 DM_DBG1(("dmNotifyBC: onePortContext is NULL, wrong!!!\n")); 4335 return; 4336 } 4337 4338 if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4339 { 4340 if (onePortContext->DiscoveryAbortInProgress == agFALSE) 4341 { 4342 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4343 { 4344 DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE\n")); 4345 onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4346 onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4347 /* processed broadcast change */ 4348 onePortContext->discovery.SeenBC = agFALSE; 4349 } 4350 else 4351 { 4352 DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4353 onePortContext->discovery.SeenBC = agTRUE; 4354 } 4355 } 4356 } 4357 else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4358 { 4359 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4360 } 4361 else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4362 { 4363 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4364 } 4365 else 4366 { 4367 DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4368 } 4369 return; 4370} 4371 4372 4373#ifdef WORKED 4374/* triggers incremental discovery */ 4375osGLOBAL void 4376dmNotifyBC( 4377 dmRoot_t *dmRoot, 4378 dmPortContext_t *dmPortContext, 4379 bit32 type) 4380{ 4381 dmIntPortContext_t *onePortContext = agNULL; 4382 4383 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4384 4385 DM_DBG3(("dmNotifyBC: start\n")); 4386 4387 4388 if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4389 { 4390 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4391 { 4392 DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE; does incremental discovery\n")); 4393 onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4394 onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4395 /* processed broadcast change */ 4396 onePortContext->discovery.SeenBC = agFALSE; 4397 if (onePortContext->discovery.ResetTriggerred == agTRUE) 4398 { 4399 DM_DBG3(("dmNotifyBC: tdsaBCTimer\n")); 4400 dmBCTimer(dmRoot, onePortContext); 4401 } 4402 else 4403 { 4404 dmDiscover( 4405 dmRoot, 4406 dmPortContext, 4407 DM_DISCOVERY_OPTION_INCREMENTAL_START 4408 ); 4409 } 4410 } 4411 else 4412 { 4413 DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4414 onePortContext->discovery.SeenBC = agTRUE; 4415 } 4416 } 4417 else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4418 { 4419 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4420 } 4421 else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4422 { 4423 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4424 } 4425 else 4426 { 4427 DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4428 } 4429 return; 4430} 4431#endif 4432 4433osGLOBAL bit32 4434dmResetFailedDiscovery( 4435 dmRoot_t *dmRoot, 4436 dmPortContext_t *dmPortContext) 4437{ 4438 dmIntPortContext_t *onePortContext = agNULL; 4439 4440 DM_DBG1(("dmResetFailedDiscovery: start\n")); 4441 4442 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4443 4444 if (onePortContext == agNULL) 4445 { 4446 DM_DBG1(("dmResetFailedDiscovery: onePortContext is NULL, wrong!!!\n")); 4447 return DM_RC_FAILURE; 4448 } 4449 4450 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4451 { 4452 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 4453 } 4454 else 4455 { 4456 DM_DBG1(("dmResetFailedDiscovery: discovery is NOT DM_DSTATE_COMPLETED_WITH_FAILURE. It is 0x%x\n", onePortContext->DiscoveryState)); 4457 return DM_RC_FAILURE; 4458 } 4459 4460 return DM_RC_SUCCESS; 4461} 4462 4463osGLOBAL bit32 4464dmQueryDiscovery( 4465 dmRoot_t *dmRoot, 4466 dmPortContext_t *dmPortContext) 4467{ 4468 dmIntPortContext_t *onePortContext = agNULL; 4469 4470 DM_DBG3(("dmQueryDiscovery: start\n")); 4471 4472 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4473 4474 if (onePortContext == agNULL) 4475 { 4476 DM_DBG1(("dmQueryDiscovery: onePortContext is NULL, wrong!!!\n")); 4477 return DM_RC_FAILURE; 4478 } 4479 4480 /* call tddmQueryDiscoveryCB() */ 4481 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4482 { 4483 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscCompleted); 4484 } 4485 else if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4486 { 4487 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscFailed); 4488 } 4489 else 4490 { 4491 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscInProgress); 4492 } 4493 4494 return DM_RC_SUCCESS; 4495} 4496 4497 4498/* 4499 should only for an expander 4500*/ 4501osGLOBAL bit32 4502dmRegisterDevice( 4503 dmRoot_t *dmRoot, 4504 dmPortContext_t *dmPortContext, 4505 dmDeviceInfo_t *dmDeviceInfo, 4506 agsaDevHandle_t *agDevHandle 4507 ) 4508{ 4509 4510 dmIntPortContext_t *onePortContext = agNULL; 4511 dmExpander_t *oneExpander = agNULL; 4512 bit32 sasAddressHi, sasAddressLo; 4513 dmDeviceData_t *oneDeviceData = agNULL; 4514 dmSASSubID_t dmSASSubID; 4515 4516 DM_DBG3(("dmRegisterDevice: start\n")); 4517 4518 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4519 if (onePortContext == agNULL) 4520 { 4521 DM_DBG1(("dmRegisterDevice: onePortContext is NULL!!!\n")); 4522 return DM_RC_FAILURE; 4523 } 4524 4525 if (onePortContext->valid == agFALSE) 4526 { 4527 DM_DBG1(("dmRegisterDevice: invalid port!!!\n")); 4528 return DM_RC_FAILURE; 4529 } 4530 4531 onePortContext->RegFailed = agFALSE; 4532 4533 /* tdssAddSASToSharedcontext() from ossaHwCB() 4534osGLOBAL void 4535tdssAddSASToSharedcontext( 4536 tdsaPortContext_t *tdsaPortContext_Instance, 4537 agsaRoot_t *agRoot, 4538 agsaDevHandle_t *agDevHandle, 4539 tdsaSASSubID_t *agSASSubID, 4540 bit32 registered, 4541 bit8 phyID, 4542 bit32 flag 4543 ); 4544from discovery 4545osGLOBAL tdsaDeviceData_t * 4546tdssNewAddSASToSharedcontext( 4547 agsaRoot_t *agRoot, 4548 tdsaPortContext_t *onePortContext, 4549 tdsaSASSubID_t *agSASSubID, 4550 tdsaDeviceData_t *oneExpDeviceData, 4551 bit8 phyID 4552 ); 4553 4554 */ 4555 /* start here */ 4556 dmSASSubID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4557 dmSASSubID.sasAddressLo = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressLo); 4558 dmSASSubID.initiator_ssp_stp_smp = dmDeviceInfo->initiator_ssp_stp_smp; 4559 dmSASSubID.target_ssp_stp_smp = dmDeviceInfo->target_ssp_stp_smp; 4560 4561 oneDeviceData = dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, agNULL, 0xFF); 4562 if (oneDeviceData == agNULL) 4563 { 4564 DM_DBG1(("dmRegisterDevice: oneDeviceData is NULL!!!\n")); 4565 return DM_RC_FAILURE; 4566 } 4567 oneDeviceData->agDeviceInfo.devType_S_Rate = dmDeviceInfo->devType_S_Rate; 4568 dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressHi, dmDeviceInfo->sasAddressHi, 4); 4569 dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressLo, dmDeviceInfo->sasAddressLo, 4); 4570 /* finds the type of expanders */ 4571 if (DEVINFO_GET_EXT_SMP(dmDeviceInfo)) 4572 { 4573 if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_EDGE_EXPANDER_DEVICE) 4574 { 4575 oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4576 } 4577 else if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_FANOUT_EXPANDER_DEVICE) 4578 { 4579 oneDeviceData->SASSpecDeviceType = SAS_FANOUT_EXPANDER_DEVICE; 4580 } 4581 else 4582 { 4583 /* default */ 4584 DM_DBG4(("dmRegisterDevice: no expander type. default to edge expander\n")); 4585 oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4586 } 4587 } 4588 4589 if (DEVINFO_GET_EXT_MCN(dmDeviceInfo) == 0xF) 4590 { 4591 DM_DBG1(("dmRegisterDevice: directly attached expander\n")); 4592 oneDeviceData->directlyAttached = agTRUE; 4593 oneDeviceData->dmDeviceInfo.ext = (bit16)(oneDeviceData->dmDeviceInfo.ext | (0xF << 11)); 4594 } 4595 else 4596 { 4597 DM_DBG1(("dmRegisterDevice: NOT directly attached expander\n")); 4598 oneDeviceData->directlyAttached = agFALSE; 4599 } 4600 4601 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 4602 { 4603 DM_DBG3(("dmRegisterDevice: DM_DSTATE_NOT_STARTED\n")); 4604 /* before the discovery is started */ 4605 oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 4606 if ( oneExpander != agNULL) 4607 { 4608 oneExpander->agDevHandle = agDevHandle; 4609 /* update SAS address field */ 4610 oneExpander->dmDevice->SASAddressID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4611 oneExpander->dmDevice->SASAddressID.sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4612 DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi, oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4613 dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 4614 } 4615 else 4616 { 4617 DM_DBG1(("dmRegisterDevice: failed to allocate expander !!!\n")); 4618 /* remember that the registration failed so that a discovery can't be started */ 4619 onePortContext->RegFailed = agTRUE; 4620 return DM_RC_FAILURE; 4621 } 4622 } 4623 else 4624 { 4625 /* 4626 the discovery has started. Alloc and add have been done. 4627 find an expander using dmDeviceInfo, and update the expander's agDevHandle 4628 call dmExpFind() 4629 */ 4630 DM_DBG3(("dmRegisterDevice: NOT DM_DSTATE_NOT_STARTED\n")); 4631 sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4632 sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4633 DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 4634 oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 4635 if ( oneExpander != agNULL) 4636 { 4637 oneExpander->agDevHandle = agDevHandle; 4638 } 4639 else 4640 { 4641 DM_DBG1(("dmRegisterDevice: not allowed case, wrong !!!\n")); 4642 return DM_RC_FAILURE; 4643 } 4644 } 4645 4646 return DM_RC_SUCCESS; 4647} 4648 4649osGLOBAL dmExpander_t * 4650dmDiscoveringExpanderAlloc( 4651 dmRoot_t *dmRoot, 4652 dmIntPortContext_t *onePortContext, 4653 dmDeviceData_t *oneDeviceData 4654 ) 4655{ 4656 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4657 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4658 dmExpander_t *oneExpander = agNULL; 4659 dmList_t *ExpanderList; 4660 4661 DM_DBG3(("dmDiscoveringExpanderAlloc: start\n")); 4662 DM_DBG3(("dmDiscoveringExpanderAlloc: did %d\n", oneDeviceData->id)); 4663 DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4664 DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4665 4666 if (onePortContext->valid == agFALSE) 4667 { 4668 DM_DBG1(("dmDiscoveringExpanderAlloc: invalid port!!!\n")); 4669 return agNULL; 4670 } 4671 4672 4673 /* check exitence in dmAllShared->mainExpanderList */ 4674 oneExpander = dmExpMainListFind(dmRoot, 4675 onePortContext, 4676 oneDeviceData->SASAddressID.sasAddressHi, 4677 oneDeviceData->SASAddressID.sasAddressLo); 4678 4679 if (oneExpander == agNULL) 4680 { 4681 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4682 if (DMLIST_EMPTY(&(dmAllShared->freeExpanderList))) 4683 { 4684 DM_DBG1(("dmDiscoveringExpanderAlloc: no free expanders pid %d!!!\n", onePortContext->id)); 4685 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4686 return agNULL; 4687 } 4688 else 4689 { 4690 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4691 } 4692 4693 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4694 DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(dmAllShared->freeExpanderList)); 4695 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4696 4697 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4698 } 4699 4700 if (oneExpander != agNULL) 4701 { 4702 DM_DBG1(("dmDiscoveringExpanderAlloc: pid %d exp id %d \n", onePortContext->id, oneExpander->id)); 4703 4704 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4705 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 4706 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4707 4708 oneExpander->dmDevice = oneDeviceData; 4709 oneExpander->dmUpStreamExpander = agNULL; 4710 oneExpander->dmCurrentDownStreamExpander = agNULL; 4711 oneExpander->dmReturnginExpander = agNULL; 4712 oneExpander->hasUpStreamDevice = agFALSE; 4713 oneExpander->numOfUpStreamPhys = 0; 4714 oneExpander->currentUpStreamPhyIndex = 0; 4715 oneExpander->discoveringPhyId = 0; 4716 oneExpander->underDiscovering = agFALSE; 4717 dm_memset( &(oneExpander->currentIndex), 0, sizeof(oneExpander->currentIndex)); 4718 4719 oneDeviceData->dmExpander = oneExpander; 4720 DM_DBG3(("dmDiscoveringExpanderAlloc: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 4721 DM_DBG3(("dmDiscoveringExpanderAlloc: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 4722 4723 } 4724 4725 return oneExpander; 4726} 4727 4728osGLOBAL void 4729dmDiscoveringExpanderAdd( 4730 dmRoot_t *dmRoot, 4731 dmIntPortContext_t *onePortContext, 4732 dmExpander_t *oneExpander 4733 ) 4734{ 4735 DM_DBG3(("dmDiscoveringExpanderAdd: start\n")); 4736 DM_DBG3(("dmDiscoveringExpanderAdd: expander id %d\n", oneExpander->id)); 4737 DM_DBG3(("dmDiscoveringExpanderAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4738 DM_DBG3(("dmDiscoveringExpanderAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4739 4740 if (onePortContext->valid == agFALSE) 4741 { 4742 DM_DBG1(("dmDiscoveringExpanderAdd: invalid port!!!\n")); 4743 return; 4744 } 4745 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4746 { 4747 DM_DBG3(("dmDiscoveringExpanderAdd: UPSTREAM\n")); 4748 } 4749 else if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4750 { 4751 DM_DBG3(("dmDiscoveringExpanderAdd: DOWNSTREAM\n")); 4752 } 4753 else 4754 { 4755 DM_DBG3(("dmDiscoveringExpanderAdd: status %d\n", onePortContext->discovery.status)); 4756 } 4757 4758 if ( oneExpander->underDiscovering == agFALSE) 4759 { 4760 DM_DBG3(("dmDiscoveringExpanderAdd: ADDED \n")); 4761 4762 oneExpander->underDiscovering = agTRUE; 4763 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4764 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 4765 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4766 } 4767 4768 return; 4769} 4770 4771osGLOBAL dmExpander_t * 4772dmFindConfigurableExp( 4773 dmRoot_t *dmRoot, 4774 dmIntPortContext_t *onePortContext, 4775 dmExpander_t *oneExpander 4776 ) 4777{ 4778 dmExpander_t *tempExpander; 4779 dmIntPortContext_t *tmpOnePortContext = onePortContext; 4780 dmExpander_t *ret = agNULL; 4781 DM_DBG3(("dmFindConfigurableExp: start\n")); 4782 4783 if (oneExpander == agNULL) 4784 { 4785 DM_DBG3(("dmFindConfigurableExp: NULL expander\n")); 4786 return agNULL; 4787 } 4788 4789 DM_DBG3(("dmFindConfigurableExp: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4790 DM_DBG3(("dmFindConfigurableExp: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4791 4792 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4793 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4794 { 4795 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4796 DM_DBG3(("dmFindConfigurableExp: empty UpdiscoveringExpanderList\n")); 4797 return agNULL; 4798 } 4799 else 4800 { 4801 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4802 } 4803 tempExpander = oneExpander->dmUpStreamExpander; 4804 while (tempExpander) 4805 { 4806 DM_DBG3(("dmFindConfigurableExp: loop exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4807 DM_DBG3(("dmFindConfigurableExp: loop exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4808 if (tempExpander->configRouteTable) 4809 { 4810 DM_DBG3(("dmFindConfigurableExp: found configurable expander\n")); 4811 ret = tempExpander; 4812 break; 4813 } 4814 tempExpander = tempExpander->dmUpStreamExpander; 4815 } 4816 4817 return ret; 4818} 4819 4820osGLOBAL bit32 4821dmDuplicateConfigSASAddr( 4822 dmRoot_t *dmRoot, 4823 dmExpander_t *oneExpander, 4824 bit32 configSASAddressHi, 4825 bit32 configSASAddressLo 4826 ) 4827{ 4828 bit32 i; 4829 bit32 ret = agFALSE; 4830 DM_DBG3(("dmDuplicateConfigSASAddr: start\n")); 4831 4832 if (oneExpander == agNULL) 4833 { 4834 DM_DBG3(("dmDuplicateConfigSASAddr: NULL expander\n")); 4835 return agTRUE; 4836 } 4837 4838 if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi && 4839 oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo 4840 ) 4841 { 4842 DM_DBG3(("dmDuplicateConfigSASAddr: unnecessary\n")); 4843 return agTRUE; 4844 } 4845 4846 DM_DBG3(("dmDuplicateConfigSASAddr: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4847 DM_DBG3(("dmDuplicateConfigSASAddr: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4848 DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressHi 0x%08x\n", configSASAddressHi)); 4849 DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressLo 0x%08x\n", configSASAddressLo)); 4850 DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4851 for(i=0;i<oneExpander->configSASAddrTableIndex;i++) 4852 { 4853 if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi && 4854 oneExpander->configSASAddressLoTable[i] == configSASAddressLo 4855 ) 4856 { 4857 DM_DBG3(("dmDuplicateConfigSASAddr: FOUND\n")); 4858 ret = agTRUE; 4859 break; 4860 } 4861 } 4862 /* new one; let's add it */ 4863 if (ret == agFALSE) 4864 { 4865 DM_DBG3(("dmDuplicateConfigSASAddr: adding configSAS Addr\n")); 4866 DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4867 oneExpander->configSASAddressHiTable[oneExpander->configSASAddrTableIndex] = configSASAddressHi; 4868 oneExpander->configSASAddressLoTable[oneExpander->configSASAddrTableIndex] = configSASAddressLo; 4869 oneExpander->configSASAddrTableIndex++; 4870 } 4871 4872 return ret; 4873} 4874 4875osGLOBAL bit16 4876dmFindCurrentDownStreamPhyIndex( 4877 dmRoot_t *dmRoot, 4878 dmExpander_t *oneExpander 4879 ) 4880{ 4881 dmExpander_t *DownStreamExpander; 4882 bit16 index = 0; 4883 bit16 i; 4884 bit8 phyId = 0; 4885 4886 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: start\n")); 4887 4888 if (oneExpander == agNULL) 4889 { 4890 DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, oneExpander is NULL!!!\n")); 4891 return 0; 4892 } 4893 4894 DownStreamExpander = oneExpander->dmCurrentDownStreamExpander; 4895 4896 if (DownStreamExpander == agNULL) 4897 { 4898 DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, DownStreamExpander is NULL!!!\n")); 4899 return 0; 4900 } 4901 4902 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4903 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4904 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 4905 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 4906 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: numOfDownStreamPhys %d\n", oneExpander->numOfDownStreamPhys)); 4907 4908 phyId = DownStreamExpander->upStreamPhys[0]; 4909 4910 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: phyId %d\n", phyId)); 4911 4912 for (i=0; i<oneExpander->numOfDownStreamPhys;i++) 4913 { 4914 if (oneExpander->downStreamPhys[i] == phyId) 4915 { 4916 index = i; 4917 break; 4918 } 4919 } 4920 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: index %d\n", index)); 4921 return index; 4922} 4923 4924osGLOBAL bit32 4925dmFindDiscoveringExpander( 4926 dmRoot_t *dmRoot, 4927 dmIntPortContext_t *onePortContext, 4928 dmExpander_t *oneExpander 4929 ) 4930{ 4931 dmList_t *ExpanderList; 4932 dmExpander_t *tempExpander; 4933 dmIntPortContext_t *tmpOnePortContext = onePortContext; 4934 bit32 ret = agFALSE; 4935 4936 4937 DM_DBG3(("dmFindDiscoveringExpander: start\n")); 4938 4939 DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4940 DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4941 4942 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4943 { 4944 DM_DBG3(("dmFindDiscoveringExpander: empty discoveringExpanderList\n")); 4945 return ret; 4946 } 4947 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 4948 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 4949 { 4950 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4951 if (tempExpander == oneExpander) 4952 { 4953 if (tempExpander != agNULL) 4954 { 4955 DM_DBG3(("dmFindDiscoveringExpander: match, expander id %d\n", tempExpander->id)); 4956 DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4957 DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4958 } 4959 ret = agTRUE; 4960 break; 4961 } 4962 4963 ExpanderList = ExpanderList->flink; 4964 } 4965 4966 4967 return ret; 4968} 4969 4970 4971osGLOBAL void 4972dmDiscoveringExpanderRemove( 4973 dmRoot_t *dmRoot, 4974 dmIntPortContext_t *onePortContext, 4975 dmExpander_t *oneExpander 4976 ) 4977{ 4978 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4979 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4980 4981 DM_DBG3(("dmDiscoveringExpanderRemove: start\n")); 4982 DM_DBG3(("dmDiscoveringExpanderRemove: expander id %d\n", oneExpander->id)); 4983 DM_DBG3(("dmDiscoveringExpanderRemove: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4984 DM_DBG3(("dmDiscoveringExpanderRemove: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4985 4986 DM_DBG3(("dmDiscoveringExpanderRemove: BEFORE\n")); 4987 dmDumpAllExp(dmRoot, onePortContext, oneExpander); 4988 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 4989 dmDumpAllFreeExp(dmRoot); 4990 4991 // if is temporary till smp problem is fixed 4992 if (dmFindDiscoveringExpander(dmRoot, onePortContext, oneExpander) == agTRUE) 4993 { 4994 DM_DBG3(("dmDiscoveringExpanderRemove: oneDeviceData %p did %d\n", oneExpander->dmDevice, oneExpander->dmDevice->id)); 4995 DM_DBG3(("dmDiscoveringExpanderRemove: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 4996 4997 if (oneExpander != oneExpander->dmDevice->dmExpander) 4998 { 4999 DM_DBG3(("dmDiscoveringExpanderRemove: before !!! wrong !!!\n")); 5000 } 5001 oneExpander->underDiscovering = agFALSE; 5002 oneExpander->discoveringPhyId = 0; 5003 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5004 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 5005 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5006 5007 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 5008 { 5009 DM_DBG3(("dmDiscoveringExpanderRemove: DISCOVERY_UP_STREAM\n")); 5010 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5011 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->upNode), &(onePortContext->discovery.UpdiscoveringExpanderList)); 5012 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5013 onePortContext->discovery.NumOfUpExp++; 5014 } 5015 else 5016 { 5017 DM_DBG3(("dmDiscoveringExpanderRemove: Status %d\n", onePortContext->discovery.status)); 5018 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5019 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->mainExpanderList)); 5020// DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 5021 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5022 } 5023 // error checking 5024 if (oneExpander != oneExpander->dmDevice->dmExpander) 5025 { 5026 DM_DBG3(("dmDiscoveringExpanderRemove: after !!! wrong !!!\n")); 5027 } 5028 5029 } //end temp if 5030 else 5031 { 5032 DM_DBG1(("dmDiscoveringExpanderRemove: !!! problem !!!\n")); 5033 } 5034 5035 DM_DBG3(("dmDiscoveringExpanderRemove: AFTER\n")); 5036 5037 dmDumpAllExp(dmRoot, onePortContext, oneExpander); 5038 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 5039 dmDumpAllFreeExp(dmRoot); 5040 5041 return; 5042} 5043 5044/* 5045 returns an expander with sasAddrLo, sasAddrHi from dmAllShared->mainExpanderList 5046*/ 5047osGLOBAL dmExpander_t * 5048dmExpMainListFind( 5049 dmRoot_t *dmRoot, 5050 dmIntPortContext_t *onePortContext, 5051 bit32 sasAddrHi, 5052 bit32 sasAddrLo 5053 ) 5054{ 5055 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5056 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5057 dmList_t *ExpanderList; 5058 dmExpander_t *tempExpander; 5059 5060 DM_DBG3(("dmExpMainListFind: start\n")); 5061 5062 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5063 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 5064 { 5065 DM_DBG1(("dmExpMainListFind: empty mainExpanderList\n")); 5066 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5067 return agNULL; 5068 } 5069 else 5070 { 5071 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5072 } 5073 ExpanderList = dmAllShared->mainExpanderList.flink; 5074 while (ExpanderList != &(dmAllShared->mainExpanderList)) 5075 { 5076 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5077 if (tempExpander == agNULL) 5078 { 5079 DM_DBG1(("dmExpMainListFind: tempExpander is NULL!!!\n")); 5080 return agNULL; 5081 } 5082 DM_DBG3(("dmExpMainListFind: expander id %d\n", tempExpander->id)); 5083 DM_DBG3(("dmExpMainListFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5084 DM_DBG3(("dmExpMainListFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5085 if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5086 (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5087 (tempExpander->dmDevice->dmPortContext == onePortContext) 5088 ) 5089 { 5090 DM_DBG3(("dmExpMainListFind: found expander id %d\n", tempExpander->id)); 5091 DM_DBG3(("dmExpMainListFind: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5092 DM_DBG3(("dmExpMainListFind: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5093 return tempExpander; 5094 } 5095 ExpanderList = ExpanderList->flink; 5096 } 5097 return agNULL; 5098 5099} 5100 5101/* 5102 returns an expander with sasAddrLo, sasAddrHi from discoveringExpanderList 5103*/ 5104osGLOBAL dmExpander_t * 5105dmExpFind( 5106 dmRoot_t *dmRoot, 5107 dmIntPortContext_t *onePortContext, 5108 bit32 sasAddrHi, 5109 bit32 sasAddrLo 5110 ) 5111{ 5112 dmList_t *ExpanderList; 5113 dmExpander_t *tempExpander; 5114 dmIntPortContext_t *tmpOnePortContext = onePortContext; 5115 DM_DBG3(("dmExpFind: start\n")); 5116 5117 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5118 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5119 { 5120 DM_DBG3(("dmExpFind tdsaDumpAllExp: empty discoveringExpanderList\n")); 5121 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5122 return agNULL; 5123 } 5124 else 5125 { 5126 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5127 } 5128 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5129 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5130 { 5131 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5132 if (tempExpander == agNULL) 5133 { 5134 DM_DBG1(("dmExpFind: tempExpander is NULL!!!\n")); 5135 return agNULL; 5136 } 5137 DM_DBG3(("dmExpFind: expander id %d\n", tempExpander->id)); 5138 DM_DBG3(("dmExpFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5139 DM_DBG3(("dmExpFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5140 if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5141 (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5142 (tempExpander->dmDevice->dmPortContext == onePortContext) 5143 ) 5144 { 5145 DM_DBG3(("dmExpFind: found\n")); 5146 return tempExpander; 5147 } 5148 ExpanderList = ExpanderList->flink; 5149 } 5150 return agNULL; 5151} 5152 5153osGLOBAL bit32 5154dmDiscoverCheck( 5155 dmRoot_t *dmRoot, 5156 dmIntPortContext_t *onePortContext 5157 ) 5158{ 5159 DM_DBG3(("dmDiscoverCheck: start\n")); 5160 5161 if (onePortContext == agNULL) 5162 { 5163 DM_DBG1(("dmDiscoverCheck: onePortContext is NULL!!!\n")); 5164 return agTRUE; 5165 } 5166 if (onePortContext->valid == agFALSE) 5167 { 5168 DM_DBG1(("dmDiscoverCheck: invalid port!!!\n")); 5169 return agTRUE; 5170 } 5171 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5172 onePortContext->discovery.status == DISCOVERY_SAS_DONE 5173 ) 5174 { 5175 DM_DBG1(("dmDiscoverCheck: aborted discovery!!!\n")); 5176 tddmDiscoverCB( 5177 dmRoot, 5178 onePortContext->dmPortContext, 5179 dmDiscAborted 5180 ); 5181 return agTRUE; 5182 } 5183 5184 return agFALSE; 5185} 5186 5187/* ??? needs to handle pending SMPs 5188 move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList 5189*/ 5190osGLOBAL void 5191dmDiscoverAbort( 5192 dmRoot_t *dmRoot, 5193 dmIntPortContext_t *onePortContext 5194 ) 5195{ 5196 DM_DBG1(("dmDiscoverAbort: start\n")); 5197 5198 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5199 onePortContext->discovery.status == DISCOVERY_SAS_DONE) 5200 { 5201 DM_DBG1(("dmDiscoverAbort: not allowed case!!! onePortContext->DiscoveryState 0x%x onePortContext->discovery.status 0x%x\n", 5202 onePortContext->DiscoveryState, onePortContext->discovery.status)); 5203 return; 5204 } 5205 5206 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5207 onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5208 5209 /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5210 dmCleanAllExp(dmRoot, onePortContext); 5211 5212 5213 return; 5214 5215 5216} 5217 5218/* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5219osGLOBAL void 5220dmCleanAllExp( 5221 dmRoot_t *dmRoot, 5222 dmIntPortContext_t *onePortContext 5223 ) 5224{ 5225 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5226 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5227 dmList_t *ExpanderList; 5228 dmExpander_t *tempExpander; 5229 dmExpander_t *oneExpander = agNULL; 5230 dmIntPortContext_t *tmpOnePortContext = onePortContext; 5231 5232 DM_DBG3(("dmCleanAllExp: start\n")); 5233 DM_DBG3(("dmCleanAllExp: pid %d\n", onePortContext->id)); 5234 5235 DM_DBG3(("dmCleanAllExp: before all clean up\n")); 5236 dmDumpAllFreeExp(dmRoot); 5237 5238 /* clean up UpdiscoveringExpanderList*/ 5239 DM_DBG3(("dmCleanAllExp: clean discoveringExpanderList\n")); 5240 if (!DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5241 { 5242 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5243 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5244 { 5245 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5246 if (tempExpander == agNULL) 5247 { 5248 DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5249 return; 5250 } 5251 DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5252 DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5253 DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5254 5255 oneExpander = dmExpMainListFind(dmRoot, 5256 tmpOnePortContext, 5257 tempExpander->dmDevice->SASAddressID.sasAddressHi, 5258 tempExpander->dmDevice->SASAddressID.sasAddressLo); 5259 if (oneExpander == agNULL) 5260 { 5261 DM_DBG3(("dmCleanAllExp: moving\n")); 5262 DM_DBG3(("dmCleanAllExp: moving, exp id %d\n", tempExpander->id)); 5263 /* putting back to the free pool */ 5264 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5265 DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 5266// DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 5267 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5268 5269 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5270 { 5271 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5272 break; 5273 } 5274 else 5275 { 5276 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5277 } 5278 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5279 } 5280 else 5281 { 5282 DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5283 ExpanderList = ExpanderList->flink; 5284 } 5285 } 5286 } 5287 else 5288 { 5289 DM_DBG3(("dmCleanAllExp: empty discoveringExpanderList\n")); 5290 } 5291 5292 /* reset discoveringExpanderList */ 5293 DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.discoveringExpanderList)); 5294 5295 /* clean up UpdiscoveringExpanderList*/ 5296 DM_DBG3(("dmCleanAllExp: clean UpdiscoveringExpanderList\n")); 5297 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5298 { 5299 DM_DBG3(("dmCleanAllExp: empty UpdiscoveringExpanderList\n")); 5300 return; 5301 } 5302 ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5303 while (ExpanderList != &(tmpOnePortContext->discovery.UpdiscoveringExpanderList)) 5304 { 5305 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, upNode, ExpanderList); 5306 if (tempExpander == agNULL) 5307 { 5308 DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5309 return; 5310 } 5311 DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5312 DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5313 DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5314 oneExpander = dmExpMainListFind(dmRoot, 5315 tmpOnePortContext, 5316 tempExpander->dmDevice->SASAddressID.sasAddressHi, 5317 tempExpander->dmDevice->SASAddressID.sasAddressLo); 5318 if (oneExpander == agNULL) 5319 { 5320 DM_DBG3(("dmCleanAllExp: moving\n")); 5321 DM_DBG3(("dmCleanAllExp: moving exp id %d\n", tempExpander->id)); 5322 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5323 DMLIST_DEQUEUE_THIS(&(tempExpander->upNode)); 5324 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5325 5326 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5327 { 5328 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5329 break; 5330 } 5331 else 5332 { 5333 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5334 } 5335 ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5336 } 5337 else 5338 { 5339 DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5340 ExpanderList = ExpanderList->flink; 5341 } 5342 } 5343 5344 /* reset UpdiscoveringExpanderList */ 5345 DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList)); 5346 5347 DM_DBG3(("dmCleanAllExp: after all clean up\n")); 5348 dmDumpAllFreeExp(dmRoot); 5349 5350 return; 5351} 5352 5353osGLOBAL void 5354dmInternalRemovals( 5355 dmRoot_t *dmRoot, 5356 dmIntPortContext_t *onePortContext 5357 ) 5358{ 5359 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5360 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5361 dmDeviceData_t *oneDeviceData = agNULL; 5362 dmList_t *DeviceListList; 5363 5364 5365 DM_DBG3(("dmInternalRemovals: start\n")); 5366 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5367 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5368 { 5369 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5370 DM_DBG3(("dmInternalRemovals: empty device list\n")); 5371 return; 5372 } 5373 else 5374 { 5375 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5376 } 5377 5378 DeviceListList = dmAllShared->MainDeviceList.flink; 5379 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5380 { 5381 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5382 if (oneDeviceData == agNULL) 5383 { 5384 DM_DBG1(("dmInternalRemovals: oneDeviceData is NULL!!!\n")); 5385 return; 5386 } 5387 DM_DBG3(("dmInternalRemovals: loop did %d\n", oneDeviceData->id)); 5388 DM_DBG3(("dmInternalRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5389 DM_DBG3(("dmInternalRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5390 DM_DBG3(("dmInternalRemovals: valid %d\n", oneDeviceData->valid)); 5391 DM_DBG3(("dmInternalRemovals: valid2 %d\n", oneDeviceData->valid2)); 5392 DM_DBG3(("dmInternalRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5393 if ( oneDeviceData->dmPortContext == onePortContext) 5394 { 5395 DM_DBG3(("dmInternalRemovals: right portcontext pid %d\n", onePortContext->id)); 5396 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 5397 { 5398 DM_DBG3(("dmInternalRemovals: incremental discovery\n")); 5399 oneDeviceData->valid2 = agFALSE; 5400 } 5401 else 5402 { 5403 DM_DBG3(("dmInternalRemovals: full discovery\n")); 5404 oneDeviceData->valid = agFALSE; 5405 } 5406 DeviceListList = DeviceListList->flink; 5407 } 5408 else 5409 { 5410 if (oneDeviceData->dmPortContext != agNULL) 5411 { 5412 DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5413 } 5414 else 5415 { 5416 DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5417 } 5418 DeviceListList = DeviceListList->flink; 5419 } 5420 } 5421 5422 5423 return; 5424} 5425 5426osGLOBAL void 5427dmDiscoveryResetProcessed( 5428 dmRoot_t *dmRoot, 5429 dmIntPortContext_t *onePortContext 5430 ) 5431{ 5432 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5433 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5434 dmDeviceData_t *oneDeviceData = agNULL; 5435 dmList_t *DeviceListList; 5436 5437 DM_DBG3(("dmDiscoveryResetProcessed: start\n")); 5438 5439 /* reinitialize the device data belonging to this portcontext */ 5440 DeviceListList = dmAllShared->MainDeviceList.flink; 5441 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5442 { 5443 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5444 if (oneDeviceData == agNULL) 5445 { 5446 DM_DBG1(("dmDiscoveryResetProcessed: oneDeviceData is NULL!!!\n")); 5447 return; 5448 } 5449 DM_DBG3(("dmDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id)); 5450 if (oneDeviceData->dmPortContext == onePortContext) 5451 { 5452 DM_DBG3(("dmDiscoveryResetProcessed: resetting procssed flag\n")); 5453 oneDeviceData->processed = agFALSE; 5454 } 5455 DeviceListList = DeviceListList->flink; 5456 } 5457 5458 return; 5459} 5460 5461/* 5462 calls 5463osGLOBAL void 5464tddmDiscoverCB( 5465 dmRoot_t *dmRoot, 5466 dmPortContext_t *dmPortContext, 5467 bit32 eventStatus 5468 ) 5469 5470*/ 5471osGLOBAL void 5472dmDiscoverDone( 5473 dmRoot_t *dmRoot, 5474 dmIntPortContext_t *onePortContext, 5475 bit32 flag 5476 ) 5477{ 5478 5479 DM_DBG3(("dmDiscoverDone: start\n")); 5480 DM_DBG3(("dmDiscoverDone: pid %d\n", onePortContext->id)); 5481 5482 /* Set discovery status */ 5483 onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5484 5485 5486 /* clean up expanders data strucures; move to free exp when device is cleaned */ 5487 dmCleanAllExp(dmRoot, onePortContext); 5488 5489 dmDumpAllMainExp(dmRoot, onePortContext); 5490 5491 dmDiscoveryResetProcessed(dmRoot, onePortContext); 5492 5493 dmDiscoveryDumpMCN(dmRoot, onePortContext); 5494 5495 if (onePortContext->discovery.SeenBC == agTRUE) 5496 { 5497 DM_DBG3(("dmDiscoverDone: broadcast change; discover again\n")); 5498 dmDiscoveryResetMCN(dmRoot, onePortContext); 5499 5500 dmInternalRemovals(dmRoot, onePortContext); 5501 5502 /* processed broadcast change */ 5503 onePortContext->discovery.SeenBC = agFALSE; 5504 if (onePortContext->discovery.ResetTriggerred == agTRUE) 5505 { 5506 DM_DBG3(("dmDiscoverDone: dmBCTimer\n")); 5507 dmBCTimer(dmRoot, onePortContext); 5508 } 5509 else 5510 { 5511 5512 dmIncrementalDiscover(dmRoot, onePortContext, agTRUE); 5513 } 5514 } 5515 else 5516 { 5517 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5518 5519 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 5520 { 5521 if (flag == DM_RC_SUCCESS) 5522 { 5523 5524 dmResetReported(dmRoot, 5525 onePortContext 5526 ); 5527 5528 dmDiscoveryReportMCN(dmRoot, 5529 onePortContext 5530 ); 5531 5532 5533 /* call tddmDiscoverCB() */ 5534 tddmDiscoverCB( 5535 dmRoot, 5536 onePortContext->dmPortContext, 5537 dmDiscCompleted 5538 ); 5539 } 5540 else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5541 { 5542 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5543 DM_DBG1(("dmDiscoverDone: Error; clean up!!!\n")); 5544 5545 dmDiscoveryInvalidateDevices(dmRoot, 5546 onePortContext 5547 ); 5548 5549 tddmDiscoverCB( 5550 dmRoot, 5551 onePortContext->dmPortContext, 5552 dmDiscFailed 5553 ); 5554 } 5555 } 5556 else 5557 { 5558 if (flag == DM_RC_SUCCESS) 5559 { 5560 dmReportChanges(dmRoot, 5561 onePortContext 5562 ); 5563 dmDiscoveryReportMCN(dmRoot, 5564 onePortContext 5565 ); 5566 tddmDiscoverCB( 5567 dmRoot, 5568 onePortContext->dmPortContext, 5569 dmDiscCompleted 5570 ); 5571 } 5572 else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5573 { 5574 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5575 dmDiscoveryInvalidateDevices(dmRoot, 5576 onePortContext 5577 ); 5578 5579 tddmDiscoverCB( 5580 dmRoot, 5581 onePortContext->dmPortContext, 5582 dmDiscFailed 5583 ); 5584 } 5585 } 5586 } 5587 return; 5588} 5589 5590/* called by dmDiscoveryErrorRemovals() or dmReportRemovals() on discovery failure */ 5591osGLOBAL void 5592dmSubReportRemovals( 5593 dmRoot_t *dmRoot, 5594 dmIntPortContext_t *onePortContext, 5595 dmDeviceData_t *oneDeviceData, 5596 bit32 flag 5597 ) 5598{ 5599 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5600 DM_DBG3(("dmSubReportRemovals: start\n")); 5601 5602 DM_DBG3(("dmSubReportRemovals: flag 0x%x\n", flag)); 5603 if (flag == dmDeviceRemoval) 5604 { 5605 oneDeviceData->registered = agFALSE; 5606 } 5607 5608 if (oneDeviceData->ExpDevice != agNULL) 5609 { 5610 DM_DBG3(("dmSubReportRemovals: attached expander case\n")); 5611 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5612 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5613 } 5614 else 5615 { 5616 DM_DBG3(("dmSubReportRemovals: NO attached expander case\n")); 5617 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5618 } 5619 5620 5621 /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5622 oneDeviceData->reported = agFALSE; 5623 return; 5624} 5625 5626 5627/* called by dmReportChanges() on discovery success */ 5628osGLOBAL void 5629dmSubReportChanges( 5630 dmRoot_t *dmRoot, 5631 dmIntPortContext_t *onePortContext, 5632 dmDeviceData_t *oneDeviceData, 5633 bit32 flag 5634 ) 5635{ 5636 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5637 DM_DBG3(("dmSubReportChanges: start\n")); 5638 5639 DM_DBG3(("dmSubReportChanges: flag 0x%x\n", flag)); 5640 if (flag == dmDeviceRemoval) 5641 { 5642 oneDeviceData->registered = agFALSE; 5643 } 5644 if (oneDeviceData->reported == agFALSE) 5645 { 5646 if (oneDeviceData->ExpDevice != agNULL) 5647 { 5648 DM_DBG3(("dmSubReportChanges: attached expander case\n")); 5649 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5650 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5651 } 5652 else 5653 { 5654 DM_DBG3(("dmSubReportChanges: NO attached expander case\n")); 5655 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5656 } 5657 } 5658 else 5659 { 5660 DM_DBG3(("dmSubReportChanges: skip; been reported\n")); 5661 } 5662 5663 5664 /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5665 oneDeviceData->reported = agFALSE; 5666 return; 5667} 5668 5669/* 5670 should add or remove be reported per device??? 5671*/ 5672osGLOBAL void 5673dmReportChanges( 5674 dmRoot_t *dmRoot, 5675 dmIntPortContext_t *onePortContext 5676 ) 5677{ 5678 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5679 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5680 dmDeviceData_t *oneDeviceData = agNULL; 5681 dmList_t *DeviceListList; 5682 bit32 added = agFALSE, removed = agFALSE; 5683// dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5684 5685 DM_DBG3(("dmReportChanges: start\n")); 5686 5687 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5688 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5689 { 5690 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5691 DM_DBG3(("dmReportChanges: empty device list\n")); 5692 return; 5693 } 5694 else 5695 { 5696 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5697 } 5698 5699 DeviceListList = dmAllShared->MainDeviceList.flink; 5700 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5701 { 5702 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5703 if (oneDeviceData == agNULL) 5704 { 5705 DM_DBG1(("dmReportChanges: oneDeviceData is NULL!!!\n")); 5706 return; 5707 } 5708 DM_DBG3(("dmReportChanges: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5709 DM_DBG3(("dmReportChanges: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5710 if ( oneDeviceData->dmPortContext == onePortContext) 5711 { 5712 DM_DBG3(("dmReportChanges: right portcontext\n")); 5713 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5714 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5715 ) 5716 { 5717 DM_DBG1(("dmReportChanges: keep, not reporting did 0x%x\n", oneDeviceData->id)); 5718 oneDeviceData->valid = agTRUE; 5719 oneDeviceData->valid2 = agFALSE; 5720 } 5721 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) ) 5722 { 5723 DM_DBG3(("dmReportChanges: same\n")); 5724 /* reset valid bit */ 5725 oneDeviceData->valid = oneDeviceData->valid2; 5726 oneDeviceData->valid2 = agFALSE; 5727 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceNoChange); 5728 } 5729 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) ) 5730 { 5731 DM_DBG3(("dmReportChanges: removed\n")); 5732 removed = agTRUE; 5733 /* reset valid bit */ 5734 oneDeviceData->valid = oneDeviceData->valid2; 5735 oneDeviceData->valid2 = agFALSE; 5736 5737 onePortContext->RegisteredDevNums--; 5738 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5739 } 5740 else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) ) 5741 { 5742 DM_DBG3(("dmReportChanges: added\n")); 5743 added = agTRUE; 5744 /* reset valid bit */ 5745 oneDeviceData->valid = oneDeviceData->valid2; 5746 oneDeviceData->valid2 = agFALSE; 5747 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceArrival); 5748 } 5749 else 5750 { 5751 DM_DBG3(("dmReportChanges: else\n")); 5752 } 5753 } 5754 else 5755 { 5756 DM_DBG3(("dmReportChanges: different portcontext\n")); 5757 } 5758 DeviceListList = DeviceListList->flink; 5759 } 5760 /* 5761 osGLOBAL void 5762tddmReportDevice( 5763 dmRoot_t *dmRoot, 5764 dmPortContext_t *dmPortContext, 5765 dmDeviceInfo_t *dmDeviceInfo, 5766 dmDeviceInfo_t *dmExpDeviceInfo, 5767 bit32 flag 5768 5769 ) 5770 5771 */ 5772 5773 /* arrival or removal at once */ 5774 if (added == agTRUE) 5775 { 5776 DM_DBG3(("dmReportChanges: added at the end\n")); 5777#if 0 /* TBD */ 5778 ostiInitiatorEvent( 5779 tiRoot, 5780 onePortContext->tiPortalContext, 5781 agNULL, 5782 tiIntrEventTypeDeviceChange, 5783 tiDeviceArrival, 5784 agNULL 5785 ); 5786#endif 5787 5788 } 5789 if (removed == agTRUE) 5790 { 5791 DM_DBG3(("dmReportChanges: removed at the end\n")); 5792#if 0 /* TBD */ 5793 ostiInitiatorEvent( 5794 tiRoot, 5795 onePortContext->tiPortalContext, 5796 agNULL, 5797 tiIntrEventTypeDeviceChange, 5798 tiDeviceRemoval, 5799 agNULL 5800 ); 5801#endif 5802 } 5803 5804 if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE) 5805 { 5806 DM_DBG3(("dmReportChanges: missed chance to report. forced to report OK\n")); 5807 onePortContext->discovery.forcedOK = agFALSE; 5808#if 0 /* TBD */ 5809 ostiInitiatorEvent( 5810 tiRoot, 5811 onePortContext->tiPortalContext, 5812 agNULL, 5813 tiIntrEventTypeDiscovery, 5814 tiDiscOK, 5815 agNULL 5816 ); 5817#endif 5818 } 5819 5820 if (added == agFALSE && removed == agFALSE) 5821 { 5822 DM_DBG3(("dmReportChanges: the same\n")); 5823 } 5824 5825 return; 5826} 5827 5828osGLOBAL void 5829dmReportRemovals( 5830 dmRoot_t *dmRoot, 5831 dmIntPortContext_t *onePortContext, 5832 bit32 flag 5833 ) 5834{ 5835 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5836 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5837 dmDeviceData_t *oneDeviceData = agNULL; 5838 dmList_t *DeviceListList; 5839 bit32 removed = agFALSE; 5840 5841 DM_DBG1(("dmReportRemovals: start\n")); 5842 5843 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5844 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5845 { 5846 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5847 DM_DBG3(("dmReportRemovals: empty device list\n")); 5848 return; 5849 } 5850 else 5851 { 5852 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5853 } 5854 5855 DeviceListList = dmAllShared->MainDeviceList.flink; 5856 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5857 { 5858 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5859 if (oneDeviceData == agNULL) 5860 { 5861 DM_DBG1(("dmReportRemovals: oneDeviceData is NULL!!!\n")); 5862 return; 5863 } 5864 DM_DBG3(("dmReportRemovals: loop did %d\n", oneDeviceData->id)); 5865 DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5866 DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5867 DM_DBG3(("dmReportRemovals: valid %d\n", oneDeviceData->valid)); 5868 DM_DBG3(("dmReportRemovals: valid2 %d\n", oneDeviceData->valid2)); 5869 DM_DBG3(("dmReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5870 if ( oneDeviceData->dmPortContext == onePortContext) 5871 { 5872 DM_DBG3(("dmReportRemovals: right portcontext pid %d\n", onePortContext->id)); 5873 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5874 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5875 ) 5876 { 5877 DM_DBG1(("dmReportRemovals: keeping\n")); 5878 oneDeviceData->valid = agTRUE; 5879 oneDeviceData->valid2 = agFALSE; 5880 } 5881 else if (oneDeviceData->valid == agTRUE) 5882 { 5883 DM_DBG3(("dmReportRemovals: removing\n")); 5884 5885 /* notify only reported devices to OS layer*/ 5886 if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || 5887 DEVICE_IS_STP_TARGET(oneDeviceData) || 5888 DEVICE_IS_SATA_DEVICE(oneDeviceData) 5889 ) 5890 { 5891 removed = agTRUE; 5892 } 5893 5894 /* all targets except expanders */ 5895 DM_DBG3(("dmReportRemovals: did %d\n", oneDeviceData->id)); 5896 DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5897 DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5898 onePortContext->RegisteredDevNums--; 5899 dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5900 5901 5902 /* reset valid bit */ 5903 oneDeviceData->valid = agFALSE; 5904 oneDeviceData->valid2 = agFALSE; 5905 5906 5907 } 5908 /* called by port invalid case */ 5909 if (flag == agTRUE) 5910 { 5911 oneDeviceData->dmPortContext = agNULL; 5912 } 5913 DeviceListList = DeviceListList->flink; 5914 } 5915 else 5916 { 5917 if (oneDeviceData->dmPortContext != agNULL) 5918 { 5919 DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5920 } 5921 else 5922 { 5923 DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5924 } 5925 DeviceListList = DeviceListList->flink; 5926 } 5927 } 5928 5929 if (removed == agTRUE) 5930 { 5931 DM_DBG3(("dmReportRemovals: removed at the end\n")); 5932#if 0 /* TBD */ 5933 ostiInitiatorEvent( 5934 tiRoot, 5935 onePortContext->tiPortalContext, 5936 agNULL, 5937 tiIntrEventTypeDeviceChange, 5938 tiDeviceRemoval, 5939 agNULL 5940 ); 5941#endif 5942 } 5943 5944 return; 5945} 5946 5947osGLOBAL void 5948dmResetReported( 5949 dmRoot_t *dmRoot, 5950 dmIntPortContext_t *onePortContext 5951 ) 5952{ 5953 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5954 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5955 dmDeviceData_t *oneDeviceData = agNULL; 5956 dmList_t *DeviceListList; 5957 5958 DM_DBG3(("dmResetReported: start\n")); 5959 5960 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5961 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5962 { 5963 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5964 DM_DBG3(("dmResetReported: empty device list\n")); 5965 return; 5966 } 5967 else 5968 { 5969 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5970 } 5971 5972 DeviceListList = dmAllShared->MainDeviceList.flink; 5973 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5974 { 5975 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5976 if (oneDeviceData == agNULL) 5977 { 5978 DM_DBG1(("dmResetReported: oneDeviceData is NULL!!!\n")); 5979 return; 5980 } 5981 DM_DBG3(("dmResetReported: loop did %d\n", oneDeviceData->id)); 5982 DM_DBG3(("dmResetReported: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5983 DM_DBG3(("dmResetReported: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5984 DM_DBG3(("dmResetReported: valid %d\n", oneDeviceData->valid)); 5985 DM_DBG3(("dmResetReported: valid2 %d\n", oneDeviceData->valid2)); 5986 DM_DBG3(("dmResetReported: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5987 if ( oneDeviceData->dmPortContext == onePortContext) 5988 { 5989 DM_DBG3(("dmResetReported: right portcontext pid %d\n", onePortContext->id)); 5990 oneDeviceData->reported = agFALSE; 5991 DeviceListList = DeviceListList->flink; 5992 } 5993 else 5994 { 5995 if (oneDeviceData->dmPortContext != agNULL) 5996 { 5997 DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5998 } 5999 else 6000 { 6001 DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6002 } 6003 DeviceListList = DeviceListList->flink; 6004 } 6005 } 6006 6007 return; 6008} 6009 6010/* called on discover failure */ 6011osGLOBAL void 6012dmDiscoveryInvalidateDevices( 6013 dmRoot_t *dmRoot, 6014 dmIntPortContext_t *onePortContext 6015 ) 6016{ 6017 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6018 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6019 dmDeviceData_t *oneDeviceData = agNULL; 6020 dmList_t *DeviceListList; 6021 6022 DM_DBG1(("dmDiscoveryInvalidateDevices: start\n")); 6023 6024 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6025 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6026 { 6027 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6028 DM_DBG3(("dmDiscoveryInvalidateDevices: empty device list\n")); 6029 return; 6030 } 6031 else 6032 { 6033 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6034 } 6035 DeviceListList = dmAllShared->MainDeviceList.flink; 6036 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6037 { 6038 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6039 if (oneDeviceData == agNULL) 6040 { 6041 DM_DBG1(("dmDiscoveryInvalidateDevices: oneDeviceData is NULL!!!\n")); 6042 return; 6043 } 6044 DM_DBG3(("dmDiscoveryInvalidateDevices: loop did %d\n", oneDeviceData->id)); 6045 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6046 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6047 DM_DBG3(("dmDiscoveryInvalidateDevices: valid %d\n", oneDeviceData->valid)); 6048 DM_DBG3(("dmDiscoveryInvalidateDevices: valid2 %d\n", oneDeviceData->valid2)); 6049 DM_DBG3(("dmDiscoveryInvalidateDevices: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6050 if ( oneDeviceData->dmPortContext == onePortContext) 6051 { 6052 DM_DBG3(("dmDiscoveryInvalidateDevices: right portcontext pid %d\n", onePortContext->id)); 6053 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6054 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6055 ) 6056 { 6057 DM_DBG1(("dmDiscoveryInvalidateDevices: keeping\n")); 6058 oneDeviceData->valid = agTRUE; 6059 oneDeviceData->valid2 = agFALSE; 6060 } 6061 else 6062 { 6063 oneDeviceData->valid = agFALSE; 6064 oneDeviceData->valid2 = agFALSE; 6065 oneDeviceData->registered = agFALSE; 6066 oneDeviceData->reported = agFALSE; 6067 /* all targets other than expanders */ 6068 DM_DBG3(("dmDiscoveryInvalidateDevices: did %d\n", oneDeviceData->id)); 6069 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6070 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6071 onePortContext->RegisteredDevNums--; 6072 } 6073 DeviceListList = DeviceListList->flink; 6074 } 6075 else 6076 { 6077 if (oneDeviceData->dmPortContext != agNULL) 6078 { 6079 DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6080 } 6081 else 6082 { 6083 DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6084 } 6085 DeviceListList = DeviceListList->flink; 6086 } 6087 } 6088 6089 return; 6090} 6091 6092 6093/* 6094 should DM report the device removal to TDM on an error case? 6095 or 6096 DM simply removes the devices 6097 For now, the second option. 6098*/ 6099osGLOBAL void 6100dmDiscoveryErrorRemovals( 6101 dmRoot_t *dmRoot, 6102 dmIntPortContext_t *onePortContext 6103 ) 6104{ 6105 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6106 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6107 dmDeviceData_t *oneDeviceData = agNULL; 6108 dmList_t *DeviceListList; 6109 6110 DM_DBG1(("dmDiscoveryErrorRemovals: start\n")); 6111 6112 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6113 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6114 { 6115 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6116 DM_DBG3(("dmDiscoveryErrorRemovals: empty device list\n")); 6117 return; 6118 } 6119 else 6120 { 6121 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6122 } 6123 DeviceListList = dmAllShared->MainDeviceList.flink; 6124 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6125 { 6126 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6127 if (oneDeviceData == agNULL) 6128 { 6129 DM_DBG1(("dmDiscoveryErrorRemovals: oneDeviceData is NULL!!!\n")); 6130 return; 6131 } 6132 DM_DBG3(("dmDiscoveryErrorRemovals: loop did %d\n", oneDeviceData->id)); 6133 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6134 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6135 DM_DBG3(("dmDiscoveryErrorRemovals: valid %d\n", oneDeviceData->valid)); 6136 DM_DBG3(("dmDiscoveryErrorRemovals: valid2 %d\n", oneDeviceData->valid2)); 6137 DM_DBG3(("dmDiscoveryErrorRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6138 if ( oneDeviceData->dmPortContext == onePortContext) 6139 { 6140 DM_DBG3(("dmDiscoveryErrorRemovals: right portcontext pid %d\n", onePortContext->id)); 6141 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6142 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6143 ) 6144 { 6145 DM_DBG1(("dmDiscoveryErrorRemovals: keeping\n")); 6146 oneDeviceData->valid = agTRUE; 6147 oneDeviceData->valid2 = agFALSE; 6148 } 6149 else 6150 { 6151 oneDeviceData->valid = agFALSE; 6152 oneDeviceData->valid2 = agFALSE; 6153 6154 /* all targets other than expanders */ 6155 DM_DBG3(("dmDiscoveryErrorRemovals: did %d\n", oneDeviceData->id)); 6156 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6157 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6158 onePortContext->RegisteredDevNums--; 6159 dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 6160 6161 } 6162 DeviceListList = DeviceListList->flink; 6163 } 6164 else 6165 { 6166 if (oneDeviceData->dmPortContext != agNULL) 6167 { 6168 DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6169 } 6170 else 6171 { 6172 DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6173 } 6174 DeviceListList = DeviceListList->flink; 6175 } 6176 } 6177 6178 return; 6179} 6180 6181/* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */ 6182osGLOBAL void 6183dmDiscoveryExpanderCleanUp( 6184 dmRoot_t *dmRoot, 6185 dmIntPortContext_t *onePortContext 6186 ) 6187{ 6188 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6189 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6190 dmExpander_t *oneExpander = agNULL; 6191 dmList_t *ExpanderList = agNULL; 6192 dmDeviceData_t *oneDeviceData = agNULL; 6193 6194 DM_DBG3(("dmDiscoveryExpanderCleanUp: start\n")); 6195 /* 6196 be sure to call 6197 osGLOBAL void 6198 dmExpanderDeviceDataReInit( 6199 dmRoot_t *dmRoot, 6200 dmExpander_t *oneExpander 6201 ); 6202 6203 */ 6204 6205 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6206 if (!DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6207 { 6208 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6209 ExpanderList = dmAllShared->mainExpanderList.flink; 6210 while (ExpanderList != &(dmAllShared->mainExpanderList)) 6211 { 6212 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6213 if (oneExpander == agNULL) 6214 { 6215 DM_DBG1(("dmDiscoveryExpanderCleanUp: oneExpander is NULL!!!\n")); 6216 return; 6217 } 6218 oneDeviceData = oneExpander->dmDevice; 6219 DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6220 DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6221 if ( oneDeviceData->dmPortContext == onePortContext) 6222 { 6223 dmExpanderDeviceDataReInit(dmRoot, oneExpander); 6224 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6225 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 6226 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 6227 6228 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6229 { 6230 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6231 break; 6232 } 6233 else 6234 { 6235 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6236 } 6237 ExpanderList = dmAllShared->mainExpanderList.flink; 6238 } 6239 else 6240 { 6241 ExpanderList = ExpanderList->flink; 6242 } 6243 } 6244 } 6245 else 6246 { 6247 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6248 DM_DBG3(("dmDiscoveryExpanderCleanUp: empty mainExpanderList\n")); 6249 } 6250 return; 6251 6252} 6253 6254 6255/* moves all devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */ 6256osGLOBAL void 6257dmDiscoveryDeviceCleanUp( 6258 dmRoot_t *dmRoot, 6259 dmIntPortContext_t *onePortContext 6260 ) 6261{ 6262 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6263 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6264 dmDeviceData_t *oneDeviceData = agNULL; 6265 dmList_t *DeviceListList; 6266 6267 DM_DBG3(("dmDiscoveryDeviceCleanUp: start\n")); 6268 6269 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6270 if (!DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6271 { 6272 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6273 DeviceListList = dmAllShared->MainDeviceList.flink; 6274 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6275 { 6276 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6277 if (oneDeviceData == agNULL) 6278 { 6279 DM_DBG1(("dmDiscoveryDeviceCleanUp: oneDeviceData is NULL!!!\n")); 6280 return; 6281 } 6282 DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6283 DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6284 if ( oneDeviceData->dmPortContext == onePortContext) 6285 { 6286 dmDeviceDataReInit(dmRoot, oneDeviceData); 6287 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6288 DMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 6289 DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(dmAllShared->FreeDeviceList)); 6290 6291 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6292 { 6293 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6294 break; 6295 } 6296 else 6297 { 6298 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6299 } 6300 onePortContext->RegisteredDevNums--; 6301 DeviceListList = dmAllShared->MainDeviceList.flink; 6302 } 6303 else 6304 { 6305 DeviceListList = DeviceListList->flink; 6306 } 6307 } 6308 } 6309 else 6310 { 6311 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6312 DM_DBG3(("dmDiscoveryDeviceCleanUp: empty MainDeviceList\n")); 6313 } 6314 return; 6315} 6316 6317 6318 6319osGLOBAL void 6320dmDumpAllExp( 6321 dmRoot_t *dmRoot, 6322 dmIntPortContext_t *onePortContext, 6323 dmExpander_t *oneExpander 6324 ) 6325{ 6326 DM_DBG3(("dmDumpAllExp: start\n")); 6327 return; 6328} 6329 6330 6331osGLOBAL void 6332dmDumpAllUpExp( 6333 dmRoot_t *dmRoot, 6334 dmIntPortContext_t *onePortContext, 6335 dmExpander_t *oneExpander 6336 ) 6337{ 6338 DM_DBG3(("dmDumpAllUpExp: start\n")); 6339 return; 6340} 6341 6342osGLOBAL void 6343dmDumpAllFreeExp( 6344 dmRoot_t *dmRoot 6345 ) 6346{ 6347 DM_DBG3(("dmDumpAllFreeExp: start\n")); 6348 return; 6349} 6350 6351osGLOBAL void 6352dmDumpAllMainExp( 6353 dmRoot_t *dmRoot, 6354 dmIntPortContext_t *onePortContext 6355 ) 6356{ 6357 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6358 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6359 dmList_t *ExpanderList; 6360 dmExpander_t *tempExpander; 6361 6362 DM_DBG3(("dmDumpAllMainExp: start\n")); 6363 6364 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6365 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6366 { 6367 DM_DBG3(("dmDumpAllMainExp: empty discoveringExpanderList\n")); 6368 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6369 return; 6370 } 6371 else 6372 { 6373 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6374 } 6375 6376 ExpanderList = dmAllShared->mainExpanderList.flink; 6377 while (ExpanderList != &(dmAllShared->mainExpanderList)) 6378 { 6379 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6380 if (tempExpander == agNULL) 6381 { 6382 DM_DBG1(("dmDumpAllMainExp: tempExpander is NULL!!!\n")); 6383 return; 6384 } 6385 DM_DBG3(("dmDumpAllMainExp: expander id %d\n", tempExpander->id)); 6386 DM_DBG3(("dmDumpAllMainExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6387 DM_DBG3(("dmDumpAllMainExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6388 if ((tempExpander->dmDevice->dmPortContext == onePortContext) 6389 ) 6390 { 6391 DM_DBG3(("dmDumpAllMainExp: found expander id %d\n", tempExpander->id)); 6392 DM_DBG3(("dmDumpAllMainExp: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6393 DM_DBG3(("dmDumpAllMainExp: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6394 } 6395 ExpanderList = ExpanderList->flink; 6396 } 6397 return; 6398} 6399 6400 6401osGLOBAL void 6402dmDumpAllMainDevice( 6403 dmRoot_t *dmRoot, 6404 dmIntPortContext_t *onePortContext 6405 ) 6406{ 6407 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6408 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6409 dmDeviceData_t *oneDeviceData = agNULL; 6410 dmList_t *DeviceListList; 6411 bit32 total = 0, port_total = 0; 6412 6413 DM_DBG3(("dmDumpAllMainDevice: start\n")); 6414 6415 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6416 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6417 { 6418 DM_DBG3(("dmDumpAllMainDevice: empty discoveringExpanderList\n")); 6419 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6420 return; 6421 } 6422 else 6423 { 6424 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6425 } 6426 6427 DeviceListList = dmAllShared->MainDeviceList.flink; 6428 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6429 { 6430 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6431 if (oneDeviceData == agNULL) 6432 { 6433 DM_DBG3(("dmDumpAllMainDevice: oneDeviceData is NULL!!!\n")); 6434 return; 6435 } 6436 DM_DBG3(("dmDumpAllMainDevice: oneDeviceData id %d\n", oneDeviceData->id)); 6437 DM_DBG3(("dmDumpAllMainDevice: addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6438 DM_DBG3(("dmDumpAllMainDevice: addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6439 total++; 6440 if ((oneDeviceData->dmPortContext == onePortContext) 6441 ) 6442 { 6443 DM_DBG3(("dmDumpAllMainDevice: found oneDeviceData id %d\n", oneDeviceData->id)); 6444 DM_DBG3(("dmDumpAllMainDevice: found addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6445 DM_DBG3(("dmDumpAllMainDevice: found addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6446 port_total++; 6447 } 6448 DeviceListList = DeviceListList->flink; 6449 } 6450 DM_DBG3(("dmDumpAllMainDevice: total %d port_totaol %d\n", total, port_total)); 6451 6452 return; 6453} 6454 6455 6456 6457osGLOBAL dmDeviceData_t * 6458dmAddSASToSharedcontext( 6459 dmRoot_t *dmRoot, 6460 dmIntPortContext_t *onePortContext, 6461 dmSASSubID_t *dmSASSubID, 6462 dmDeviceData_t *oneExpDeviceData, 6463 bit8 phyID 6464 ) 6465{ 6466 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6467 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6468 dmDeviceData_t *oneDeviceData = agNULL; 6469 dmList_t *DeviceListList; 6470 bit32 new_device = agTRUE; 6471 6472 6473 DM_DBG3(("dmAddSASToSharedcontext: start\n")); 6474 DM_DBG3(("dmAddSASToSharedcontext: oneportContext ID %d\n", onePortContext->id)); 6475 6476 if (oneExpDeviceData != agNULL) 6477 { 6478 DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6479 oneExpDeviceData->SASAddressID.sasAddressHi, oneExpDeviceData->SASAddressID.sasAddressLo)); 6480 } 6481 else 6482 { 6483 DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData is NULL\n")); 6484 } 6485 /* find a device's existence */ 6486 DeviceListList = dmAllShared->MainDeviceList.flink; 6487 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6488 { 6489 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6490 if (oneDeviceData == agNULL) 6491 { 6492 DM_DBG1(("dmAddSASToSharedcontext: oneDeviceData is NULL!!!\n")); 6493 return agNULL; 6494 } 6495 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 6496 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 6497 (oneDeviceData->dmPortContext == onePortContext) 6498 ) 6499 { 6500 DM_DBG3(("dmAddSASToSharedcontext: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6501 new_device = agFALSE; 6502 break; 6503 } 6504 DeviceListList = DeviceListList->flink; 6505 } 6506 6507 /* new device */ 6508 if (new_device == agTRUE) 6509 { 6510 DM_DBG3(("dmAddSASToSharedcontext: new device\n")); 6511 DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6512 dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6513 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6514 if (!DMLIST_NOT_EMPTY(&(dmAllShared->FreeDeviceList))) 6515 { 6516 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6517 DM_DBG1(("dmAddSASToSharedcontext: empty DeviceData FreeLink\n")); 6518 dmDumpAllMainDevice(dmRoot, onePortContext); 6519 return agNULL; 6520 } 6521 6522 DMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(dmAllShared->FreeDeviceList)); 6523 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6524 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, FreeLink, DeviceListList); 6525 6526 if (oneDeviceData != agNULL) 6527 { 6528 DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p pid %d did %d\n", oneDeviceData, onePortContext->id, oneDeviceData->id)); 6529 6530 onePortContext->Count++; 6531 oneDeviceData->dmRoot = dmRoot; 6532 /* saving sas address */ 6533 oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6534 oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6535 oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6536 oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6537 oneDeviceData->dmPortContext = onePortContext; 6538 /* handles both SAS target and STP-target, SATA-device */ 6539 if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6540 { 6541 oneDeviceData->DeviceType = DM_SAS_DEVICE; 6542 } 6543 else 6544 { 6545 oneDeviceData->DeviceType = DM_SATA_DEVICE; 6546 } 6547 6548 if (oneExpDeviceData != agNULL) 6549 { 6550 oneDeviceData->ExpDevice = oneExpDeviceData; 6551 } 6552 6553 /* set phyID only when it has initial value of 0xFF */ 6554 if (oneDeviceData->phyID == 0xFF) 6555 { 6556 oneDeviceData->phyID = phyID; 6557 } 6558 /* incremental discovery */ 6559 /* add device to incremental-related link. Report using this link 6560 when incremental discovery is done */ 6561 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6562 { 6563 DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6564 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6565 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6566 oneDeviceData->valid = agTRUE; 6567 } 6568 else 6569 { 6570 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6571 { 6572 DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6573 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6574 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6575 oneDeviceData->valid2 = agTRUE; 6576 } 6577 else 6578 { 6579 DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6580 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6581 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6582 oneDeviceData->valid = agTRUE; 6583 } 6584 } 6585 /* add the devicedata to the portcontext */ 6586 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6587 DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(dmAllShared->MainDeviceList)); 6588 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6589 DM_DBG3(("dmAddSASToSharedcontext: one case pid %d did %d \n", onePortContext->id, oneDeviceData->id)); 6590 DM_DBG3(("dmAddSASToSharedcontext: new case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6591 } 6592 } 6593 else /* old device */ 6594 { 6595 DM_DBG3(("dmAddSASToSharedcontext: old device\n")); 6596 DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 6597 DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6598 dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6599 6600 oneDeviceData->dmRoot = dmRoot; 6601 /* saving sas address */ 6602 oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6603 oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6604 oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6605 oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6606 oneDeviceData->dmPortContext = onePortContext; 6607 /* handles both SAS target and STP-target, SATA-device */ 6608 if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6609 { 6610 oneDeviceData->DeviceType = DM_SAS_DEVICE; 6611 } 6612 else 6613 { 6614 oneDeviceData->DeviceType = DM_SATA_DEVICE; 6615 } 6616 6617 if (oneExpDeviceData != agNULL) 6618 { 6619 oneDeviceData->ExpDevice = oneExpDeviceData; 6620 } 6621 6622 /* set phyID only when it has initial value of 0xFF */ 6623 if (oneDeviceData->phyID == 0xFF) 6624 { 6625 oneDeviceData->phyID = phyID; 6626 } 6627 6628 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6629 { 6630 DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6631 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6632 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6633 oneDeviceData->valid = agTRUE; 6634 } 6635 else 6636 { 6637 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6638 { 6639 DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6640 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6641 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6642 oneDeviceData->valid2 = agTRUE; 6643 } 6644 else 6645 { 6646 DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6647 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6648 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6649 oneDeviceData->valid = agTRUE; 6650 } 6651 } 6652 DM_DBG3(("dmAddSASToSharedcontext: old case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6653 6654 } 6655 return oneDeviceData; 6656} 6657 6658/* no checking of valid and valid2 */ 6659osGLOBAL dmDeviceData_t * 6660dmDeviceFind( 6661 dmRoot_t *dmRoot, 6662 dmIntPortContext_t *onePortContext, 6663 bit32 sasAddrHi, 6664 bit32 sasAddrLo 6665 ) 6666{ 6667 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6668 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6669 dmDeviceData_t *oneDeviceData = agNULL; 6670 dmList_t *DeviceListList; 6671 bit32 found = agFALSE; 6672 6673 DM_DBG3(("dmDeviceFind: start\n")); 6674 /* find a device's existence */ 6675 DeviceListList = dmAllShared->MainDeviceList.flink; 6676 6677 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6678 { 6679 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6680 if (oneDeviceData == agNULL) 6681 { 6682 DM_DBG1(("dmDeviceFind: oneDeviceData is NULL!!!\n")); 6683 return agNULL; 6684 } 6685 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 6686 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 6687// (oneDeviceData->valid == agTRUE) && 6688 (oneDeviceData->dmPortContext == onePortContext) 6689 ) 6690 { 6691 DM_DBG3(("dmDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6692 DM_DBG3(("dmDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6693 DM_DBG3(("dmDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6694 found = agTRUE; 6695 break; 6696 } 6697 DeviceListList = DeviceListList->flink; 6698 } 6699 6700 if (found == agFALSE) 6701 { 6702 DM_DBG3(("dmDeviceFind: end returning NULL\n")); 6703 return agNULL; 6704 } 6705 else 6706 { 6707 DM_DBG3(("dmDeviceFind: end returning NOT NULL\n")); 6708 return oneDeviceData; 6709 } 6710 6711} 6712 6713 6714osGLOBAL void 6715dmBCTimer( 6716 dmRoot_t *dmRoot, 6717 dmIntPortContext_t *onePortContext 6718 ) 6719{ 6720 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6721 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6722 dmDiscovery_t *discovery; 6723 6724 DM_DBG3(("dmBCTimer: start\n")); 6725 6726 discovery = &(onePortContext->discovery); 6727 6728 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6729 if (discovery->BCTimer.timerRunning == agTRUE) 6730 { 6731 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6732 dmKillTimer( 6733 dmRoot, 6734 &discovery->BCTimer 6735 ); 6736 } 6737 else 6738 { 6739 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6740 } 6741 6742 if (onePortContext->valid == agTRUE) 6743 { 6744 dmSetTimerRequest( 6745 dmRoot, 6746 &discovery->BCTimer, 6747 BC_TIMER_VALUE/dmAllShared->usecsPerTick, 6748 dmBCTimerCB, 6749 onePortContext, 6750 agNULL, 6751 agNULL 6752 ); 6753 6754 dmAddTimer( 6755 dmRoot, 6756 &dmAllShared->timerlist, 6757 &discovery->BCTimer 6758 ); 6759 6760 } 6761 6762 6763 return; 6764} 6765 6766 6767osGLOBAL void 6768dmBCTimerCB( 6769 dmRoot_t * dmRoot, 6770 void * timerData1, 6771 void * timerData2, 6772 void * timerData3 6773 ) 6774{ 6775 dmIntPortContext_t *onePortContext; 6776 dmDiscovery_t *discovery; 6777 6778 DM_DBG3(("dmBCTimerCB: start\n")); 6779 6780 onePortContext = (dmIntPortContext_t *)timerData1; 6781 discovery = &(onePortContext->discovery); 6782 6783 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6784 if (discovery->BCTimer.timerRunning == agTRUE) 6785 { 6786 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6787 dmKillTimer( 6788 dmRoot, 6789 &discovery->BCTimer 6790 ); 6791 } 6792 else 6793 { 6794 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6795 } 6796 6797 discovery->ResetTriggerred = agFALSE; 6798 6799 if (onePortContext->valid == agTRUE) 6800 { 6801 dmDiscover(dmRoot, 6802 onePortContext->dmPortContext, 6803 DM_DISCOVERY_OPTION_INCREMENTAL_START 6804 ); 6805 } 6806 return; 6807} 6808 6809/* discovery related SMP timers */ 6810osGLOBAL void 6811dmDiscoverySMPTimer(dmRoot_t *dmRoot, 6812 dmIntPortContext_t *onePortContext, 6813 bit32 functionCode, 6814 dmSMPRequestBody_t *dmSMPRequestBody 6815 ) 6816{ 6817 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6818 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6819 dmDiscovery_t *discovery; 6820 6821 DM_DBG3(("dmDiscoverySMPTimer: start\n")); 6822 DM_DBG3(("dmDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode)); 6823 6824 /* start the SMP timer which works as SMP application timer */ 6825 discovery = &(onePortContext->discovery); 6826 6827 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6828 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6829 { 6830 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6831 dmKillTimer( 6832 dmRoot, 6833 &discovery->DiscoverySMPTimer 6834 ); 6835 } 6836 else 6837 { 6838 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6839 } 6840 6841 6842 dmSetTimerRequest( 6843 dmRoot, 6844 &discovery->DiscoverySMPTimer, 6845 SMP_TIMER_VALUE/dmAllShared->usecsPerTick, 6846 dmDiscoverySMPTimerCB, 6847 onePortContext, 6848 dmSMPRequestBody, 6849 agNULL 6850 ); 6851 6852 dmAddTimer ( 6853 dmRoot, 6854 &dmAllShared->timerlist, 6855 &discovery->DiscoverySMPTimer 6856 ); 6857 6858 return; 6859} 6860 6861 6862osGLOBAL void 6863dmDiscoverySMPTimerCB( 6864 dmRoot_t * dmRoot, 6865 void * timerData1, 6866 void * timerData2, 6867 void * timerData3 6868 ) 6869{ 6870 agsaRoot_t *agRoot; 6871 dmIntPortContext_t *onePortContext; 6872 bit8 SMPFunction; 6873#ifndef DIRECT_SMP 6874 dmSMPFrameHeader_t *dmSMPFrameHeader; 6875 bit8 smpHeader[4]; 6876#endif 6877 dmSMPRequestBody_t *dmSMPRequestBody; 6878 dmDiscovery_t *discovery; 6879 dmDeviceData_t *oneDeviceData; 6880 agsaIORequest_t *agAbortIORequest = agNULL; 6881 agsaIORequest_t *agToBeAbortIORequest = agNULL; 6882 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6883 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6884 dmExpander_t *oneExpander = agNULL; 6885 dmSMPRequestBody_t *dmAbortSMPRequestBody = agNULL; 6886 dmList_t *SMPList; 6887 6888 DM_DBG1(("dmDiscoverySMPTimerCB: start!!!\n")); 6889 6890 onePortContext = (dmIntPortContext_t *)timerData1; 6891 dmSMPRequestBody = (dmSMPRequestBody_t *)timerData2; 6892 6893 discovery = &(onePortContext->discovery); 6894 oneDeviceData = dmSMPRequestBody->dmDevice; 6895 agToBeAbortIORequest = &(dmSMPRequestBody->agIORequest); 6896 agRoot = dmAllShared->agRoot; 6897 6898#ifdef DIRECT_SMP 6899 SMPFunction = dmSMPRequestBody->smpPayload[1]; 6900#else 6901 saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpHeader, 4); 6902 dmSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 6903 SMPFunction = dmSMPFrameHeader->smpFunction; 6904#endif 6905 6906 DM_DBG3(("dmDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction)); 6907 6908 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6909 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6910 { 6911 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6912 dmKillTimer( 6913 dmRoot, 6914 &discovery->DiscoverySMPTimer 6915 ); 6916 } 6917 else 6918 { 6919 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6920 } 6921 6922//for debugging 6923// saGetPendingPICI(agRoot); 6924 6925 switch (SMPFunction) 6926 { 6927 case SMP_REPORT_GENERAL: /* fall through */ 6928 case SMP_DISCOVER: /* fall through */ 6929 case SMP_CONFIGURE_ROUTING_INFORMATION: /* fall through */ 6930 DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function 0x%x !!!\n", SMPFunction)); 6931 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6932 return; /* no more things to do */ 6933 case SMP_REPORT_PHY_SATA: 6934 DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA !!!\n")); 6935 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6936 break; 6937 default: 6938 /* do nothing */ 6939 DM_DBG1(("dmDiscoverySMPTimerCB: Error, not allowed case!!!\n")); 6940 break; 6941 } 6942 6943 if (oneDeviceData->registered == agTRUE && (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) ) 6944 { 6945 /* call to saSMPAbort(one) */ 6946 /* get an smp REQUEST from the free list */ 6947 tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 6948 if (DMLIST_EMPTY(&(dmAllShared->freeSMPList))) 6949 { 6950 DM_DBG1(("dmDiscoverySMPTimerCB: no free SMP, can't abort SMP!!!\n")); 6951 tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6952 return; 6953 } 6954 else 6955 { 6956 DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList)); 6957 tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6958 dmAbortSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList); 6959 if (dmAbortSMPRequestBody == agNULL) 6960 { 6961 DM_DBG1(("dmDiscoverySMPTimerCB: dmAbortSMPRequestBody is NULL!!!\n")); 6962 return; 6963 } 6964 DM_DBG5(("dmDiscoverySMPTimerCB: SMP id %d\n", dmAbortSMPRequestBody->id)); 6965 } 6966 6967 dmAbortSMPRequestBody->dmRoot = dmRoot; 6968 6969 agAbortIORequest = &(dmAbortSMPRequestBody->agIORequest); 6970 agAbortIORequest->osData = (void *) dmAbortSMPRequestBody; 6971 agAbortIORequest->sdkData = agNULL; /* SALL takes care of this */ 6972 6973 oneExpander = oneDeviceData->dmExpander; 6974 6975 DM_DBG1(("dmDiscoverySMPTimerCB: calling saSMPAbort!!!\n")); 6976 saSMPAbort(agRoot, 6977 agAbortIORequest, 6978 0, 6979 oneExpander->agDevHandle, 6980 0, /* abort one */ 6981 agToBeAbortIORequest, 6982 dmSMPAbortCB 6983 ); 6984 } 6985 return; 6986} 6987 6988 6989 6990 6991osGLOBAL void 6992dmSMPBusyTimer(dmRoot_t *dmRoot, 6993 dmIntPortContext_t *onePortContext, 6994 dmDeviceData_t *oneDeviceData, 6995 dmSMPRequestBody_t *dmSMPRequestBody 6996 ) 6997{ 6998 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6999 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7000 dmDiscovery_t *discovery; 7001 7002 DM_DBG3(("dmSMPBusyTimer: start\n")); 7003 DM_DBG3(("dmSMPBusyTimer: pid %d\n", onePortContext->id)); 7004 7005 discovery = &(onePortContext->discovery); 7006 7007 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7008 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7009 { 7010 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7011 dmKillTimer( 7012 dmRoot, 7013 &discovery->SMPBusyTimer 7014 ); 7015 } 7016 else 7017 { 7018 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7019 } 7020 7021 dmSetTimerRequest( 7022 dmRoot, 7023 &discovery->SMPBusyTimer, 7024 SMP_BUSY_TIMER_VALUE/dmAllShared->usecsPerTick, 7025 dmSMPBusyTimerCB, 7026 onePortContext, 7027 oneDeviceData, 7028 dmSMPRequestBody 7029 ); 7030 7031 dmAddTimer ( 7032 dmRoot, 7033 &dmAllShared->timerlist, 7034 &discovery->SMPBusyTimer 7035 ); 7036 7037 7038 return; 7039} 7040 7041osGLOBAL void 7042dmSMPBusyTimerCB( 7043 dmRoot_t * dmRoot, 7044 void * timerData1, 7045 void * timerData2, 7046 void * timerData3 7047 ) 7048{ 7049 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7050 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7051 agsaRoot_t *agRoot; 7052 dmIntPortContext_t *onePortContext; 7053 dmDeviceData_t *oneDeviceData; 7054 dmSMPRequestBody_t *dmSMPRequestBody; 7055 agsaSASRequestBody_t *agSASRequestBody; 7056 agsaIORequest_t *agIORequest; 7057 agsaDevHandle_t *agDevHandle; 7058 dmDiscovery_t *discovery; 7059 bit32 status = AGSA_RC_FAILURE; 7060 dmExpander_t *oneExpander = agNULL; 7061 7062 7063 DM_DBG3(("dmSMPBusyTimerCB: start\n")); 7064 7065 onePortContext = (dmIntPortContext_t *)timerData1; 7066 oneDeviceData = (dmDeviceData_t *)timerData2; 7067 dmSMPRequestBody = (dmSMPRequestBody_t *)timerData3; 7068 agRoot = dmAllShared->agRoot; 7069 agIORequest = &(dmSMPRequestBody->agIORequest); 7070 oneExpander = oneDeviceData->dmExpander; 7071 agDevHandle = oneExpander->agDevHandle; 7072 agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 7073 discovery = &(onePortContext->discovery); 7074 7075 discovery->SMPRetries++; 7076 7077 if (discovery->SMPRetries < SMP_BUSY_RETRIES) 7078 { 7079 status = saSMPStart( 7080 agRoot, 7081 agIORequest, 7082 0, 7083 agDevHandle, 7084 AGSA_SMP_INIT_REQ, 7085 agSASRequestBody, 7086 &dmsaSMPCompleted 7087 ); 7088 } 7089 7090 if (status == AGSA_RC_SUCCESS) 7091 { 7092 discovery->SMPRetries = 0; 7093 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7094 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7095 { 7096 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7097 dmKillTimer( 7098 dmRoot, 7099 &discovery->SMPBusyTimer 7100 ); 7101 } 7102 else 7103 { 7104 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7105 } 7106 } 7107 else if (status == AGSA_RC_FAILURE) 7108 { 7109 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7110 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7111 { 7112 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7113 dmKillTimer( 7114 dmRoot, 7115 &discovery->SMPBusyTimer 7116 ); 7117 } 7118 else 7119 { 7120 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7121 } 7122 7123 discovery->SMPRetries = 0; 7124 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7125 } 7126 else /* AGSA_RC_BUSY */ 7127 { 7128 if (discovery->SMPRetries >= SMP_BUSY_RETRIES) 7129 { 7130 /* done with retris; give up */ 7131 DM_DBG3(("dmSMPBusyTimerCB: retries are over\n")); 7132 7133 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7134 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7135 { 7136 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7137 dmKillTimer( 7138 dmRoot, 7139 &discovery->SMPBusyTimer 7140 ); 7141 } 7142 else 7143 { 7144 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7145 } 7146 7147 discovery->SMPRetries = 0; 7148 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7149 7150 } 7151 else 7152 { 7153 /* keep retrying */ 7154 dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 7155 } 7156 } 7157 7158 return; 7159} 7160 7161 7162/* expander configuring timer */ 7163osGLOBAL void 7164dmDiscoveryConfiguringTimer(dmRoot_t *dmRoot, 7165 dmIntPortContext_t *onePortContext, 7166 dmDeviceData_t *oneDeviceData 7167 ) 7168{ 7169 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7170 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7171 dmDiscovery_t *discovery; 7172 7173 DM_DBG3(("dmDiscoveryConfiguringTimer: start\n")); 7174 DM_DBG3(("dmDiscoveryConfiguringTimer: pid %d\n", onePortContext->id)); 7175 7176 discovery = &(onePortContext->discovery); 7177 7178 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7179 if (discovery->discoveryTimer.timerRunning == agTRUE) 7180 { 7181 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7182 dmKillTimer( 7183 dmRoot, 7184 &discovery->discoveryTimer 7185 ); 7186 } 7187 else 7188 { 7189 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7190 } 7191 7192 DM_DBG3(("dmDiscoveryConfiguringTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7193 DM_DBG3(("dmDiscoveryConfiguringTimer: Timervalue %d\n", DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick)); 7194 7195 dmSetTimerRequest( 7196 dmRoot, 7197 &discovery->discoveryTimer, 7198 DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick, 7199 dmDiscoveryConfiguringTimerCB, 7200 onePortContext, 7201 oneDeviceData, 7202 agNULL 7203 ); 7204 7205 dmAddTimer ( 7206 dmRoot, 7207 &dmAllShared->timerlist, 7208 &discovery->discoveryTimer 7209 ); 7210 7211 7212 return; 7213} 7214 7215 7216osGLOBAL void 7217dmDiscoveryConfiguringTimerCB( 7218 dmRoot_t * dmRoot, 7219 void * timerData1, 7220 void * timerData2, 7221 void * timerData3 7222 ) 7223{ 7224 dmIntPortContext_t *onePortContext = agNULL; 7225 dmDiscovery_t *discovery = agNULL; 7226 dmDeviceData_t *oneDeviceData = agNULL; 7227 7228 onePortContext = (dmIntPortContext_t *)timerData1; 7229 oneDeviceData = (dmDeviceData_t *)timerData2; 7230 discovery = &(onePortContext->discovery); 7231 7232 DM_DBG3(("dmDiscoveryConfiguringTimerCB: start\n")); 7233 7234 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7235 if (discovery->discoveryTimer.timerRunning == agTRUE) 7236 { 7237 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7238 dmKillTimer( 7239 dmRoot, 7240 &discovery->discoveryTimer 7241 ); 7242 } 7243 else 7244 { 7245 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7246 } 7247 7248 if (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) 7249 { 7250 dmReportGeneralSend(dmRoot, oneDeviceData); 7251 } 7252 return; 7253} 7254 7255osGLOBAL void 7256dmConfigureRouteTimer(dmRoot_t *dmRoot, 7257 dmIntPortContext_t *onePortContext, 7258 dmExpander_t *oneExpander, 7259 smpRespDiscover_t *pdmSMPDiscoverResp, 7260 smpRespDiscover2_t *pdmSMPDiscover2Resp 7261 ) 7262{ 7263 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7264 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7265 dmDiscovery_t *discovery; 7266 7267 DM_DBG3(("dmConfigureRouteTimer: start\n")); 7268 7269 DM_DBG3(("dmConfigureRouteTimer: pid %d\n", onePortContext->id)); 7270 7271 discovery = &(onePortContext->discovery); 7272 7273 DM_DBG3(("dmConfigureRouteTimer: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7274 7275 DM_DBG3(("dmConfigureRouteTimer: discovery %p \n", discovery)); 7276 7277 DM_DBG3(("dmConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7278 7279 DM_DBG3(("dmConfigureRouteTimer: discovery->status %d\n", discovery->status)); 7280 7281 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7282 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7283 { 7284 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7285 dmKillTimer( 7286 dmRoot, 7287 &discovery->configureRouteTimer 7288 ); 7289 } 7290 else 7291 { 7292 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7293 } 7294 7295 DM_DBG3(("dmConfigureRouteTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7296 DM_DBG3(("dmConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick)); 7297 7298 if (oneExpander->SAS2 == 0) 7299 { 7300 /* SAS 1.1 */ 7301 dmSetTimerRequest( 7302 dmRoot, 7303 &discovery->configureRouteTimer, 7304 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7305 dmConfigureRouteTimerCB, 7306 (void *)onePortContext, 7307 (void *)oneExpander, 7308 (void *)pdmSMPDiscoverResp 7309 ); 7310 } 7311 else 7312 { 7313 /* SAS 2 */ 7314 dmSetTimerRequest( 7315 dmRoot, 7316 &discovery->configureRouteTimer, 7317 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7318 dmConfigureRouteTimerCB, 7319 (void *)onePortContext, 7320 (void *)oneExpander, 7321 (void *)pdmSMPDiscover2Resp 7322 ); 7323 } 7324 dmAddTimer ( 7325 dmRoot, 7326 &dmAllShared->timerlist, 7327 &discovery->configureRouteTimer 7328 ); 7329 7330 return; 7331} 7332 7333 7334osGLOBAL void 7335dmConfigureRouteTimerCB( 7336 dmRoot_t * dmRoot, 7337 void * timerData1, 7338 void * timerData2, 7339 void * timerData3 7340 ) 7341{ 7342 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7343 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7344 dmIntPortContext_t *onePortContext; 7345 dmExpander_t *oneExpander; 7346 smpRespDiscover_t *pdmSMPDiscoverResp = agNULL; 7347 smpRespDiscover2_t *pdmSMPDiscover2Resp = agNULL; 7348 dmDiscovery_t *discovery; 7349 7350 7351 DM_DBG3(("dmConfigureRouteTimerCB: start\n")); 7352 7353 onePortContext = (dmIntPortContext_t *)timerData1; 7354 oneExpander = (dmExpander_t *)timerData2; 7355 if (oneExpander->SAS2 == 0) 7356 { 7357 pdmSMPDiscoverResp = (smpRespDiscover_t *)timerData3; 7358 } 7359 else 7360 { 7361 pdmSMPDiscover2Resp = (smpRespDiscover2_t *)timerData3; 7362 } 7363 discovery = &(onePortContext->discovery); 7364 7365 DM_DBG3(("dmConfigureRouteTimerCB: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7366 7367 DM_DBG3(("dmConfigureRouteTimerCB: discovery %p\n", discovery)); 7368 7369 DM_DBG3(("dmConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7370 7371 DM_DBG3(("dmConfigureRouteTimerCB: discovery.status %d\n", discovery->status)); 7372 7373 discovery->configureRouteRetries++; 7374 if (discovery->configureRouteRetries >= dmAllShared->MaxRetryDiscovery) 7375 { 7376 DM_DBG3(("dmConfigureRouteTimerCB: retries are over\n")); 7377 7378 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7379 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7380 { 7381 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7382 dmKillTimer( 7383 dmRoot, 7384 &discovery->configureRouteTimer 7385 ); 7386 } 7387 else 7388 { 7389 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7390 } 7391 7392 discovery->configureRouteRetries = 0; 7393 /* failed the discovery */ 7394 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7395 7396 return; 7397 } 7398 7399 7400 if (oneExpander->SAS2 == 0) 7401 { 7402 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7403 { 7404 DM_DBG3(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscoverExpanderPhy\n")); 7405 dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 7406 discovery->configureRouteRetries = 0; 7407 7408 dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp); 7409 } 7410 else 7411 { 7412 DM_DBG3(("dmConfigureRouteTimerCB: setting timer again\n")); 7413 /* set the timer again */ 7414 dmSetTimerRequest( 7415 dmRoot, 7416 &discovery->configureRouteTimer, 7417 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7418 dmConfigureRouteTimerCB, 7419 (void *)onePortContext, 7420 (void *)oneExpander, 7421 (void *)pdmSMPDiscoverResp 7422 ); 7423 7424 dmAddTimer ( 7425 dmRoot, 7426 &dmAllShared->timerlist, 7427 &discovery->configureRouteTimer 7428 ); 7429 } 7430 } /* SAS 1.1 */ 7431 else 7432 { 7433 /* SAS 2 */ 7434 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7435 { 7436 DM_DBG2(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscover2ExpanderPhy\n")); 7437 dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 7438 7439 dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp); 7440 } 7441 else 7442 { 7443 DM_DBG2(("dmConfigureRouteTimerCB: setting timer again\n")); 7444 /* set the timer again */ 7445 dmSetTimerRequest( 7446 dmRoot, 7447 &discovery->configureRouteTimer, 7448 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7449 dmConfigureRouteTimerCB, 7450 (void *)onePortContext, 7451 (void *)oneExpander, 7452 (void *)pdmSMPDiscover2Resp 7453 ); 7454 7455 dmAddTimer ( 7456 dmRoot, 7457 &dmAllShared->timerlist, 7458 &discovery->configureRouteTimer 7459 ); 7460 } 7461 } 7462 7463 return; 7464} 7465#endif /* FDS_ DM */ 7466 7467