1285809Sscottl/******************************************************************************* 2285809Sscottl** 3285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4285809Sscottl* 5285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 6285809Sscottl*that the following conditions are met: 7285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 8285809Sscottl*following disclaimer. 9285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 10285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided 11285809Sscottl*with the distribution. 12285809Sscottl* 13285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 14285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 18285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 21285809Sscottl** 22285809Sscottl********************************************************************************/ 23285809Sscottl#include <sys/cdefs.h> 24285809Sscottl__FBSDID("$FreeBSD$"); 25285809Sscottl#include <dev/pms/config.h> 26285809Sscottl 27285809Sscottl#include <dev/pms/freebsd/driver/common/osenv.h> 28285809Sscottl#include <dev/pms/freebsd/driver/common/ostypes.h> 29285809Sscottl#include <dev/pms/freebsd/driver/common/osdebug.h> 30285809Sscottl 31285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/sa.h> 32285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 33285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 34285809Sscottl 35285809Sscottl#ifdef FDS_DM 36285809Sscottl#include <dev/pms/RefTisa/discovery/api/dm.h> 37285809Sscottl#include <dev/pms/RefTisa/discovery/api/dmapi.h> 38285809Sscottl#include <dev/pms/RefTisa/discovery/api/tddmapi.h> 39285809Sscottl 40285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 41285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 42285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmproto.h> 43285809Sscottl 44285809Sscottl/*****************************************************************************/ 45285809Sscottl/*! \brief dmDiscover 46285809Sscottl * 47285809Sscottl * 48285809Sscottl * Purpose: A discovery is started by this function 49285809Sscottl * 50285809Sscottl * \param dmRoot: DM context handle. 51285809Sscottl * \param dmPortContext: Pointer to this instance of port context 52285809Sscottl * \param option: Discovery option 53285809Sscottl * 54285809Sscottl * \return: 55285809Sscottl * DM_RC_SUCCESS 56285809Sscottl * DM_RC_FAILURE 57285809Sscottl * 58285809Sscottl */ 59285809Sscottl/*****************************************************************************/ 60285809SscottlosGLOBAL bit32 61285809SscottldmDiscover( 62285809Sscottl dmRoot_t *dmRoot, 63285809Sscottl dmPortContext_t *dmPortContext, 64285809Sscottl bit32 option) 65285809Sscottl{ 66285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 67285809Sscottl bit32 ret = DM_RC_FAILURE; 68285809Sscottl 69285809Sscottl DM_DBG3(("dmDiscover: start\n")); 70285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 71285809Sscottl 72285809Sscottl if (onePortContext == agNULL) 73285809Sscottl { 74285809Sscottl DM_DBG1(("dmDiscover: onePortContext is NULL!!!\n")); 75285809Sscottl return DM_RC_FAILURE; 76285809Sscottl } 77285809Sscottl 78285809Sscottl if (onePortContext->valid == agFALSE) 79285809Sscottl { 80285809Sscottl DM_DBG1(("dmDiscover: invalid port!!!\n")); 81285809Sscottl return DM_RC_FAILURE; 82285809Sscottl } 83285809Sscottl 84285809Sscottl if (onePortContext->RegFailed == agTRUE) 85285809Sscottl { 86285809Sscottl DM_DBG1(("dmDiscover: Registration failed!!!\n")); 87285809Sscottl return DM_RC_FAILURE; 88285809Sscottl } 89285809Sscottl 90285809Sscottl switch ( option ) 91285809Sscottl { 92285809Sscottl case DM_DISCOVERY_OPTION_FULL_START: 93285809Sscottl DM_DBG3(("dmDiscover: full, pid %d\n", onePortContext->id)); 94285809Sscottl onePortContext->discovery.type = DM_DISCOVERY_OPTION_FULL_START; 95285809Sscottl dmDiscoveryResetMCN(dmRoot, onePortContext); 96285809Sscottl ret = dmFullDiscover(dmRoot, onePortContext); 97285809Sscottl break; 98285809Sscottl case DM_DISCOVERY_OPTION_INCREMENTAL_START: 99285809Sscottl DM_DBG3(("dmDiscover: incremental, pid %d\n", onePortContext->id)); 100285809Sscottl onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 101285809Sscottl dmDiscoveryResetMCN(dmRoot, onePortContext); 102285809Sscottl ret = dmIncrementalDiscover(dmRoot, onePortContext, agFALSE); 103285809Sscottl break; 104285809Sscottl case DM_DISCOVERY_OPTION_ABORT: 105285809Sscottl DM_DBG3(("dmDiscover: abort\n")); 106285809Sscottl if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 107285809Sscottl { 108285809Sscottl if (onePortContext->discovery.pendingSMP == 0) 109285809Sscottl { 110285809Sscottl dmDiscoverAbort(dmRoot, onePortContext); 111285809Sscottl tddmDiscoverCB( 112285809Sscottl dmRoot, 113285809Sscottl onePortContext->dmPortContext, 114285809Sscottl dmDiscAborted 115285809Sscottl ); 116285809Sscottl } 117285809Sscottl else 118285809Sscottl { 119285809Sscottl DM_DBG3(("dmDiscover: abortInProgress\n")); 120285809Sscottl onePortContext->DiscoveryAbortInProgress = agTRUE; 121285809Sscottl tddmDiscoverCB( 122285809Sscottl dmRoot, 123285809Sscottl dmPortContext, 124285809Sscottl dmDiscAbortInProgress 125285809Sscottl ); 126285809Sscottl } 127285809Sscottl } 128285809Sscottl else 129285809Sscottl { 130285809Sscottl DM_DBG3(("dmDiscover: no discovery to abort\n")); 131285809Sscottl tddmDiscoverCB( 132285809Sscottl dmRoot, 133285809Sscottl dmPortContext, 134285809Sscottl dmDiscAbortInvalid 135285809Sscottl ); 136285809Sscottl } 137285809Sscottl ret = DM_RC_SUCCESS; 138285809Sscottl break; 139285809Sscottl default: 140285809Sscottl break; 141285809Sscottl } 142285809Sscottl return ret; 143285809Sscottl} 144285809Sscottl 145285809SscottlosGLOBAL bit32 146285809SscottldmFullDiscover( 147285809Sscottl dmRoot_t *dmRoot, 148285809Sscottl dmIntPortContext_t *onePortContext 149285809Sscottl ) 150285809Sscottl{ 151285809Sscottl dmExpander_t *oneExpander = agNULL; 152285809Sscottl dmSASSubID_t dmSASSubID; 153285809Sscottl dmDeviceData_t *oneExpDeviceData = agNULL; 154285809Sscottl 155285809Sscottl DM_DBG1(("dmFullDiscover: start\n")); 156285809Sscottl 157285809Sscottl if (onePortContext->valid == agFALSE) 158285809Sscottl { 159285809Sscottl DM_DBG1(("dmFullDiscover: invalid port!!!\n")); 160285809Sscottl return DM_RC_FAILURE; 161285809Sscottl } 162285809Sscottl 163285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 164285809Sscottl { 165285809Sscottl DM_DBG1(("dmFullDiscover: no two instances of discovery allowed!!!\n")); 166285809Sscottl return DM_RC_FAILURE; 167285809Sscottl } 168285809Sscottl 169285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_STARTED; 170285809Sscottl 171285809Sscottl dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 172285809Sscottl dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 173285809Sscottl 174285809Sscottl /* check OnePortContext->discovery.discoveringExpanderList */ 175285809Sscottl oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 176285809Sscottl if (oneExpander != agNULL) 177285809Sscottl { 178285809Sscottl oneExpDeviceData = oneExpander->dmDevice; 179285809Sscottl } 180285809Sscottl else 181285809Sscottl { 182285809Sscottl /* check dmAllShared->mainExpanderList */ 183285809Sscottl oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 184285809Sscottl if (oneExpander != agNULL) 185285809Sscottl { 186285809Sscottl oneExpDeviceData = oneExpander->dmDevice; 187285809Sscottl } 188285809Sscottl } 189285809Sscottl 190285809Sscottl if (oneExpDeviceData != agNULL) 191285809Sscottl { 192285809Sscottl dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 193285809Sscottl dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 194285809Sscottl oneExpDeviceData->registered = agTRUE; 195285809Sscottl dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 196285809Sscottl } 197285809Sscottl else 198285809Sscottl { 199285809Sscottl DM_DBG1(("dmFullDiscover:oneExpDeviceData is NULL!!!\n")); 200285809Sscottl return DM_RC_FAILURE; 201285809Sscottl } 202285809Sscottl 203285809Sscottl dmUpStreamDiscoverStart(dmRoot, onePortContext); 204285809Sscottl 205285809Sscottl return DM_RC_SUCCESS; 206285809Sscottl} 207285809Sscottl 208285809SscottlosGLOBAL bit32 209285809SscottldmIncrementalDiscover( 210285809Sscottl dmRoot_t *dmRoot, 211285809Sscottl dmIntPortContext_t *onePortContext, 212285809Sscottl bit32 flag 213285809Sscottl ) 214285809Sscottl{ 215285809Sscottl dmExpander_t *oneExpander = agNULL; 216285809Sscottl dmSASSubID_t dmSASSubID; 217285809Sscottl dmDeviceData_t *oneExpDeviceData = agNULL; 218285809Sscottl 219285809Sscottl DM_DBG1(("dmIncrementalDiscover: start\n")); 220285809Sscottl 221285809Sscottl if (onePortContext->valid == agFALSE) 222285809Sscottl { 223285809Sscottl DM_DBG1(("dmIncrementalDiscover: invalid port!!!\n")); 224285809Sscottl return DM_RC_FAILURE; 225285809Sscottl } 226285809Sscottl 227285809Sscottl /* TDM triggerred; let go DM triggerred */ 228285809Sscottl if (flag == agFALSE) 229285809Sscottl { 230285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 231285809Sscottl { 232285809Sscottl DM_DBG1(("dmIncrementalDiscover: no two instances of discovery allowed!!!\n")); 233285809Sscottl return DM_RC_FAILURE; 234285809Sscottl } 235285809Sscottl } 236285809Sscottl 237285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_STARTED; 238285809Sscottl onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 239285809Sscottl 240285809Sscottl dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 241285809Sscottl dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 242285809Sscottl 243285809Sscottl /* check OnePortContext->discovery.discoveringExpanderList */ 244285809Sscottl oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 245285809Sscottl if (oneExpander != agNULL) 246285809Sscottl { 247285809Sscottl oneExpDeviceData = oneExpander->dmDevice; 248285809Sscottl } 249285809Sscottl else 250285809Sscottl { 251285809Sscottl /* check dmAllShared->mainExpanderList */ 252285809Sscottl oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 253285809Sscottl if (oneExpander != agNULL) 254285809Sscottl { 255285809Sscottl oneExpDeviceData = oneExpander->dmDevice; 256285809Sscottl } 257285809Sscottl } 258285809Sscottl 259285809Sscottl if (oneExpDeviceData != agNULL) 260285809Sscottl { 261285809Sscottl dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 262285809Sscottl dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 263285809Sscottl oneExpDeviceData->registered = agTRUE; 264285809Sscottl dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 265285809Sscottl } 266285809Sscottl else 267285809Sscottl { 268285809Sscottl DM_DBG1(("dmIncrementalDiscover:oneExpDeviceData is NULL!!!\n")); 269285809Sscottl return DM_RC_FAILURE; 270285809Sscottl } 271285809Sscottl 272285809Sscottl dmUpStreamDiscoverStart(dmRoot, onePortContext); 273285809Sscottl 274285809Sscottl return DM_RC_SUCCESS; 275285809Sscottl} 276285809Sscottl 277285809SscottlosGLOBAL void 278285809SscottldmUpStreamDiscoverStart( 279285809Sscottl dmRoot_t *dmRoot, 280285809Sscottl dmIntPortContext_t *onePortContext 281285809Sscottl ) 282285809Sscottl{ 283285809Sscottl// dmExpander_t *oneExpander = agNULL; 284285809Sscottl bit32 sasAddressHi, sasAddressLo; 285285809Sscottl dmDeviceData_t *oneDeviceData; 286285809Sscottl dmExpander_t *oneExpander = agNULL; 287285809Sscottl 288285809Sscottl DM_DBG3(("dmUpStreamDiscoverStart: start\n")); 289285809Sscottl if (onePortContext->valid == agFALSE) 290285809Sscottl { 291285809Sscottl DM_DBG1(("dmUpStreamDiscoverStart: invalid port!!!\n")); 292285809Sscottl return; 293285809Sscottl } 294285809Sscottl /* 295285809Sscottl at this point, the 1st expander should have been registered. 296285809Sscottl find an expander from onePortContext 297285809Sscottl */ 298285809Sscottl sasAddressHi = onePortContext->sasRemoteAddressHi; 299285809Sscottl sasAddressLo = onePortContext->sasRemoteAddressLo; 300285809Sscottl DM_DBG3(("dmUpStreamDiscoverStart: Port Remote AddrHi 0x%08x Remote AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 301285809Sscottl 302285809Sscottl oneDeviceData = dmDeviceFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 303285809Sscottl 304285809Sscottl// oneDeviceData = oneExpander->dmDevice; 305285809Sscottl// start here 306285809Sscottl onePortContext->discovery.status = DISCOVERY_UP_STREAM; 307285809Sscottl if (oneDeviceData == agNULL) 308285809Sscottl { 309285809Sscottl DM_DBG1(("dmUpStreamDiscoverStart: oneExpander is NULL, wrong!!!\n")); 310285809Sscottl return; 311285809Sscottl } 312285809Sscottl else 313285809Sscottl { 314285809Sscottl if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 315285809Sscottl || 316285809Sscottl (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 317285809Sscottl || 318285809Sscottl DEVICE_IS_SMP_TARGET(oneDeviceData) 319285809Sscottl ) 320285809Sscottl { 321285809Sscottl#if 1 /* for incremental discovery */ 322285809Sscottl /* start here: if not on discoveringExpanderList, alloc and add 323285809Sscottl dmNewEXPorNot() 324285809Sscottl */ 325285809Sscottl oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 326285809Sscottl if ( oneExpander == agNULL) 327285809Sscottl { 328285809Sscottl /* alloc and add */ 329285809Sscottl oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 330285809Sscottl if ( oneExpander != agNULL) 331285809Sscottl { 332285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 333285809Sscottl } 334285809Sscottl else 335285809Sscottl { 336285809Sscottl DM_DBG1(("dmUpStreamDiscoverStart: failed to allocate expander or discovey aborted!!!\n")); 337285809Sscottl return; 338285809Sscottl } 339285809Sscottl } 340285809Sscottl#endif 341285809Sscottl 342285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 343285809Sscottl } 344285809Sscottl else 345285809Sscottl { 346285809Sscottl DM_DBG1(("dmUpStreamDiscoverStart: oneDeviceData is not an Expander did %d, wrong!!!\n", oneDeviceData->id)); 347285809Sscottl return; 348285809Sscottl } 349285809Sscottl } 350285809Sscottl return; 351285809Sscottl} 352285809Sscottl 353285809Sscottl/* sends report general */ 354285809SscottlosGLOBAL void 355285809SscottldmUpStreamDiscovering( 356285809Sscottl dmRoot_t *dmRoot, 357285809Sscottl dmIntPortContext_t *onePortContext, 358285809Sscottl dmDeviceData_t *oneDeviceData 359285809Sscottl ) 360285809Sscottl{ 361285809Sscottl dmList_t *ExpanderList; 362285809Sscottl dmExpander_t *oneNextExpander = agNULL; 363285809Sscottl 364285809Sscottl DM_DBG3(("dmUpStreamDiscovering: start\n")); 365285809Sscottl 366285809Sscottl if (onePortContext->valid == agFALSE) 367285809Sscottl { 368285809Sscottl DM_DBG1(("dmUpStreamDiscovering: invalid port!!!\n")); 369285809Sscottl return; 370285809Sscottl } 371285809Sscottl 372285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 373285809Sscottl if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 374285809Sscottl { 375285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 376285809Sscottl DM_DBG3(("dmUpStreamDiscovering: should be the end\n")); 377285809Sscottl oneNextExpander = agNULL; 378285809Sscottl } 379285809Sscottl else 380285809Sscottl { 381285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList)); 382285809Sscottl oneNextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 383285809Sscottl if ( oneNextExpander != agNULL) 384285809Sscottl { 385285809Sscottl DMLIST_ENQUEUE_AT_HEAD(&(oneNextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 386285809Sscottl DM_DBG3(("dmUpStreamDiscovering tdsaSASUpStreamDiscovering: dequeue head\n")); 387285809Sscottl DM_DBG3(("dmUpStreamDiscovering: expander id %d\n", oneNextExpander->id)); 388285809Sscottl } 389285809Sscottl else 390285809Sscottl { 391285809Sscottl DM_DBG1(("dmUpStreamDiscovering: oneNextExpander is NULL!!!\n")); 392285809Sscottl } 393285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 394285809Sscottl 395285809Sscottl } 396285809Sscottl 397285809Sscottl if (oneNextExpander != agNULL) 398285809Sscottl { 399285809Sscottl dmReportGeneralSend(dmRoot, oneNextExpander->dmDevice); 400285809Sscottl } 401285809Sscottl else 402285809Sscottl { 403285809Sscottl DM_DBG3(("dmUpStreamDiscovering: No more expander list\n")); 404285809Sscottl dmDownStreamDiscoverStart(dmRoot, onePortContext, oneDeviceData); 405285809Sscottl } 406285809Sscottl 407285809Sscottl return; 408285809Sscottl} 409285809Sscottl 410285809SscottlosGLOBAL void 411285809SscottldmDownStreamDiscoverStart( 412285809Sscottl dmRoot_t *dmRoot, 413285809Sscottl dmIntPortContext_t *onePortContext, 414285809Sscottl dmDeviceData_t *oneDeviceData 415285809Sscottl ) 416285809Sscottl{ 417285809Sscottl dmExpander_t *UpStreamExpander; 418285809Sscottl dmExpander_t *oneExpander; 419285809Sscottl 420285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: start\n")); 421285809Sscottl 422285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 423285809Sscottl { 424285809Sscottl DM_DBG1(("dmDownStreamDiscoverStart: invalid port or aborted discovery!!!\n")); 425285809Sscottl return; 426285809Sscottl } 427285809Sscottl 428285809Sscottl /* set discovery status */ 429285809Sscottl onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 430285809Sscottl 431285809Sscottl /* If it's an expander */ 432285809Sscottl if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 433285809Sscottl || (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 434285809Sscottl || DEVICE_IS_SMP_TARGET(oneDeviceData) 435285809Sscottl ) 436285809Sscottl { 437285809Sscottl oneExpander = oneDeviceData->dmExpander; 438285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 439285809Sscottl 440285809Sscottl /* If the two expanders are the root of two edge sets; sub-to-sub */ 441285809Sscottl if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->dmUpStreamExpander == oneExpander ) ) 442285809Sscottl { 443285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: Root found pExpander=%p pUpStreamExpander=%p\n", 444285809Sscottl oneExpander, UpStreamExpander)); 445285809Sscottl //Saves the root expander 446285809Sscottl onePortContext->discovery.RootExp = oneExpander; 447285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 448285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 449285809Sscottl 450285809Sscottl /* reset up stream inform for pExpander */ 451285809Sscottl oneExpander->dmUpStreamExpander = agNULL; 452285809Sscottl /* Add the pExpander to discovering list */ 453285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 454285809Sscottl 455285809Sscottl /* reset up stream inform for oneExpander */ 456285809Sscottl UpStreamExpander->dmUpStreamExpander = agNULL; 457285809Sscottl /* Add the UpStreamExpander to discovering list */ 458285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, UpStreamExpander); 459285809Sscottl } 460285809Sscottl /* If the two expanders are not the root of two edge sets. eg) one root */ 461285809Sscottl else 462285809Sscottl { 463285809Sscottl //Saves the root expander 464285809Sscottl onePortContext->discovery.RootExp = oneExpander; 465285809Sscottl 466285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: NO Root pExpander=%p\n", oneExpander)); 467285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 468285809Sscottl DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 469285809Sscottl 470285809Sscottl /* (2.2.2.1) Add the pExpander to discovering list */ 471285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 472285809Sscottl } 473285809Sscottl } 474285809Sscottl 475285809Sscottl /* Continue down stream discovering */ 476285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 477285809Sscottl 478285809Sscottl return; 479285809Sscottl} 480285809Sscottl 481285809SscottlosGLOBAL void 482285809SscottldmDownStreamDiscovering( 483285809Sscottl dmRoot_t *dmRoot, 484285809Sscottl dmIntPortContext_t *onePortContext, 485285809Sscottl dmDeviceData_t *oneDeviceData 486285809Sscottl ) 487285809Sscottl{ 488285809Sscottl dmExpander_t *NextExpander = agNULL; 489285809Sscottl dmList_t *ExpanderList; 490285809Sscottl 491285809Sscottl DM_DBG3(("dmDownStreamDiscovering: start\n")); 492285809Sscottl 493285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 494285809Sscottl { 495285809Sscottl DM_DBG1(("dmDownStreamDiscovering: invalid port or aborted discovery!!!\n")); 496285809Sscottl return; 497285809Sscottl } 498285809Sscottl 499285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 500285809Sscottl if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 501285809Sscottl { 502285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 503285809Sscottl DM_DBG3(("dmDownStreamDiscovering: should be the end\n")); 504285809Sscottl NextExpander = agNULL; 505285809Sscottl } 506285809Sscottl else 507285809Sscottl { 508285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList));; 509285809Sscottl NextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 510285809Sscottl if ( NextExpander != agNULL) 511285809Sscottl { 512285809Sscottl DMLIST_ENQUEUE_AT_HEAD(&(NextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList));; 513285809Sscottl DM_DBG3(("dmDownStreamDiscovering tdsaSASDownStreamDiscovering: dequeue head\n")); 514285809Sscottl DM_DBG3(("dmDownStreamDiscovering: expander id %d\n", NextExpander->id)); 515285809Sscottl } 516285809Sscottl else 517285809Sscottl { 518285809Sscottl DM_DBG1(("dmDownStreamDiscovering: NextExpander is NULL!!!\n")); 519285809Sscottl } 520285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 521285809Sscottl 522285809Sscottl } 523285809Sscottl 524285809Sscottl /* If there is an expander for continue discoving */ 525285809Sscottl if ( NextExpander != agNULL) 526285809Sscottl { 527285809Sscottl DM_DBG3(("dmDownStreamDiscovering: Found pNextExpander=%p discoveryStatus=0x%x\n", 528285809Sscottl NextExpander, onePortContext->discovery.status)); 529285809Sscottl 530285809Sscottl switch (onePortContext->discovery.status) 531285809Sscottl { 532285809Sscottl /* If the discovery status is DISCOVERY_DOWN_STREAM */ 533285809Sscottl case DISCOVERY_DOWN_STREAM: 534285809Sscottl /* Send report general for the next expander */ 535285809Sscottl DM_DBG3(("dmDownStreamDiscovering: DownStream pNextExpander=%p\n", NextExpander)); 536285809Sscottl DM_DBG3(("dmDownStreamDiscovering: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 537285809Sscottl DM_DBG3(("dmDownStreamDiscovering: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 538285809Sscottl 539285809Sscottl DM_DBG3(("dmDownStreamDiscovering: 2nd oneDeviceData %p did %d\n", NextExpander->dmDevice, NextExpander->dmDevice->id)); 540285809Sscottl DM_DBG3(("dmDownStreamDiscovering: 2nd oneExpander %p did %d\n", NextExpander, NextExpander->id)); 541285809Sscottl DM_DBG3(("dmDownStreamDiscovering: 2nd used oneExpander %p did %d\n", NextExpander->dmDevice->dmExpander, NextExpander->dmDevice->dmExpander->id)); 542285809Sscottl 543285809Sscottl if (NextExpander != NextExpander->dmDevice->dmExpander) 544285809Sscottl { 545285809Sscottl DM_DBG3(("dmDownStreamDiscovering: wrong!!!\n")); 546285809Sscottl } 547285809Sscottl 548285809Sscottl 549285809Sscottl dmReportGeneralSend(dmRoot, NextExpander->dmDevice); 550285809Sscottl break; 551285809Sscottl /* If the discovery status is DISCOVERY_CONFIG_ROUTING */ 552285809Sscottl case DISCOVERY_CONFIG_ROUTING: 553285809Sscottl case DISCOVERY_REPORT_PHY_SATA: 554285809Sscottl 555285809Sscottl /* set discovery status */ 556285809Sscottl onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 557285809Sscottl 558285809Sscottl DM_DBG3(("dmDownStreamDiscovering: pPort->discovery.status=DISCOVERY_CONFIG_ROUTING, make it DOWN_STREAM\n")); 559285809Sscottl /* If not the last phy */ 560285809Sscottl if ( NextExpander->discoveringPhyId < NextExpander->dmDevice->numOfPhys ) 561285809Sscottl { 562285809Sscottl DM_DBG3(("dmDownStreamDiscovering: pNextExpander->discoveringPhyId=0x%x pNextExpander->numOfPhys=0x%x. Send More Discover\n", 563285809Sscottl NextExpander->discoveringPhyId, NextExpander->dmDevice->numOfPhys)); 564285809Sscottl /* Send discover for the next expander */ 565285809Sscottl dmDiscoverSend(dmRoot, NextExpander->dmDevice); 566285809Sscottl } 567285809Sscottl /* If it's the last phy */ 568285809Sscottl else 569285809Sscottl { 570285809Sscottl DM_DBG3(("dmDownStreamDiscovering: Last Phy, remove expander%p start DownStream=%p\n", 571285809Sscottl NextExpander, NextExpander->dmDevice)); 572285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, NextExpander); 573285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, NextExpander->dmDevice); 574285809Sscottl } 575285809Sscottl break; 576285809Sscottl 577285809Sscottl default: 578285809Sscottl DM_DBG3(("dmDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status)); 579285809Sscottl } 580285809Sscottl } 581285809Sscottl /* If no expander for continue discoving */ 582285809Sscottl else 583285809Sscottl { 584285809Sscottl DM_DBG3(("dmDownStreamDiscovering: No more expander DONE\n")); 585285809Sscottl /* discover done */ 586285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_SUCCESS); 587285809Sscottl } 588285809Sscottl 589285809Sscottl 590285809Sscottl return; 591285809Sscottl} 592285809Sscottl 593285809SscottlosGLOBAL void 594285809SscottldmUpStreamDiscoverExpanderPhy( 595285809Sscottl dmRoot_t *dmRoot, 596285809Sscottl dmIntPortContext_t *onePortContext, 597285809Sscottl dmExpander_t *oneExpander, 598285809Sscottl smpRespDiscover_t *pDiscoverResp 599285809Sscottl ) 600285809Sscottl{ 601285809Sscottl agsaSASIdentify_t sasIdentify; 602285809Sscottl dmSASSubID_t dmSASSubID; 603285809Sscottl bit32 attachedSasHi, attachedSasLo; 604285809Sscottl dmExpander_t *AttachedExpander = agNULL; 605285809Sscottl bit8 connectionRate; 606285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 607285809Sscottl dmDeviceData_t *AttachedDevice = agNULL; 608285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 609285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 610285809Sscottl 611285809Sscottl 612285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: start\n")); 613285809Sscottl 614285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 615285809Sscottl { 616285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 617285809Sscottl return; 618285809Sscottl } 619285809Sscottl 620285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 621285809Sscottl { 622285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: wrong!!!\n")); 623285809Sscottl } 624285809Sscottl 625285809Sscottl dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 626285809Sscottl 627285809Sscottl oneDeviceData = oneExpander->dmDevice; 628285809Sscottl 629285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 630285809Sscottl oneExpander->discoveringPhyId, 631285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, 632285809Sscottl oneDeviceData->SASAddressID.sasAddressLo)); 633285809Sscottl 634285809Sscottl DM_DBG3((" Attached device: %s\n", 635285809Sscottl ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 636285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 637285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 638285809Sscottl 639285809Sscottl 640285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 641285809Sscottl { 642285809Sscottl DM_DBG3((" SAS address : %08x-%08x\n", 643285809Sscottl DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 644285809Sscottl DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 645285809Sscottl DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 646285809Sscottl DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 647285809Sscottl DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 648285809Sscottl DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 649285809Sscottl DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 650285809Sscottl DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 651285809Sscottl DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 652285809Sscottl DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 653285809Sscottl DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 654285809Sscottl } 655285809Sscottl 656285809Sscottl /* for debugging */ 657285809Sscottl if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 658285809Sscottl { 659285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 660285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 661285809Sscottl dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 662285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 663285809Sscottl return; 664285809Sscottl } 665285809Sscottl 666285809Sscottl /* saving routing attribute for non self-configuring expanders */ 667285809Sscottl oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = (bit8)DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 668285809Sscottl 669285809Sscottl if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 670285809Sscottl { 671285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 672285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 673285809Sscottl { 674285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 675285809Sscottl 676285809Sscottl /* discovery error */ 677285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 678285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 679285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 680285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 681285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 682285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 683285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 684285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 685285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 686285809Sscottl 687285809Sscottl /* (2.1.3) discovery done */ 688285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 689285809Sscottl return; 690285809Sscottl } 691285809Sscottl } 692285809Sscottl else 693285809Sscottl { 694285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 695285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 696285809Sscottl { 697285809Sscottl /* Setup sasIdentify for the attached device */ 698285809Sscottl sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 699285809Sscottl sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70); 700285809Sscottl sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 701285809Sscottl sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 702285809Sscottl *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 703285809Sscottl *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 704285809Sscottl 705285809Sscottl /* incremental discovery */ 706285809Sscottl dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 707285809Sscottl dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 708285809Sscottl dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 709285809Sscottl dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 710285809Sscottl 711285809Sscottl attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 712285809Sscottl attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 713285809Sscottl 714285809Sscottl /* If the phy has subtractive routing attribute */ 715285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 716285809Sscottl { 717285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 718285809Sscottl /* Setup upstream phys */ 719285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 720285809Sscottl /* If the expander already has an upsteam device set up */ 721285809Sscottl if (oneExpander->hasUpStreamDevice == agTRUE) 722285809Sscottl { 723285809Sscottl /* just to update MCN */ 724285809Sscottl dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 725285809Sscottl /* If the sas address doesn't match */ 726285809Sscottl if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 727285809Sscottl (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 728285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 729285809Sscottl DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 730285809Sscottl ) 731285809Sscottl { 732285809Sscottl /* TODO: discovery error, callback */ 733285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 734285809Sscottl /* call back to notify discovery error */ 735285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 736285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 737285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 738285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 739285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 740285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 741285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 742285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 743285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 744285809Sscottl /* discovery done */ 745285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 746285809Sscottl } 747285809Sscottl } 748285809Sscottl else 749285809Sscottl { 750285809Sscottl /* Setup SAS address for up stream device */ 751285809Sscottl oneExpander->hasUpStreamDevice = agTRUE; 752285809Sscottl oneExpander->upStreamSASAddressHi = attachedSasHi; 753285809Sscottl oneExpander->upStreamSASAddressLo = attachedSasLo; 754285809Sscottl if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 755285809Sscottl || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 756285809Sscottl { 757285809Sscottl /* Find the device from the discovered list */ 758285809Sscottl AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 759285809Sscottl /* New device, If the device has been discovered before */ 760285809Sscottl if ( AttachedDevice != agNULL) /* old device */ 761285809Sscottl { 762285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Seen This Device Before\n")); 763285809Sscottl /* If attached device is an edge expander */ 764285809Sscottl if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 765285809Sscottl { 766285809Sscottl /* The attached device is an expander */ 767285809Sscottl AttachedExpander = AttachedDevice->dmExpander; 768285809Sscottl /* If the two expanders are the root of the two edge expander sets */ 769285809Sscottl if ( (AttachedExpander->upStreamSASAddressHi == 770285809Sscottl DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 771285809Sscottl && (AttachedExpander->upStreamSASAddressLo == 772285809Sscottl DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 773285809Sscottl { 774285809Sscottl /* Setup upstream expander for the pExpander */ 775285809Sscottl oneExpander->dmUpStreamExpander = AttachedExpander; 776285809Sscottl } 777285809Sscottl /* If the two expanders are not the root of the two edge expander sets */ 778285809Sscottl else 779285809Sscottl { 780285809Sscottl /* TODO: loop found, discovery error, callback */ 781285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error loop detection!!!\n")); 782285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 783285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 784285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 785285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 786285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 787285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 788285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 789285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 790285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 791285809Sscottl /* discovery done */ 792285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 793285809Sscottl } 794285809Sscottl } 795285809Sscottl /* If attached device is not an edge expander */ 796285809Sscottl else 797285809Sscottl { 798285809Sscottl /*TODO: should not happen, ASSERT */ 799285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 800285809Sscottl } 801285809Sscottl } /* AttachedExpander != agNULL */ 802285809Sscottl /* New device, If the device has not been discovered before */ 803285809Sscottl else /* new device */ 804285809Sscottl { 805285809Sscottl /* Add the device */ 806285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: New device\n")); 807285809Sscottl /* read minimum rate from the configuration 808285809Sscottl onePortContext->LinkRate is SPC's local link rate 809285809Sscottl */ 810285809Sscottl connectionRate = (bit8)MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 811285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 812285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 813285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 814285809Sscottl if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 815285809Sscottl { 816285809Sscottl /* incremental discovery */ 817285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 818285809Sscottl { 819285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 820285809Sscottl dmRoot, 821285809Sscottl onePortContext, 822285809Sscottl sasIdentify, 823285809Sscottl agFALSE, 824285809Sscottl connectionRate, 825285809Sscottl dmAllShared->itNexusTimeout, 826285809Sscottl 0, 827285809Sscottl STP_DEVICE_TYPE, 828285809Sscottl oneDeviceData, 829285809Sscottl oneExpander, 830285809Sscottl pDiscoverResp->phyIdentifier 831285809Sscottl ); 832285809Sscottl } 833285809Sscottl else 834285809Sscottl { 835285809Sscottl /* incremental discovery */ 836285809Sscottl AttachedDevice = dmFindRegNValid( 837285809Sscottl dmRoot, 838285809Sscottl onePortContext, 839285809Sscottl &dmSASSubID 840285809Sscottl ); 841285809Sscottl /* not registered and not valid; add this*/ 842285809Sscottl if (AttachedDevice == agNULL) 843285809Sscottl { 844285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 845285809Sscottl dmRoot, 846285809Sscottl onePortContext, 847285809Sscottl sasIdentify, 848285809Sscottl agFALSE, 849285809Sscottl connectionRate, 850285809Sscottl dmAllShared->itNexusTimeout, 851285809Sscottl 0, 852285809Sscottl STP_DEVICE_TYPE, 853285809Sscottl oneDeviceData, 854285809Sscottl oneExpander, 855285809Sscottl pDiscoverResp->phyIdentifier 856285809Sscottl ); 857285809Sscottl } 858285809Sscottl } 859285809Sscottl } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 860285809Sscottl else 861285809Sscottl { 862285809Sscottl /* incremental discovery */ 863285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 864285809Sscottl { 865285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 866285809Sscottl dmRoot, 867285809Sscottl onePortContext, 868285809Sscottl sasIdentify, 869285809Sscottl agFALSE, 870285809Sscottl connectionRate, 871285809Sscottl dmAllShared->itNexusTimeout, 872285809Sscottl 0, 873285809Sscottl SAS_DEVICE_TYPE, 874285809Sscottl oneDeviceData, 875285809Sscottl oneExpander, 876285809Sscottl pDiscoverResp->phyIdentifier 877285809Sscottl ); 878285809Sscottl } 879285809Sscottl else 880285809Sscottl { 881285809Sscottl /* incremental discovery */ 882285809Sscottl AttachedDevice = dmFindRegNValid( 883285809Sscottl dmRoot, 884285809Sscottl onePortContext, 885285809Sscottl &dmSASSubID 886285809Sscottl ); 887285809Sscottl /* not registered and not valid; add this*/ 888285809Sscottl if (AttachedDevice == agNULL) 889285809Sscottl { 890285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 891285809Sscottl dmRoot, 892285809Sscottl onePortContext, 893285809Sscottl sasIdentify, 894285809Sscottl agFALSE, 895285809Sscottl connectionRate, 896285809Sscottl dmAllShared->itNexusTimeout, 897285809Sscottl 0, 898285809Sscottl SAS_DEVICE_TYPE, 899285809Sscottl oneDeviceData, 900285809Sscottl oneExpander, 901285809Sscottl pDiscoverResp->phyIdentifier 902285809Sscottl ); 903285809Sscottl } 904285809Sscottl } 905285809Sscottl } 906285809Sscottl /* If the device is added successfully */ 907285809Sscottl if ( AttachedDevice != agNULL) 908285809Sscottl { 909285809Sscottl 910285809Sscottl /* (3.1.2.3.2.3.2.1) callback about new device */ 911285809Sscottl if ( DISCRSP_IS_SSP_TARGET(pDiscoverResp) 912285809Sscottl || DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 913285809Sscottl || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 914285809Sscottl || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 915285809Sscottl { 916285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 917285809Sscottl attachedSasHi, attachedSasLo)); 918285809Sscottl } 919285809Sscottl else 920285809Sscottl { 921285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n")); 922285809Sscottl } 923285809Sscottl /* If the attached device is an expander */ 924285809Sscottl if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 925285809Sscottl || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 926285809Sscottl { 927285809Sscottl /* Allocate an expander data structure */ 928285809Sscottl AttachedExpander = dmDiscoveringExpanderAlloc( 929285809Sscottl dmRoot, 930285809Sscottl onePortContext, 931285809Sscottl AttachedDevice 932285809Sscottl ); 933285809Sscottl 934285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander)); 935285809Sscottl /* If allocate successfully */ 936285809Sscottl if ( AttachedExpander != agNULL) 937285809Sscottl { 938285809Sscottl /* Add the pAttachedExpander to discovering list */ 939285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 940285809Sscottl /* Setup upstream expander for the pExpander */ 941285809Sscottl oneExpander->dmUpStreamExpander = AttachedExpander; 942285809Sscottl } 943285809Sscottl /* If failed to allocate */ 944285809Sscottl else 945285809Sscottl { 946285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 947285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 948285809Sscottl } 949285809Sscottl } 950285809Sscottl /* If the attached device is an end device */ 951285809Sscottl else 952285809Sscottl { 953285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found end device\n")); 954285809Sscottl /* LP2006-05-26 added upstream device to the newly found device */ 955285809Sscottl AttachedDevice->dmExpander = oneExpander; 956285809Sscottl oneExpander->dmUpStreamExpander = agNULL; 957285809Sscottl } 958285809Sscottl } 959285809Sscottl else 960285809Sscottl { 961285809Sscottl DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 962285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 963285809Sscottl } 964285809Sscottl 965285809Sscottl 966285809Sscottl 967285809Sscottl } /* else, new device */ 968285809Sscottl } /* onePortContext->sasLocalAddressLo != attachedSasLo */ 969285809Sscottl } /* else */ 970285809Sscottl } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 971285809Sscottl } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 972285809Sscottl } /* big else */ 973285809Sscottl 974285809Sscottl 975285809Sscottl 976285809Sscottl oneExpander->discoveringPhyId ++; 977285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 978285809Sscottl { 979285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 980285809Sscottl { 981285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 982285809Sscottl /* continue discovery for the next phy */ 983285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 984285809Sscottl } 985285809Sscottl else 986285809Sscottl { 987285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 988285809Sscottl 989285809Sscottl /* for MCN */ 990285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 991285809Sscottl /* remove the expander from the discovering list */ 992285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 993285809Sscottl /* continue upstream discovering */ 994285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 995285809Sscottl } 996285809Sscottl } 997285809Sscottl else 998285809Sscottl { 999285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1000285809Sscottl 1001285809Sscottl } 1002285809Sscottl 1003285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 1004285809Sscottl 1005285809Sscottl return; 1006285809Sscottl} 1007285809Sscottl 1008285809SscottlosGLOBAL void 1009285809SscottldmUpStreamDiscover2ExpanderPhy( 1010285809Sscottl dmRoot_t *dmRoot, 1011285809Sscottl dmIntPortContext_t *onePortContext, 1012285809Sscottl dmExpander_t *oneExpander, 1013285809Sscottl smpRespDiscover2_t *pDiscoverResp 1014285809Sscottl ) 1015285809Sscottl{ 1016285809Sscottl dmDeviceData_t *oneDeviceData; 1017285809Sscottl dmDeviceData_t *AttachedDevice = agNULL; 1018285809Sscottl dmExpander_t *AttachedExpander; 1019285809Sscottl agsaSASIdentify_t sasIdentify; 1020285809Sscottl bit8 connectionRate; 1021285809Sscottl bit32 attachedSasHi, attachedSasLo; 1022285809Sscottl dmSASSubID_t dmSASSubID; 1023285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1024285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1025285809Sscottl 1026285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: start\n")); 1027285809Sscottl 1028285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1029285809Sscottl { 1030285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 1031285809Sscottl return; 1032285809Sscottl } 1033285809Sscottl 1034285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 1035285809Sscottl { 1036285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: wrong!!!\n")); 1037285809Sscottl } 1038285809Sscottl 1039285809Sscottl dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 1040285809Sscottl 1041285809Sscottl oneDeviceData = oneExpander->dmDevice; 1042285809Sscottl 1043285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 1044285809Sscottl oneExpander->discoveringPhyId, 1045285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, 1046285809Sscottl oneDeviceData->SASAddressID.sasAddressLo)); 1047285809Sscottl 1048285809Sscottl DM_DBG2((" Attached device: %s\n", 1049285809Sscottl ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 1050285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 1051285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 1052285809Sscottl 1053285809Sscottl 1054285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1055285809Sscottl { 1056285809Sscottl DM_DBG2((" SAS address : %08x-%08x\n", 1057285809Sscottl SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 1058285809Sscottl SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 1059285809Sscottl DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 1060285809Sscottl DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 1061285809Sscottl DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1062285809Sscottl DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1063285809Sscottl DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1064285809Sscottl DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 1065285809Sscottl DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 1066285809Sscottl DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 1067285809Sscottl DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 1068285809Sscottl } 1069285809Sscottl 1070285809Sscottl if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 1071285809Sscottl { 1072285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 1073285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 1074285809Sscottl dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 1075285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1076285809Sscottl return; 1077285809Sscottl } 1078285809Sscottl 1079285809Sscottl /* saving routing attribute for non self-configuring expanders */ 1080285809Sscottl oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 1081285809Sscottl 1082285809Sscottl if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 1083285809Sscottl { 1084285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 1085285809Sscottl if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1086285809Sscottl { 1087285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 1088285809Sscottl 1089285809Sscottl /* discovery error */ 1090285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1091285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1092285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1093285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1094285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1095285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1096285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1097285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1098285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1099285809Sscottl 1100285809Sscottl /* (2.1.3) discovery done */ 1101285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1102285809Sscottl return; 1103285809Sscottl } 1104285809Sscottl } 1105285809Sscottl else 1106285809Sscottl { 1107285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 1108285809Sscottl 1109285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1110285809Sscottl { 1111285809Sscottl /* Setup sasIdentify for the attached device */ 1112285809Sscottl sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1113285809Sscottl sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 1114285809Sscottl sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1115285809Sscottl sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1116285809Sscottl *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1117285809Sscottl *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1118285809Sscottl 1119285809Sscottl /* incremental discovery */ 1120285809Sscottl dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1121285809Sscottl dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1122285809Sscottl dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1123285809Sscottl dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1124285809Sscottl 1125285809Sscottl attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1126285809Sscottl attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1127285809Sscottl 1128285809Sscottl /* If the phy has subtractive routing attribute */ 1129285809Sscottl if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1130285809Sscottl { 1131285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 1132285809Sscottl /* Setup upstream phys */ 1133285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 1134285809Sscottl /* If the expander already has an upsteam device set up */ 1135285809Sscottl if (oneExpander->hasUpStreamDevice == agTRUE) 1136285809Sscottl { 1137285809Sscottl /* just to update MCN */ 1138285809Sscottl dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1139285809Sscottl /* If the sas address doesn't match */ 1140285809Sscottl if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 1141285809Sscottl (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 1142285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1143285809Sscottl SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1144285809Sscottl ) 1145285809Sscottl { 1146285809Sscottl /* TODO: discovery error, callback */ 1147285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1148285809Sscottl /* call back to notify discovery error */ 1149285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1150285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1151285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1152285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1153285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1154285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1155285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1156285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1157285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1158285809Sscottl /* discovery done */ 1159285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1160285809Sscottl } 1161285809Sscottl } 1162285809Sscottl else 1163285809Sscottl { 1164285809Sscottl /* Setup SAS address for up stream device */ 1165285809Sscottl oneExpander->hasUpStreamDevice = agTRUE; 1166285809Sscottl oneExpander->upStreamSASAddressHi = attachedSasHi; 1167285809Sscottl oneExpander->upStreamSASAddressLo = attachedSasLo; 1168285809Sscottl 1169285809Sscottl if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 1170285809Sscottl || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 1171285809Sscottl { 1172285809Sscottl /* Find the device from the discovered list */ 1173285809Sscottl AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1174285809Sscottl /* If the device has been discovered before */ 1175285809Sscottl if ( AttachedDevice != agNULL) 1176285809Sscottl { 1177285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Seen This Device Before\n")); 1178285809Sscottl /* If attached device is an edge expander */ 1179285809Sscottl if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 1180285809Sscottl { 1181285809Sscottl /* The attached device is an expander */ 1182285809Sscottl AttachedExpander = AttachedDevice->dmExpander; 1183285809Sscottl /* If the two expanders are the root of the two edge expander sets */ 1184285809Sscottl if ( (AttachedExpander->upStreamSASAddressHi == 1185285809Sscottl DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1186285809Sscottl && (AttachedExpander->upStreamSASAddressLo == 1187285809Sscottl DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 1188285809Sscottl { 1189285809Sscottl /* Setup upstream expander for the pExpander */ 1190285809Sscottl oneExpander->dmUpStreamExpander = AttachedExpander; 1191285809Sscottl } 1192285809Sscottl /* If the two expanders are not the root of the two edge expander sets */ 1193285809Sscottl else 1194285809Sscottl { 1195285809Sscottl /* TODO: loop found, discovery error, callback */ 1196285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error loop detection!!!\n")); 1197285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1198285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1199285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1200285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1201285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1202285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1203285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1204285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1205285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1206285809Sscottl /* discovery done */ 1207285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1208285809Sscottl } 1209285809Sscottl } 1210285809Sscottl /* If attached device is not an edge expander */ 1211285809Sscottl else 1212285809Sscottl { 1213285809Sscottl /*TODO: should not happen, ASSERT */ 1214285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 1215285809Sscottl } 1216285809Sscottl } 1217285809Sscottl /* If the device has not been discovered before */ 1218285809Sscottl else 1219285809Sscottl { 1220285809Sscottl /* Add the device */ 1221285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: New device\n")); 1222285809Sscottl /* read minimum rate from the configuration 1223285809Sscottl onePortContext->LinkRate is SPC's local link rate 1224285809Sscottl */ 1225285809Sscottl connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 1226285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 1227285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 1228285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 1229285809Sscottl //hhhhhhhh 1230285809Sscottl if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 1231285809Sscottl { 1232285809Sscottl /* incremental discovery */ 1233285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1234285809Sscottl { 1235285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1236285809Sscottl dmRoot, 1237285809Sscottl onePortContext, 1238285809Sscottl sasIdentify, 1239285809Sscottl agFALSE, 1240285809Sscottl connectionRate, 1241285809Sscottl dmAllShared->itNexusTimeout, 1242285809Sscottl 0, 1243285809Sscottl STP_DEVICE_TYPE, 1244285809Sscottl oneDeviceData, 1245285809Sscottl oneExpander, 1246285809Sscottl pDiscoverResp->phyIdentifier 1247285809Sscottl ); 1248285809Sscottl } 1249285809Sscottl else 1250285809Sscottl { 1251285809Sscottl /* incremental discovery */ 1252285809Sscottl AttachedDevice = dmFindRegNValid( 1253285809Sscottl dmRoot, 1254285809Sscottl onePortContext, 1255285809Sscottl &dmSASSubID 1256285809Sscottl ); 1257285809Sscottl /* not registered and not valid; add this*/ 1258285809Sscottl if (AttachedDevice == agNULL) 1259285809Sscottl { 1260285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1261285809Sscottl dmRoot, 1262285809Sscottl onePortContext, 1263285809Sscottl sasIdentify, 1264285809Sscottl agFALSE, 1265285809Sscottl connectionRate, 1266285809Sscottl dmAllShared->itNexusTimeout, 1267285809Sscottl 0, 1268285809Sscottl STP_DEVICE_TYPE, 1269285809Sscottl oneDeviceData, 1270285809Sscottl oneExpander, 1271285809Sscottl pDiscoverResp->phyIdentifier 1272285809Sscottl ); 1273285809Sscottl } 1274285809Sscottl } 1275285809Sscottl } 1276285809Sscottl else 1277285809Sscottl { 1278285809Sscottl /* incremental discovery */ 1279285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1280285809Sscottl { 1281285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1282285809Sscottl dmRoot, 1283285809Sscottl onePortContext, 1284285809Sscottl sasIdentify, 1285285809Sscottl agFALSE, 1286285809Sscottl connectionRate, 1287285809Sscottl dmAllShared->itNexusTimeout, 1288285809Sscottl 0, 1289285809Sscottl SAS_DEVICE_TYPE, 1290285809Sscottl oneDeviceData, 1291285809Sscottl oneExpander, 1292285809Sscottl pDiscoverResp->phyIdentifier 1293285809Sscottl ); 1294285809Sscottl } 1295285809Sscottl else 1296285809Sscottl { 1297285809Sscottl /* incremental discovery */ 1298285809Sscottl AttachedDevice = dmFindRegNValid( 1299285809Sscottl dmRoot, 1300285809Sscottl onePortContext, 1301285809Sscottl &dmSASSubID 1302285809Sscottl ); 1303285809Sscottl /* not registered and not valid; add this*/ 1304285809Sscottl if (AttachedDevice == agNULL) 1305285809Sscottl { 1306285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1307285809Sscottl dmRoot, 1308285809Sscottl onePortContext, 1309285809Sscottl sasIdentify, 1310285809Sscottl agFALSE, 1311285809Sscottl connectionRate, 1312285809Sscottl dmAllShared->itNexusTimeout, 1313285809Sscottl 0, 1314285809Sscottl SAS_DEVICE_TYPE, 1315285809Sscottl oneDeviceData, 1316285809Sscottl oneExpander, 1317285809Sscottl pDiscoverResp->phyIdentifier 1318285809Sscottl ); 1319285809Sscottl } 1320285809Sscottl } 1321285809Sscottl } 1322285809Sscottl /* If the device is added successfully */ 1323285809Sscottl if ( AttachedDevice != agNULL) 1324285809Sscottl { 1325285809Sscottl 1326285809Sscottl /* (3.1.2.3.2.3.2.1) callback about new device */ 1327285809Sscottl if ( SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp) 1328285809Sscottl || SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 1329285809Sscottl || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 1330285809Sscottl || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 1331285809Sscottl { 1332285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 1333285809Sscottl attachedSasHi, attachedSasLo)); 1334285809Sscottl } 1335285809Sscottl else 1336285809Sscottl { 1337285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found a SAS STP device.\n")); 1338285809Sscottl } 1339285809Sscottl /* If the attached device is an expander */ 1340285809Sscottl if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1341285809Sscottl || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 1342285809Sscottl { 1343285809Sscottl /* Allocate an expander data structure */ 1344285809Sscottl AttachedExpander = dmDiscoveringExpanderAlloc( 1345285809Sscottl dmRoot, 1346285809Sscottl onePortContext, 1347285809Sscottl AttachedDevice 1348285809Sscottl ); 1349285809Sscottl 1350285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found expander=%p\n", AttachedExpander)); 1351285809Sscottl /* If allocate successfully */ 1352285809Sscottl if ( AttachedExpander != agNULL) 1353285809Sscottl { 1354285809Sscottl /* Add the pAttachedExpander to discovering list */ 1355285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1356285809Sscottl /* Setup upstream expander for the pExpander */ 1357285809Sscottl oneExpander->dmUpStreamExpander = AttachedExpander; 1358285809Sscottl } 1359285809Sscottl /* If failed to allocate */ 1360285809Sscottl else 1361285809Sscottl { 1362285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 1363285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1364285809Sscottl } 1365285809Sscottl } 1366285809Sscottl /* If the attached device is an end device */ 1367285809Sscottl else 1368285809Sscottl { 1369285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found end device\n")); 1370285809Sscottl /* LP2006-05-26 added upstream device to the newly found device */ 1371285809Sscottl AttachedDevice->dmExpander = oneExpander; 1372285809Sscottl oneExpander->dmUpStreamExpander = agNULL; 1373285809Sscottl } 1374285809Sscottl } 1375285809Sscottl else 1376285809Sscottl { 1377285809Sscottl DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 1378285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1379285809Sscottl } 1380285809Sscottl } 1381285809Sscottl } 1382285809Sscottl } 1383285809Sscottl } /* substractive routing */ 1384285809Sscottl } 1385285809Sscottl } 1386285809Sscottl 1387285809Sscottl oneExpander->discoveringPhyId ++; 1388285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 1389285809Sscottl { 1390285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 1391285809Sscottl { 1392285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 1393285809Sscottl /* continue discovery for the next phy */ 1394285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 1395285809Sscottl } 1396285809Sscottl else 1397285809Sscottl { 1398285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 1399285809Sscottl 1400285809Sscottl /* for MCN */ 1401285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 1402285809Sscottl /* remove the expander from the discovering list */ 1403285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 1404285809Sscottl /* continue upstream discovering */ 1405285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 1406285809Sscottl } 1407285809Sscottl } 1408285809Sscottl else 1409285809Sscottl { 1410285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1411285809Sscottl 1412285809Sscottl } 1413285809Sscottl 1414285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 1415285809Sscottl 1416285809Sscottl return; 1417285809Sscottl} 1418285809Sscottl 1419285809Sscottl 1420285809SscottlosGLOBAL void 1421285809SscottldmDownStreamDiscoverExpanderPhy( 1422285809Sscottl dmRoot_t *dmRoot, 1423285809Sscottl dmIntPortContext_t *onePortContext, 1424285809Sscottl dmExpander_t *oneExpander, 1425285809Sscottl smpRespDiscover_t *pDiscoverResp 1426285809Sscottl ) 1427285809Sscottl{ 1428285809Sscottl agsaSASIdentify_t sasIdentify; 1429285809Sscottl dmSASSubID_t dmSASSubID; 1430285809Sscottl bit32 attachedSasHi, attachedSasLo; 1431285809Sscottl dmExpander_t *AttachedExpander; 1432285809Sscottl dmExpander_t *UpStreamExpander; 1433285809Sscottl dmExpander_t *ConfigurableExpander = agNULL; 1434285809Sscottl bit8 connectionRate, negotiatedPhyLinkRate; 1435285809Sscottl bit32 configSASAddressHi; 1436285809Sscottl bit32 configSASAddressLo; 1437285809Sscottl bit32 dupConfigSASAddr = agFALSE; 1438285809Sscottl dmDeviceData_t *oneDeviceData; 1439285809Sscottl dmDeviceData_t *AttachedDevice = agNULL; 1440285809Sscottl bit32 SAS2SAS11Check = agFALSE; 1441285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1442285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1443285809Sscottl 1444285809Sscottl 1445285809Sscottl 1446285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: start\n")); 1447285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1448285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1449285809Sscottl 1450285809Sscottl DM_ASSERT(dmRoot, "(dmDownStreamDiscoverExpanderPhy) dmRoot NULL"); 1451285809Sscottl DM_ASSERT(onePortContext, "(dmDownStreamDiscoverExpanderPhy) pPort NULL"); 1452285809Sscottl DM_ASSERT(oneExpander, "(dmDownStreamDiscoverExpanderPhy) pExpander NULL"); 1453285809Sscottl DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscoverExpanderPhy) pDiscoverResp NULL"); 1454285809Sscottl 1455285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p\n", onePortContext, oneExpander)); 1456285809Sscottl 1457285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1458285809Sscottl { 1459285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 1460285809Sscottl return; 1461285809Sscottl } 1462285809Sscottl 1463285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 1464285809Sscottl { 1465285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: wrong!!!\n")); 1466285809Sscottl } 1467285809Sscottl 1468285809Sscottl /* (1) Find the device structure of the expander */ 1469285809Sscottl oneDeviceData = oneExpander->dmDevice; 1470285809Sscottl 1471285809Sscottl DM_ASSERT(oneDeviceData, "(dmDownStreamDiscoverExpanderPhy) pDevice NULL"); 1472285809Sscottl 1473285809Sscottl /* for debugging */ 1474285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 1475285809Sscottl oneExpander->discoveringPhyId, 1476285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, 1477285809Sscottl oneDeviceData->SASAddressID.sasAddressLo)); 1478285809Sscottl 1479285809Sscottl DM_DBG3((" Attached device: %s\n", 1480285809Sscottl ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 1481285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 1482285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 1483285809Sscottl 1484285809Sscottl 1485285809Sscottl /* for debugging */ 1486285809Sscottl if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 1487285809Sscottl { 1488285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 1489285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 1490285809Sscottl dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 1491285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1492285809Sscottl return; 1493285809Sscottl } 1494285809Sscottl 1495285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1496285809Sscottl { 1497285809Sscottl DM_DBG3((" SAS address : %08x-%08x\n", 1498285809Sscottl DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 1499285809Sscottl DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 1500285809Sscottl DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 1501285809Sscottl DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 1502285809Sscottl DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1503285809Sscottl DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1504285809Sscottl DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1505285809Sscottl DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 1506285809Sscottl DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 1507285809Sscottl DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 1508285809Sscottl DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 1509285809Sscottl 1510285809Sscottl } 1511285809Sscottl /* end for debugging */ 1512285809Sscottl 1513285809Sscottl /* saving routing attribute for non self-configuring expanders */ 1514285809Sscottl oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 1515285809Sscottl 1516285809Sscottl oneExpander->discoverSMPAllowed = agTRUE; 1517285809Sscottl 1518285809Sscottl /* If a device is attached */ 1519285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1520285809Sscottl { 1521285809Sscottl /* Setup sasIdentify for the attached device */ 1522285809Sscottl sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1523285809Sscottl sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceType & 0x70; 1524285809Sscottl sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1525285809Sscottl sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1526285809Sscottl *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1527285809Sscottl *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1528285809Sscottl 1529285809Sscottl /* incremental discovery */ 1530285809Sscottl dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1531285809Sscottl dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1532285809Sscottl dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1533285809Sscottl dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1534285809Sscottl 1535285809Sscottl attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1536285809Sscottl attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1537285809Sscottl 1538285809Sscottl /* If it's a direct routing */ 1539285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 1540285809Sscottl { 1541285809Sscottl /* If the attached device is an expander */ 1542285809Sscottl if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1543285809Sscottl || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 1544285809Sscottl 1545285809Sscottl { 1546285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 1547285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1548285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1549285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1550285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1551285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1552285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1553285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1554285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1555285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1556285809Sscottl 1557285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1558285809Sscottl return; 1559285809Sscottl } 1560285809Sscottl } 1561285809Sscottl 1562285809Sscottl /* If the expander's attached device is not myself */ 1563285809Sscottl if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 1564285809Sscottl || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 1565285809Sscottl { 1566285809Sscottl /* Find the attached device from discovered list */ 1567285809Sscottl AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1568285809Sscottl /* If the device has not been discovered before */ 1569285809Sscottl if ( AttachedDevice == agNULL) //11 1570285809Sscottl { 1571285809Sscottl /* If the phy has subtractive routing attribute */ 1572285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 1573285809Sscottl (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1574285809Sscottl DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1575285809Sscottl ) 1576285809Sscottl { 1577285809Sscottl /* TODO: discovery error, callback */ 1578285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Deferred!!! **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1579285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1580285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1581285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1582285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1583285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1584285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1585285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1586285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1587285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1588285809Sscottl 1589285809Sscottl onePortContext->discovery.DeferredError = agTRUE; 1590285809Sscottl } 1591285809Sscottl else /* 11 */ 1592285809Sscottl { 1593285809Sscottl /* Add the device */ 1594285809Sscottl /* read minimum rate from the configuration 1595285809Sscottl onePortContext->LinkRate is SPC's local link rate 1596285809Sscottl */ 1597285809Sscottl connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 1598285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 1599285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 1600285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 1601285809Sscottl if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 1602285809Sscottl { 1603285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1604285809Sscottl { 1605285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1606285809Sscottl dmRoot, 1607285809Sscottl onePortContext, 1608285809Sscottl sasIdentify, 1609285809Sscottl agFALSE, 1610285809Sscottl connectionRate, 1611285809Sscottl dmAllShared->itNexusTimeout, 1612285809Sscottl 0, 1613285809Sscottl STP_DEVICE_TYPE, 1614285809Sscottl oneDeviceData, 1615285809Sscottl oneExpander, 1616285809Sscottl pDiscoverResp->phyIdentifier 1617285809Sscottl ); 1618285809Sscottl } 1619285809Sscottl else 1620285809Sscottl { 1621285809Sscottl /* incremental discovery */ 1622285809Sscottl AttachedDevice = dmFindRegNValid( 1623285809Sscottl dmRoot, 1624285809Sscottl onePortContext, 1625285809Sscottl &dmSASSubID 1626285809Sscottl ); 1627285809Sscottl /* not registered and not valid; add this*/ 1628285809Sscottl if (AttachedDevice == agNULL) 1629285809Sscottl { 1630285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1631285809Sscottl dmRoot, 1632285809Sscottl onePortContext, 1633285809Sscottl sasIdentify, 1634285809Sscottl agFALSE, 1635285809Sscottl connectionRate, 1636285809Sscottl dmAllShared->itNexusTimeout, 1637285809Sscottl 0, 1638285809Sscottl STP_DEVICE_TYPE, 1639285809Sscottl oneDeviceData, 1640285809Sscottl oneExpander, 1641285809Sscottl pDiscoverResp->phyIdentifier 1642285809Sscottl ); 1643285809Sscottl } 1644285809Sscottl } 1645285809Sscottl } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 1646285809Sscottl else /* 22 */ 1647285809Sscottl { 1648285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1649285809Sscottl { 1650285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1651285809Sscottl dmRoot, 1652285809Sscottl onePortContext, 1653285809Sscottl sasIdentify, 1654285809Sscottl agFALSE, 1655285809Sscottl connectionRate, 1656285809Sscottl dmAllShared->itNexusTimeout, 1657285809Sscottl 0, 1658285809Sscottl SAS_DEVICE_TYPE, 1659285809Sscottl oneDeviceData, 1660285809Sscottl oneExpander, 1661285809Sscottl pDiscoverResp->phyIdentifier 1662285809Sscottl ); 1663285809Sscottl } 1664285809Sscottl else 1665285809Sscottl { 1666285809Sscottl /* incremental discovery */ 1667285809Sscottl AttachedDevice = dmFindRegNValid( 1668285809Sscottl dmRoot, 1669285809Sscottl onePortContext, 1670285809Sscottl &dmSASSubID 1671285809Sscottl ); 1672285809Sscottl /* not registered and not valid; add this*/ 1673285809Sscottl if (AttachedDevice == agNULL) 1674285809Sscottl { 1675285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 1676285809Sscottl dmRoot, 1677285809Sscottl onePortContext, 1678285809Sscottl sasIdentify, 1679285809Sscottl agFALSE, 1680285809Sscottl connectionRate, 1681285809Sscottl dmAllShared->itNexusTimeout, 1682285809Sscottl 0, 1683285809Sscottl SAS_DEVICE_TYPE, 1684285809Sscottl oneDeviceData, 1685285809Sscottl oneExpander, 1686285809Sscottl pDiscoverResp->phyIdentifier 1687285809Sscottl ); 1688285809Sscottl } 1689285809Sscottl } 1690285809Sscottl } /* else 22 */ 1691285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 1692285809Sscottl /* If the device is added successfully */ 1693285809Sscottl if ( AttachedDevice != agNULL) 1694285809Sscottl { 1695285809Sscottl if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 1696285809Sscottl || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 1697285809Sscottl || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 1698285809Sscottl || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 1699285809Sscottl { 1700285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n")); 1701285809Sscottl 1702285809Sscottl } 1703285809Sscottl else 1704285809Sscottl { 1705285809Sscottl if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 1706285809Sscottl SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 1707285809Sscottl { 1708285809Sscottl 1709285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n")); 1710285809Sscottl } 1711285809Sscottl else 1712285809Sscottl { 1713285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Other type of device.\n")); 1714285809Sscottl } 1715285809Sscottl } 1716285809Sscottl 1717285809Sscottl /* LP2006-05-26 added upstream device to the newly found device */ 1718285809Sscottl AttachedDevice->dmExpander = oneExpander; 1719285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 1720285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 1721285809Sscottl 1722285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 1723285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 1724285809Sscottl 1725285809Sscottl /* If the phy has table routing attribute */ 1726285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1727285809Sscottl { 1728285809Sscottl /* If the attached device is a fan out expander */ 1729285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1730285809Sscottl { 1731285809Sscottl /* TODO: discovery error, callback */ 1732285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 1733285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1734285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1735285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1736285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1737285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1738285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1739285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1740285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1741285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1742285809Sscottl /* discovery done */ 1743285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1744285809Sscottl } 1745285809Sscottl else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1746285809Sscottl { 1747285809Sscottl /* Allocate an expander data structure */ 1748285809Sscottl AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 1749285809Sscottl 1750285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 1751285809Sscottl /* If allocate successfully */ 1752285809Sscottl if ( AttachedExpander != agNULL) 1753285809Sscottl { 1754285809Sscottl /* set up downstream information on configurable expander */ 1755285809Sscottl dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1756285809Sscottl /* Setup upstream information */ 1757285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1758285809Sscottl AttachedExpander->hasUpStreamDevice = agTRUE; 1759285809Sscottl AttachedExpander->upStreamSASAddressHi 1760285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1761285809Sscottl AttachedExpander->upStreamSASAddressLo 1762285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1763285809Sscottl AttachedExpander->dmUpStreamExpander = oneExpander; 1764285809Sscottl /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 1765285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1766285809Sscottl } 1767285809Sscottl /* If failed to allocate */ 1768285809Sscottl else 1769285809Sscottl { 1770285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 1771285809Sscottl /* discovery done */ 1772285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1773285809Sscottl } 1774285809Sscottl } 1775285809Sscottl } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1776285809Sscottl /* If status is still DISCOVERY_DOWN_STREAM */ 1777285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1778285809Sscottl { 1779285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before\n")); 1780285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1781285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 1782285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1783285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1784285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1785285809Sscottl if (ConfigurableExpander) 1786285809Sscottl { 1787285809Sscottl if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1788285809Sscottl == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1789285809Sscottl (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1790285809Sscottl == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1791285809Sscottl ) 1792285809Sscottl { /* directly attached between oneExpander and ConfigurableExpander */ 1793285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 1\n")); 1794285809Sscottl configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1795285809Sscottl configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1796285809Sscottl } 1797285809Sscottl else 1798285809Sscottl { 1799285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 2\n")); 1800285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1801285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1802285809Sscottl } 1803285809Sscottl } /* if !ConfigurableExpander */ 1804285809Sscottl 1805285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 1806285809Sscottl ConfigurableExpander, 1807285809Sscottl configSASAddressHi, 1808285809Sscottl configSASAddressLo 1809285809Sscottl ); 1810285809Sscottl 1811285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 1812285809Sscottl { 1813285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st q123\n")); 1814285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 1815285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 1816285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 1817285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 1818285809Sscottl dmRoutingEntryAdd(dmRoot, 1819285809Sscottl ConfigurableExpander, 1820285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 1821285809Sscottl configSASAddressHi, 1822285809Sscottl configSASAddressLo 1823285809Sscottl ); 1824285809Sscottl } 1825285809Sscottl } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 1826285809Sscottl } /* AttachedDevice != agNULL */ 1827285809Sscottl /* If fail to add the device */ 1828285809Sscottl else 1829285809Sscottl { 1830285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 1831285809Sscottl /* discovery done */ 1832285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1833285809Sscottl } 1834285809Sscottl } /* else 11 */ 1835285809Sscottl } /* AttachedDevice == agNULL */ 1836285809Sscottl /* If the device has been discovered before */ 1837285809Sscottl else /* haha discovered before 33 */ 1838285809Sscottl { 1839285809Sscottl /* If the phy has subtractive routing attribute */ 1840285809Sscottl if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1841285809Sscottl { 1842285809Sscottl /* If the expander doesn't have up stream device */ 1843285809Sscottl if ( oneExpander->hasUpStreamDevice == agFALSE) 1844285809Sscottl { 1845285809Sscottl /* TODO: discovery error, callback */ 1846285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 1847285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1848285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1849285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1850285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1851285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1852285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1853285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1854285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1855285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1856285809Sscottl /* discovery done */ 1857285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1858285809Sscottl } 1859285809Sscottl /* If the expander has up stream device */ 1860285809Sscottl else /* 44 */ 1861285809Sscottl { 1862285809Sscottl /* If sas address doesn't match */ 1863285809Sscottl if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 1864285809Sscottl || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 1865285809Sscottl { 1866285809Sscottl /* TODO: discovery error, callback */ 1867285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two subtractive phys!!!\n")); 1868285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1869285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1870285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1871285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1872285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1873285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1874285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1875285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1876285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1877285809Sscottl /* discovery done */ 1878285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1879285809Sscottl } 1880285809Sscottl } /* else 44 */ 1881285809Sscottl } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 1882285809Sscottl /* If the phy has table routing attribute */ 1883285809Sscottl else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1884285809Sscottl { 1885285809Sscottl /* If the attached device is a fan out expander */ 1886285809Sscottl if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1887285809Sscottl { 1888285809Sscottl /* (2.3.3.2.1.1) TODO: discovery error, callback */ 1889285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 1890285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1891285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1892285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1893285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1894285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1895285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1896285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1897285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1898285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1899285809Sscottl /* discovery done */ 1900285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1901285809Sscottl } 1902285809Sscottl /* If the attached device is an edge expander */ 1903285809Sscottl else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1904285809Sscottl { 1905285809Sscottl /* Setup up stream inform */ 1906285809Sscottl AttachedExpander = AttachedDevice->dmExpander; 1907285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 1908285809Sscottl /* If the attached expander has up stream device */ 1909285809Sscottl if ( AttachedExpander->hasUpStreamDevice == agTRUE) 1910285809Sscottl { 1911285809Sscottl /* compare the sas address */ 1912285809Sscottl if ( (AttachedExpander->upStreamSASAddressHi 1913285809Sscottl != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1914285809Sscottl || (AttachedExpander->upStreamSASAddressLo 1915285809Sscottl != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 1916285809Sscottl { 1917285809Sscottl /* TODO: discovery error, callback */ 1918285809Sscottl SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander, oneExpander, oneExpander); 1919285809Sscottl if (SAS2SAS11Check == agTRUE) 1920285809Sscottl { 1921285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 1922285809Sscottl } 1923285809Sscottl else 1924285809Sscottl { 1925285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 1926285809Sscottl } 1927285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1928285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1929285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1930285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1931285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1932285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1933285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1934285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1935285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1936285809Sscottl /* discovery done */ 1937285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1938285809Sscottl } 1939285809Sscottl else 1940285809Sscottl { 1941285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 1942285809Sscottl /* set up downstream information on configurable expander */ 1943285809Sscottl 1944285809Sscottl dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1945285809Sscottl /* haha */ 1946285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1947285809Sscottl /* Add the pAttachedExpander to discovering list */ 1948285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1949285809Sscottl } 1950285809Sscottl } /* AttachedExpander->hasUpStreamDevice == agTRUE */ 1951285809Sscottl /* If the attached expander doesn't have up stream device */ 1952285809Sscottl else 1953285809Sscottl { 1954285809Sscottl /* TODO: discovery error, callback */ 1955285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 1956285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1957285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1958285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1959285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1960285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1961285809Sscottl DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1962285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1963285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1964285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1965285809Sscottl /* discovery done */ 1966285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1967285809Sscottl } 1968285809Sscottl } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE */ 1969285809Sscottl } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1970285809Sscottl /* do this regradless of sub or table */ 1971285809Sscottl /* If status is still DISCOVERY_DOWN_STREAM */ 1972285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1973285809Sscottl { 1974285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before\n")); 1975285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1976285809Sscottl 1977285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 1978285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1979285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1980285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1981285809Sscottl if (ConfigurableExpander) 1982285809Sscottl { 1983285809Sscottl if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1984285809Sscottl == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1985285809Sscottl (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1986285809Sscottl == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1987285809Sscottl ) 1988285809Sscottl { /* directly attached between oneExpander and ConfigurableExpander */ 1989285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 1\n")); 1990285809Sscottl configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1991285809Sscottl configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1992285809Sscottl } 1993285809Sscottl else 1994285809Sscottl { 1995285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 2\n")); 1996285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1997285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1998285809Sscottl } 1999285809Sscottl } /* if !ConfigurableExpander */ 2000285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2001285809Sscottl ConfigurableExpander, 2002285809Sscottl configSASAddressHi, 2003285809Sscottl configSASAddressLo 2004285809Sscottl ); 2005285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2006285809Sscottl { 2007285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd q123 \n")); 2008285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2009285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 2010285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2011285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 2012285809Sscottl dmRoutingEntryAdd(dmRoot, 2013285809Sscottl ConfigurableExpander, 2014285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2015285809Sscottl configSASAddressHi, 2016285809Sscottl configSASAddressLo 2017285809Sscottl ); 2018285809Sscottl } 2019285809Sscottl } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 2020285809Sscottl /* incremental discovery */ 2021285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2022285809Sscottl { 2023285809Sscottl connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 2024285809Sscottl 2025285809Sscottl if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2026285809Sscottl { 2027285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SATA_STP\n")); 2028285809Sscottl 2029285809Sscottl dmPortSASDeviceAdd( 2030285809Sscottl dmRoot, 2031285809Sscottl onePortContext, 2032285809Sscottl sasIdentify, 2033285809Sscottl agFALSE, 2034285809Sscottl connectionRate, 2035285809Sscottl dmAllShared->itNexusTimeout, 2036285809Sscottl 0, 2037285809Sscottl STP_DEVICE_TYPE, 2038285809Sscottl oneDeviceData, 2039285809Sscottl oneExpander, 2040285809Sscottl pDiscoverResp->phyIdentifier 2041285809Sscottl ); 2042285809Sscottl } 2043285809Sscottl else 2044285809Sscottl { 2045285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SAS\n")); 2046285809Sscottl 2047285809Sscottl 2048285809Sscottl dmPortSASDeviceAdd( 2049285809Sscottl dmRoot, 2050285809Sscottl onePortContext, 2051285809Sscottl sasIdentify, 2052285809Sscottl agFALSE, 2053285809Sscottl connectionRate, 2054285809Sscottl dmAllShared->itNexusTimeout, 2055285809Sscottl 0, 2056285809Sscottl SAS_DEVICE_TYPE, 2057285809Sscottl oneDeviceData, 2058285809Sscottl oneExpander, 2059285809Sscottl pDiscoverResp->phyIdentifier 2060285809Sscottl ); 2061285809Sscottl 2062285809Sscottl } 2063285809Sscottl } /* onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START */ 2064285809Sscottl } /* else 33 */ 2065285809Sscottl } /* (attachedSasLo != onePortContext->sasLocalAddressLo) */ 2066285809Sscottl 2067285809Sscottl else /* else 44 */ 2068285809Sscottl { 2069285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Self\n")); 2070285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd before\n")); 2071285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2072285809Sscottl 2073285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 2074285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2075285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2076285809Sscottl ConfigurableExpander, 2077285809Sscottl onePortContext->sasLocalAddressHi, 2078285809Sscottl onePortContext->sasLocalAddressLo 2079285809Sscottl ); 2080285809Sscottl 2081285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2082285809Sscottl { 2083285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd q123 Setup routing table\n")); 2084285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2085285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 2086285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2087285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 2088285809Sscottl dmRoutingEntryAdd(dmRoot, 2089285809Sscottl ConfigurableExpander, 2090285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2091285809Sscottl onePortContext->sasLocalAddressHi, 2092285809Sscottl onePortContext->sasLocalAddressLo 2093285809Sscottl ); 2094285809Sscottl } 2095285809Sscottl } /* else 44 */ 2096285809Sscottl } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 2097285809Sscottl /* If no device is attached */ 2098285809Sscottl else 2099285809Sscottl { 2100285809Sscottl 2101285809Sscottl DM_DBG2(("!!!!!!!!!!!!!!!!!!!!! SPIN SATA !!!!!!!!!!!!!!!!!!!!!!!!!!!\n")); 2102285809Sscottl negotiatedPhyLinkRate = DISCRSP_GET_LINKRATE(pDiscoverResp); // added by thenil 2103285809Sscottl 2104285809Sscottl if (negotiatedPhyLinkRate == 0x03) 2105285809Sscottl { 2106285809Sscottl 2107285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: SPIN SATA sent reset\n")); 2108285809Sscottl dmPhyControlSend(dmRoot, 2109285809Sscottl oneDeviceData, 2110285809Sscottl SMP_PHY_CONTROL_HARD_RESET, 2111285809Sscottl pDiscoverResp->phyIdentifier 2112285809Sscottl ); 2113285809Sscottl } 2114285809Sscottl 2115285809Sscottl /* do nothing */ 2116285809Sscottl } 2117285809Sscottl 2118285809Sscottl 2119285809Sscottl /* Increment the discovering phy id */ 2120285809Sscottl oneExpander->discoveringPhyId ++; 2121285809Sscottl 2122285809Sscottl /* If the discovery status is DISCOVERY_DOWN_STREAM */ 2123285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 2124285809Sscottl { 2125285809Sscottl /* If not the last phy */ 2126285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 2127285809Sscottl { 2128285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: More Phys to discover\n")); 2129285809Sscottl /* continue discovery for the next phy */ 2130285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 2131285809Sscottl } 2132285809Sscottl /* If the last phy */ 2133285809Sscottl else 2134285809Sscottl { 2135285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: No More Phys\n")); 2136285809Sscottl 2137285809Sscottl /* for MCN */ 2138285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 2139285809Sscottl /* remove the expander from the discovering list */ 2140285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 2141285809Sscottl /* continue downstream discovering */ 2142285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 2143285809Sscottl } 2144285809Sscottl } 2145285809Sscottl else 2146285809Sscottl { 2147285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 2148285809Sscottl } 2149285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 2150285809Sscottl 2151285809Sscottl return; 2152285809Sscottl} 2153285809Sscottl 2154285809Sscottl 2155285809Sscottl/* works at SAS2 expander (called in dmDownStreamDiscover2ExpanderPhy()) 2156285809Sscottl if currentExpander is SAS2, called in dmDownStreamDiscover2ExpanderPhy() 2157285809Sscottl if currentExpander is SAS1.1, called in dmDownStreamDiscoverExpanderPhy() 2158285809Sscottl*/ 2159285809SscottlosGLOBAL bit32 2160285809SscottldmSAS2SAS11ErrorCheck( 2161285809Sscottl dmRoot_t *dmRoot, 2162285809Sscottl dmIntPortContext_t *onePortContext, 2163285809Sscottl dmExpander_t *topExpander, 2164285809Sscottl dmExpander_t *bottomExpander, 2165285809Sscottl dmExpander_t *currentExpander 2166285809Sscottl ) 2167285809Sscottl{ 2168285809Sscottl bit32 result = agFALSE, i = 0; 2169285809Sscottl bit8 downStreamPhyID, upStreamPhyID; 2170285809Sscottl 2171285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: start\n")); 2172285809Sscottl 2173285809Sscottl if (topExpander == agNULL) 2174285809Sscottl { 2175285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander is NULL\n")); 2176285809Sscottl return result; 2177285809Sscottl } 2178285809Sscottl if (bottomExpander == agNULL) 2179285809Sscottl { 2180285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander is NULL\n")); 2181285809Sscottl return result; 2182285809Sscottl } 2183285809Sscottl 2184285809Sscottl if (currentExpander == agNULL) 2185285809Sscottl { 2186285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander is NULL\n")); 2187285809Sscottl return result; 2188285809Sscottl } 2189285809Sscottl 2190285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander addrHi 0x%08x addrLo 0x%08x\n", 2191285809Sscottl topExpander->dmDevice->SASAddressID.sasAddressHi, topExpander->dmDevice->SASAddressID.sasAddressLo)); 2192285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander addrHi 0x%08x addrLo 0x%08x\n", 2193285809Sscottl bottomExpander->dmDevice->SASAddressID.sasAddressHi, bottomExpander->dmDevice->SASAddressID.sasAddressLo)); 2194285809Sscottl DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander addrHi 0x%08x addrLo 0x%08x\n", 2195285809Sscottl currentExpander->dmDevice->SASAddressID.sasAddressHi, currentExpander->dmDevice->SASAddressID.sasAddressLo)); 2196285809Sscottl 2197285809Sscottl for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2198285809Sscottl { 2199285809Sscottl downStreamPhyID = topExpander->downStreamPhys[i]; 2200285809Sscottl upStreamPhyID = bottomExpander->upStreamPhys[i]; 2201285809Sscottl if (currentExpander->SAS2 == 1) 2202285809Sscottl { 2203285809Sscottl if ( downStreamPhyID == upStreamPhyID && 2204285809Sscottl topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_TABLE && 2205285809Sscottl bottomExpander->routingAttribute[i] == SAS_ROUTING_SUBTRACTIVE && 2206285809Sscottl topExpander->SAS2 == 0 && 2207285809Sscottl bottomExpander->SAS2 == 1 2208285809Sscottl ) 2209285809Sscottl { 2210285809Sscottl result = agTRUE; 2211285809Sscottl break; 2212285809Sscottl } 2213285809Sscottl } 2214285809Sscottl else if (currentExpander->SAS2 == 0) 2215285809Sscottl { 2216285809Sscottl if ( downStreamPhyID == upStreamPhyID && 2217285809Sscottl topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_SUBTRACTIVE && 2218285809Sscottl bottomExpander->routingAttribute[i] == SAS_ROUTING_TABLE && 2219285809Sscottl topExpander->SAS2 == 1 && 2220285809Sscottl bottomExpander->SAS2 == 0 2221285809Sscottl ) 2222285809Sscottl { 2223285809Sscottl result = agTRUE; 2224285809Sscottl break; 2225285809Sscottl } 2226285809Sscottl } 2227285809Sscottl } 2228285809Sscottl return result; 2229285809Sscottl} 2230285809Sscottl 2231285809SscottlosGLOBAL void 2232285809SscottldmDownStreamDiscover2ExpanderPhy( 2233285809Sscottl dmRoot_t *dmRoot, 2234285809Sscottl dmIntPortContext_t *onePortContext, 2235285809Sscottl dmExpander_t *oneExpander, 2236285809Sscottl smpRespDiscover2_t *pDiscoverResp 2237285809Sscottl ) 2238285809Sscottl{ 2239285809Sscottl dmDeviceData_t *oneDeviceData; 2240285809Sscottl dmExpander_t *UpStreamExpander; 2241285809Sscottl dmDeviceData_t *AttachedDevice = agNULL; 2242285809Sscottl dmExpander_t *AttachedExpander; 2243285809Sscottl agsaSASIdentify_t sasIdentify; 2244285809Sscottl bit8 connectionRate; 2245285809Sscottl bit32 attachedSasHi, attachedSasLo; 2246285809Sscottl dmSASSubID_t dmSASSubID; 2247285809Sscottl dmExpander_t *ConfigurableExpander = agNULL; 2248285809Sscottl bit32 dupConfigSASAddr = agFALSE; 2249285809Sscottl bit32 configSASAddressHi; 2250285809Sscottl bit32 configSASAddressLo; 2251285809Sscottl bit32 SAS2SAS11Check = agFALSE; 2252285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 2253285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 2254285809Sscottl 2255285809Sscottl 2256285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: start\n")); 2257285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 2258285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 2259285809Sscottl 2260285809Sscottl DM_ASSERT(dmRoot, "(dmDownStreamDiscover2ExpanderPhy) dmRoot NULL"); 2261285809Sscottl DM_ASSERT(onePortContext, "(dmDownStreamDiscover2ExpanderPhy) pPort NULL"); 2262285809Sscottl DM_ASSERT(oneExpander, "(dmDownStreamDiscover2ExpanderPhy) pExpander NULL"); 2263285809Sscottl DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscover2ExpanderPhy) pDiscoverResp NULL"); 2264285809Sscottl 2265285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->dmDevice)); 2266285809Sscottl 2267285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 2268285809Sscottl { 2269285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 2270285809Sscottl return; 2271285809Sscottl } 2272285809Sscottl 2273285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 2274285809Sscottl { 2275285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: wrong!!!\n")); 2276285809Sscottl } 2277285809Sscottl 2278285809Sscottl 2279285809Sscottl /* (1) Find the device structure of the expander */ 2280285809Sscottl oneDeviceData = oneExpander->dmDevice; 2281285809Sscottl 2282285809Sscottl DM_ASSERT(oneDeviceData, "(dmDownStreamDiscover2ExpanderPhy) pDevice NULL"); 2283285809Sscottl 2284285809Sscottl /* for debugging */ 2285285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 2286285809Sscottl oneExpander->discoveringPhyId, 2287285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, 2288285809Sscottl oneDeviceData->SASAddressID.sasAddressLo)); 2289285809Sscottl 2290285809Sscottl DM_DBG2((" Attached device: %s\n", 2291285809Sscottl ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 2292285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 2293285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 2294285809Sscottl 2295285809Sscottl 2296285809Sscottl /* for debugging */ 2297285809Sscottl if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 2298285809Sscottl { 2299285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 2300285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 2301285809Sscottl dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 2302285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2303285809Sscottl return; 2304285809Sscottl } 2305285809Sscottl 2306285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2307285809Sscottl { 2308285809Sscottl DM_DBG2((" SAS address : %08x-%08x\n", 2309285809Sscottl SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 2310285809Sscottl SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 2311285809Sscottl DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 2312285809Sscottl DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 2313285809Sscottl DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 2314285809Sscottl DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 2315285809Sscottl DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 2316285809Sscottl DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 2317285809Sscottl DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 2318285809Sscottl DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 2319285809Sscottl DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 2320285809Sscottl 2321285809Sscottl } 2322285809Sscottl 2323285809Sscottl /* saving routing attribute for non self-configuring expanders */ 2324285809Sscottl oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 2325285809Sscottl 2326285809Sscottl 2327285809Sscottl oneExpander->discoverSMPAllowed = agTRUE; 2328285809Sscottl 2329285809Sscottl /* If a device is attached */ 2330285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2331285809Sscottl { 2332285809Sscottl /* Setup sasIdentify for the attached device */ 2333285809Sscottl sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 2334285809Sscottl sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 2335285809Sscottl sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 2336285809Sscottl sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 2337285809Sscottl *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 2338285809Sscottl *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 2339285809Sscottl 2340285809Sscottl /* incremental discovery */ 2341285809Sscottl dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 2342285809Sscottl dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 2343285809Sscottl dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 2344285809Sscottl dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 2345285809Sscottl 2346285809Sscottl attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 2347285809Sscottl attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 2348285809Sscottl 2349285809Sscottl /* If it's a direct routing */ 2350285809Sscottl if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 2351285809Sscottl { 2352285809Sscottl /* If the attached device is an expander */ 2353285809Sscottl if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2354285809Sscottl || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 2355285809Sscottl 2356285809Sscottl { 2357285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 2358285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2359285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2360285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2361285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2362285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2363285809Sscottl 2364285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2365285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2366285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2367285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2368285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2369285809Sscottl 2370285809Sscottl return; 2371285809Sscottl } 2372285809Sscottl } 2373285809Sscottl 2374285809Sscottl /* If the expander's attached device is not myself */ 2375285809Sscottl if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 2376285809Sscottl || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 2377285809Sscottl { 2378285809Sscottl /* Find the attached device from discovered list */ 2379285809Sscottl AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 2380285809Sscottl /* If the device has not been discovered before */ 2381285809Sscottl if ( AttachedDevice == agNULL) //11 2382285809Sscottl { 2383285809Sscottl //qqqqqq 2384285809Sscottl if (0) 2385285809Sscottl { 2386285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 2387285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2388285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2389285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2390285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2391285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2392285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2393285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2394285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2395285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2396285809Sscottl /* discovery done */ 2397285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2398285809Sscottl } 2399285809Sscottl else 2400285809Sscottl { 2401285809Sscottl /* Add the device */ 2402285809Sscottl /* read minimum rate from the configuration 2403285809Sscottl onePortContext->LinkRate is SPC's local link rate 2404285809Sscottl */ 2405285809Sscottl connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2406285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 2407285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 2408285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 2409285809Sscottl 2410285809Sscottl if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2411285809Sscottl { 2412285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2413285809Sscottl { 2414285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 2415285809Sscottl dmRoot, 2416285809Sscottl onePortContext, 2417285809Sscottl sasIdentify, 2418285809Sscottl agFALSE, 2419285809Sscottl connectionRate, 2420285809Sscottl dmAllShared->itNexusTimeout, 2421285809Sscottl 0, 2422285809Sscottl STP_DEVICE_TYPE, 2423285809Sscottl oneDeviceData, 2424285809Sscottl oneExpander, 2425285809Sscottl pDiscoverResp->phyIdentifier 2426285809Sscottl ); 2427285809Sscottl } 2428285809Sscottl else 2429285809Sscottl { 2430285809Sscottl /* incremental discovery */ 2431285809Sscottl AttachedDevice = dmFindRegNValid( 2432285809Sscottl dmRoot, 2433285809Sscottl onePortContext, 2434285809Sscottl &dmSASSubID 2435285809Sscottl ); 2436285809Sscottl /* not registered and not valid; add this*/ 2437285809Sscottl if (AttachedDevice == agNULL) 2438285809Sscottl { 2439285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 2440285809Sscottl dmRoot, 2441285809Sscottl onePortContext, 2442285809Sscottl sasIdentify, 2443285809Sscottl agFALSE, 2444285809Sscottl connectionRate, 2445285809Sscottl dmAllShared->itNexusTimeout, 2446285809Sscottl 0, 2447285809Sscottl STP_DEVICE_TYPE, 2448285809Sscottl oneDeviceData, 2449285809Sscottl oneExpander, 2450285809Sscottl pDiscoverResp->phyIdentifier 2451285809Sscottl ); 2452285809Sscottl } 2453285809Sscottl } 2454285809Sscottl } 2455285809Sscottl else 2456285809Sscottl { 2457285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2458285809Sscottl { 2459285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 2460285809Sscottl dmRoot, 2461285809Sscottl onePortContext, 2462285809Sscottl sasIdentify, 2463285809Sscottl agFALSE, 2464285809Sscottl connectionRate, 2465285809Sscottl dmAllShared->itNexusTimeout, 2466285809Sscottl 0, 2467285809Sscottl SAS_DEVICE_TYPE, 2468285809Sscottl oneDeviceData, 2469285809Sscottl oneExpander, 2470285809Sscottl pDiscoverResp->phyIdentifier 2471285809Sscottl ); 2472285809Sscottl } 2473285809Sscottl else 2474285809Sscottl { 2475285809Sscottl /* incremental discovery */ 2476285809Sscottl AttachedDevice = dmFindRegNValid( 2477285809Sscottl dmRoot, 2478285809Sscottl onePortContext, 2479285809Sscottl &dmSASSubID 2480285809Sscottl ); 2481285809Sscottl /* not registered and not valid; add this*/ 2482285809Sscottl if (AttachedDevice == agNULL) 2483285809Sscottl { 2484285809Sscottl AttachedDevice = dmPortSASDeviceAdd( 2485285809Sscottl dmRoot, 2486285809Sscottl onePortContext, 2487285809Sscottl sasIdentify, 2488285809Sscottl agFALSE, 2489285809Sscottl connectionRate, 2490285809Sscottl dmAllShared->itNexusTimeout, 2491285809Sscottl 0, 2492285809Sscottl SAS_DEVICE_TYPE, 2493285809Sscottl oneDeviceData, 2494285809Sscottl oneExpander, 2495285809Sscottl pDiscoverResp->phyIdentifier 2496285809Sscottl ); 2497285809Sscottl } 2498285809Sscottl } 2499285809Sscottl } 2500285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 2501285809Sscottl /* If the device is added successfully */ 2502285809Sscottl if ( AttachedDevice != agNULL) 2503285809Sscottl { 2504285809Sscottl if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 2505285809Sscottl || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 2506285809Sscottl || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 2507285809Sscottl || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 2508285809Sscottl { 2509285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Report a new SAS device !!\n")); 2510285809Sscottl 2511285809Sscottl } 2512285809Sscottl else 2513285809Sscottl { 2514285809Sscottl if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 2515285809Sscottl SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 2516285809Sscottl { 2517285809Sscottl 2518285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found an STP or SATA device.\n")); 2519285809Sscottl } 2520285809Sscottl else 2521285809Sscottl { 2522285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Other type of device.\n")); 2523285809Sscottl } 2524285809Sscottl } 2525285809Sscottl 2526285809Sscottl /* LP2006-05-26 added upstream device to the newly found device */ 2527285809Sscottl AttachedDevice->dmExpander = oneExpander; 2528285809Sscottl DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 2529285809Sscottl DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 2530285809Sscottl 2531285809Sscottl DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 2532285809Sscottl DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 2533285809Sscottl 2534285809Sscottl /* If the phy has table routing attribute */ 2535285809Sscottl if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2536285809Sscottl { 2537285809Sscottl /* If the attached device is a fan out expander */ 2538285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2539285809Sscottl { 2540285809Sscottl /* TODO: discovery error, callback */ 2541285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 2542285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2543285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2544285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2545285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2546285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2547285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2548285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2549285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2550285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2551285809Sscottl /* discovery done */ 2552285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2553285809Sscottl } 2554285809Sscottl else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2555285809Sscottl { 2556285809Sscottl /* Allocate an expander data structure */ 2557285809Sscottl AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2558285809Sscottl 2559285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 2560285809Sscottl /* If allocate successfully */ 2561285809Sscottl if ( AttachedExpander != agNULL) 2562285809Sscottl { 2563285809Sscottl /* set up downstream information on configurable expander */ 2564285809Sscottl 2565285809Sscottl dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2566285809Sscottl 2567285809Sscottl /* Setup upstream information */ 2568285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2569285809Sscottl//qqqqq 2570285809Sscottl AttachedExpander->hasUpStreamDevice = agTRUE; 2571285809Sscottl AttachedExpander->upStreamSASAddressHi 2572285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2573285809Sscottl AttachedExpander->upStreamSASAddressLo 2574285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2575285809Sscottl AttachedExpander->dmUpStreamExpander = oneExpander; 2576285809Sscottl /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2577285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2578285809Sscottl } 2579285809Sscottl /* If failed to allocate */ 2580285809Sscottl else 2581285809Sscottl { 2582285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 2583285809Sscottl /* discovery done */ 2584285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2585285809Sscottl } 2586285809Sscottl } 2587285809Sscottl } 2588285809Sscottl //qqqqq 2589285809Sscottl else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 2590285809Sscottl (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE || 2591285809Sscottl SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2592285809Sscottl ) 2593285809Sscottl { 2594285809Sscottl /* Allocate an expander data structure */ 2595285809Sscottl AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2596285809Sscottl 2597285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE/FANOUT exp device.%p\n", AttachedExpander)); 2598285809Sscottl /* If allocate successfully */ 2599285809Sscottl if ( AttachedExpander != agNULL) 2600285809Sscottl { 2601285809Sscottl /* set up downstream information on configurable expander */ 2602285809Sscottl dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2603285809Sscottl 2604285809Sscottl /* Setup upstream information */ 2605285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2606285809Sscottl AttachedExpander->hasUpStreamDevice = agTRUE; 2607285809Sscottl AttachedExpander->upStreamSASAddressHi 2608285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2609285809Sscottl AttachedExpander->upStreamSASAddressLo 2610285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2611285809Sscottl AttachedExpander->dmUpStreamExpander = oneExpander; 2612285809Sscottl /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2613285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2614285809Sscottl } 2615285809Sscottl /* If failed to allocate */ 2616285809Sscottl else 2617285809Sscottl { 2618285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure (2)!!!\n")); 2619285809Sscottl /* discovery done */ 2620285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2621285809Sscottl } 2622285809Sscottl 2623285809Sscottl 2624285809Sscottl } 2625285809Sscottl /* If status is still DISCOVERY_DOWN_STREAM */ 2626285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2627285809Sscottl onePortContext->discovery.ConfiguresOthers == agFALSE) 2628285809Sscottl { 2629285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before\n")); 2630285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2631285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 2632285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2633285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2634285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2635285809Sscottl if (ConfigurableExpander) 2636285809Sscottl { 2637285809Sscottl if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2638285809Sscottl == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2639285809Sscottl (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2640285809Sscottl == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2641285809Sscottl ) 2642285809Sscottl { /* directly attached between oneExpander and ConfigurableExpander */ 2643285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 1\n")); 2644285809Sscottl configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2645285809Sscottl configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2646285809Sscottl } 2647285809Sscottl else 2648285809Sscottl { 2649285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 2\n")); 2650285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2651285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2652285809Sscottl } 2653285809Sscottl } /* if !ConfigurableExpander */ 2654285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2655285809Sscottl ConfigurableExpander, 2656285809Sscottl configSASAddressHi, 2657285809Sscottl configSASAddressLo 2658285809Sscottl ); 2659285809Sscottl 2660285809Sscottl 2661285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2662285809Sscottl { 2663285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st q123\n")); 2664285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2665285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 2666285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2667285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 2668285809Sscottl dmRoutingEntryAdd(dmRoot, 2669285809Sscottl ConfigurableExpander, 2670285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2671285809Sscottl configSASAddressHi, 2672285809Sscottl configSASAddressLo 2673285809Sscottl ); 2674285809Sscottl } 2675285809Sscottl } 2676285809Sscottl } 2677285809Sscottl /* If fail to add the device */ 2678285809Sscottl else 2679285809Sscottl { 2680285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 2681285809Sscottl /* discovery done */ 2682285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2683285809Sscottl } 2684285809Sscottl } 2685285809Sscottl } 2686285809Sscottl /* If the device has been discovered before */ 2687285809Sscottl else /* discovered before */ 2688285809Sscottl { 2689285809Sscottl /* If the phy has subtractive routing attribute */ 2690285809Sscottl if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 2691285809Sscottl { 2692285809Sscottl /* If the expander doesn't have up stream device */ 2693285809Sscottl if ( oneExpander->hasUpStreamDevice == agFALSE) 2694285809Sscottl { 2695285809Sscottl /* TODO: discovery error, callback */ 2696285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 2697285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2698285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2699285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2700285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2701285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2702285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2703285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2704285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2705285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2706285809Sscottl /* discovery done */ 2707285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2708285809Sscottl } 2709285809Sscottl /* If the expander has up stream device */ 2710285809Sscottl else 2711285809Sscottl { 2712285809Sscottl 2713285809Sscottl//qqqqq 2714285809Sscottl /* If sas address doesn't match */ 2715285809Sscottl if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 2716285809Sscottl || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 2717285809Sscottl { 2718285809Sscottl /* TODO: discovery error, callback */ 2719285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** two subtractive phys!!! Allowed in SAS2!!!\n")); 2720285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2721285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2722285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2723285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2724285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2725285809Sscottl onePortContext->discovery.DeferredError = agTRUE; 2726285809Sscottl 2727285809Sscottl } 2728285809Sscottl } 2729285809Sscottl } 2730285809Sscottl /* If the phy has table routing attribute */ 2731285809Sscottl else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2732285809Sscottl { 2733285809Sscottl /* If the attached device is a fan out expander */ 2734285809Sscottl if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2735285809Sscottl { 2736285809Sscottl /* (2.3.3.2.1.1) TODO: discovery error, callback */ 2737285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 2738285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2739285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2740285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2741285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2742285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2743285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2744285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2745285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2746285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2747285809Sscottl /* discovery done */ 2748285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2749285809Sscottl } 2750285809Sscottl /* If the attached device is an edge expander */ 2751285809Sscottl else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2752285809Sscottl { 2753285809Sscottl /* Setup up stream inform */ 2754285809Sscottl AttachedExpander = AttachedDevice->dmExpander; 2755285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 2756285809Sscottl //hhhhhh 2757285809Sscottl /* If the attached expander has up stream device */ 2758285809Sscottl if ( AttachedExpander->hasUpStreamDevice == agTRUE) 2759285809Sscottl { 2760285809Sscottl /* compare the sas address */ 2761285809Sscottl if ( (AttachedExpander->upStreamSASAddressHi 2762285809Sscottl != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 2763285809Sscottl || (AttachedExpander->upStreamSASAddressLo 2764285809Sscottl != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 2765285809Sscottl { 2766285809Sscottl if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2767285809Sscottl { 2768285809Sscottl /* 2769285809Sscottl needs further error checking 2770285809Sscottl UpstreamExpanderOfAttachedExpander = AttachedExpander->UpStreamExpander 2771285809Sscottl for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2772285809Sscottl { 2773285809Sscottl if (UpstreamExpanderOfAttachedExpander->downStreamPhys[i] != 0 && 2774285809Sscottl } 2775285809Sscottl */ 2776285809Sscottl SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander->dmUpStreamExpander, AttachedExpander, oneExpander); 2777285809Sscottl if (SAS2SAS11Check == agTRUE) 2778285809Sscottl { 2779285809Sscottl 2780285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 2781285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2782285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2783285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2784285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2785285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2786285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2787285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2788285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2789285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2790285809Sscottl /* discovery done */ 2791285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2792285809Sscottl } 2793285809Sscottl else 2794285809Sscottl { 2795285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (1)\n")); 2796285809Sscottl /* move on to the next phys but should be not proceed after oneExpander */ 2797285809Sscottl oneExpander->UndoDueToTTTSupported = agTRUE; 2798285809Sscottl onePortContext->discovery.DeferredError = agFALSE; 2799285809Sscottl } 2800285809Sscottl } 2801285809Sscottl else 2802285809Sscottl { 2803285809Sscottl /* TODO: discovery error, callback */ 2804285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 2805285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2806285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2807285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2808285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2809285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2810285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2811285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2812285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2813285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2814285809Sscottl /* discovery done */ 2815285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2816285809Sscottl } 2817285809Sscottl } 2818285809Sscottl else 2819285809Sscottl { 2820285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 2821285809Sscottl /* set up downstream information on configurable expander */ 2822285809Sscottl 2823285809Sscottl dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2824285809Sscottl /* haha */ 2825285809Sscottl dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2826285809Sscottl /* Add the pAttachedExpander to discovering list */ 2827285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2828285809Sscottl } 2829285809Sscottl } 2830285809Sscottl /* If the attached expander doesn't have up stream device */ 2831285809Sscottl else 2832285809Sscottl { 2833285809Sscottl if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2834285809Sscottl { 2835285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (2)\n")); 2836285809Sscottl /* move on to the next phys but should be not proceed after oneExpander */ 2837285809Sscottl oneExpander->UndoDueToTTTSupported = agTRUE; 2838285809Sscottl onePortContext->discovery.DeferredError = agFALSE; 2839285809Sscottl } 2840285809Sscottl else 2841285809Sscottl { 2842285809Sscottl /* TODO: discovery error, callback */ 2843285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 2844285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2845285809Sscottl = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2846285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2847285809Sscottl = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2848285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2849285809Sscottl DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2850285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2851285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2852285809Sscottl onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2853285809Sscottl /* discovery done */ 2854285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2855285809Sscottl } 2856285809Sscottl } 2857285809Sscottl } 2858285809Sscottl } /* for else if (SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) */ 2859285809Sscottl 2860285809Sscottl /* do this regradless of sub or table */ 2861285809Sscottl /* If status is still DISCOVERY_DOWN_STREAM */ 2862285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2863285809Sscottl onePortContext->discovery.ConfiguresOthers == agFALSE) 2864285809Sscottl { 2865285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before\n")); 2866285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2867285809Sscottl 2868285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 2869285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2870285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2871285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2872285809Sscottl if (ConfigurableExpander) 2873285809Sscottl { 2874285809Sscottl if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2875285809Sscottl == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2876285809Sscottl (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2877285809Sscottl == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2878285809Sscottl ) 2879285809Sscottl { /* directly attached between oneExpander and ConfigurableExpander */ 2880285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 1\n")); 2881285809Sscottl configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2882285809Sscottl configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2883285809Sscottl } 2884285809Sscottl else 2885285809Sscottl { 2886285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 2\n")); 2887285809Sscottl configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2888285809Sscottl configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2889285809Sscottl } 2890285809Sscottl } /* if !ConfigurableExpander */ 2891285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2892285809Sscottl ConfigurableExpander, 2893285809Sscottl configSASAddressHi, 2894285809Sscottl configSASAddressLo 2895285809Sscottl ); 2896285809Sscottl 2897285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2898285809Sscottl { 2899285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd q123 \n")); 2900285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2901285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 2902285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2903285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 2904285809Sscottl dmRoutingEntryAdd(dmRoot, 2905285809Sscottl ConfigurableExpander, 2906285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2907285809Sscottl configSASAddressHi, 2908285809Sscottl configSASAddressLo 2909285809Sscottl ); 2910285809Sscottl } 2911285809Sscottl } /* if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) */ 2912285809Sscottl /* incremental discovery */ 2913285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2914285809Sscottl { 2915285809Sscottl connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2916285809Sscottl 2917285809Sscottl if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2918285809Sscottl { 2919285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SATA_STP\n")); 2920285809Sscottl 2921285809Sscottl dmPortSASDeviceAdd( 2922285809Sscottl dmRoot, 2923285809Sscottl onePortContext, 2924285809Sscottl sasIdentify, 2925285809Sscottl agFALSE, 2926285809Sscottl connectionRate, 2927285809Sscottl dmAllShared->itNexusTimeout, 2928285809Sscottl 0, 2929285809Sscottl STP_DEVICE_TYPE, 2930285809Sscottl oneDeviceData, 2931285809Sscottl oneExpander, 2932285809Sscottl pDiscoverResp->phyIdentifier 2933285809Sscottl ); 2934285809Sscottl } 2935285809Sscottl else 2936285809Sscottl { 2937285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SAS\n")); 2938285809Sscottl 2939285809Sscottl dmPortSASDeviceAdd( 2940285809Sscottl dmRoot, 2941285809Sscottl onePortContext, 2942285809Sscottl sasIdentify, 2943285809Sscottl agFALSE, 2944285809Sscottl connectionRate, 2945285809Sscottl dmAllShared->itNexusTimeout, 2946285809Sscottl 0, 2947285809Sscottl SAS_DEVICE_TYPE, 2948285809Sscottl oneDeviceData, 2949285809Sscottl oneExpander, 2950285809Sscottl pDiscoverResp->phyIdentifier 2951285809Sscottl ); 2952285809Sscottl 2953285809Sscottl } 2954285809Sscottl } 2955285809Sscottl 2956285809Sscottl 2957285809Sscottl }/* else; existing devce */ 2958285809Sscottl } /* not attached to myself */ 2959285809Sscottl /* If the attached device is myself */ 2960285809Sscottl else 2961285809Sscottl { 2962285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Self\n")); 2963285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd before\n")); 2964285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2965285809Sscottl 2966285809Sscottl if (onePortContext->discovery.ConfiguresOthers == agFALSE) 2967285809Sscottl { 2968285809Sscottl UpStreamExpander = oneExpander->dmUpStreamExpander; 2969285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2970285809Sscottl dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2971285809Sscottl ConfigurableExpander, 2972285809Sscottl onePortContext->sasLocalAddressHi, 2973285809Sscottl onePortContext->sasLocalAddressLo 2974285809Sscottl ); 2975285809Sscottl 2976285809Sscottl if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2977285809Sscottl { 2978285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd q123 Setup routing table\n")); 2979285809Sscottl UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2980285809Sscottl ConfigurableExpander->currentDownStreamPhyIndex = 2981285809Sscottl dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2982285809Sscottl ConfigurableExpander->dmReturnginExpander = oneExpander; 2983285809Sscottl dmRoutingEntryAdd(dmRoot, 2984285809Sscottl ConfigurableExpander, 2985285809Sscottl ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2986285809Sscottl onePortContext->sasLocalAddressHi, 2987285809Sscottl onePortContext->sasLocalAddressLo 2988285809Sscottl ); 2989285809Sscottl } 2990285809Sscottl } 2991285809Sscottl } 2992285809Sscottl } 2993285809Sscottl /* If no device is attached */ 2994285809Sscottl else 2995285809Sscottl { 2996285809Sscottl } 2997285809Sscottl 2998285809Sscottl 2999285809Sscottl /* Increment the discovering phy id */ 3000285809Sscottl oneExpander->discoveringPhyId ++; 3001285809Sscottl 3002285809Sscottl /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3003285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3004285809Sscottl { 3005285809Sscottl /* If not the last phy */ 3006285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3007285809Sscottl { 3008285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: More Phys to discover\n")); 3009285809Sscottl /* continue discovery for the next phy */ 3010285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 3011285809Sscottl } 3012285809Sscottl /* If the last phy */ 3013285809Sscottl else 3014285809Sscottl { 3015285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: No More Phys\n")); 3016285809Sscottl 3017285809Sscottl /* for MCN */ 3018285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3019285809Sscottl ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 3020285809Sscottl if (oneExpander->UndoDueToTTTSupported == agTRUE && ConfigurableExpander != agNULL) 3021285809Sscottl// if (oneExpander->UndoDueToTTTSupported == agTRUE) 3022285809Sscottl { 3023285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Not sure!!!\n")); 3024285809Sscottl dmDiscoveringUndoAdd(dmRoot, onePortContext, oneExpander); 3025285809Sscottl oneExpander->UndoDueToTTTSupported = agFALSE; 3026285809Sscottl } 3027285809Sscottl 3028285809Sscottl /* remove the expander from the discovering list */ 3029285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3030285809Sscottl /* continue downstream discovering */ 3031285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3032285809Sscottl } 3033285809Sscottl } 3034285809Sscottl else 3035285809Sscottl { 3036285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3037285809Sscottl } 3038285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3039285809Sscottl 3040285809Sscottl return; 3041285809Sscottl} 3042285809Sscottl 3043285809Sscottl 3044285809SscottlosGLOBAL void 3045285809SscottldmDiscoveringUndoAdd( 3046285809Sscottl dmRoot_t *dmRoot, 3047285809Sscottl dmIntPortContext_t *onePortContext, 3048285809Sscottl dmExpander_t *oneExpander 3049285809Sscottl ) 3050285809Sscottl{ 3051285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3052285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3053285809Sscottl dmList_t *ExpanderList; 3054285809Sscottl dmExpander_t *tempExpander; 3055285809Sscottl dmIntPortContext_t *tmpOnePortContext = onePortContext; 3056285809Sscottl 3057285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: start\n")); 3058285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3059285809Sscottl { 3060285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: empty discoveringExpanderList\n")); 3061285809Sscottl return; 3062285809Sscottl } 3063285809Sscottl 3064285809Sscottl// DM_DBG2(("dmDiscoveringUndoAdd: before\n")); 3065285809Sscottl// dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3066285809Sscottl 3067285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3068285809Sscottl while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 3069285809Sscottl { 3070285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3071285809Sscottl if ( tempExpander == agNULL) 3072285809Sscottl { 3073285809Sscottl DM_DBG1(("dmDiscoveringUndoAdd: tempExpander is NULL!!!\n")); 3074285809Sscottl return; 3075285809Sscottl } 3076285809Sscottl if (tempExpander->dmUpStreamExpander == oneExpander) 3077285809Sscottl { 3078285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: match!!! expander id %d\n", tempExpander->id)); 3079285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 3080285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 3081285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 3082285809Sscottl DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 3083285809Sscottl// DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 3084285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 3085285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 3086285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3087285809Sscottl } 3088285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3089285809Sscottl { 3090285809Sscottl DM_DBG2(("dmDiscoveringUndoAdd: hitting break\n")); 3091285809Sscottl break; 3092285809Sscottl } 3093285809Sscottl ExpanderList = ExpanderList->flink; 3094285809Sscottl } 3095285809Sscottl 3096285809Sscottl// DM_DBG2(("dmDiscoveringUndoAdd: after\n")); 3097285809Sscottl// dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3098285809Sscottl return; 3099285809Sscottl} 3100285809Sscottl 3101285809SscottlosGLOBAL void 3102285809SscottldmHandleZoneViolation( 3103285809Sscottl dmRoot_t *dmRoot, 3104285809Sscottl agsaRoot_t *agRoot, 3105285809Sscottl agsaIORequest_t *agIORequest, 3106285809Sscottl dmDeviceData_t *oneDeviceData, 3107285809Sscottl dmSMPFrameHeader_t *frameHeader, 3108285809Sscottl agsaFrameHandle_t frameHandle 3109285809Sscottl ) 3110285809Sscottl{ 3111285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 3112285809Sscottl dmExpander_t *oneExpander = agNULL; 3113285809Sscottl 3114285809Sscottl DM_DBG1(("dmHandleZoneViolation: start\n")); 3115285809Sscottl DM_DBG1(("dmHandleZoneViolation: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3116285809Sscottl DM_DBG1(("dmHandleZoneViolation: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3117285809Sscottl onePortContext = oneDeviceData->dmPortContext; 3118285809Sscottl oneExpander = oneDeviceData->dmExpander; 3119285809Sscottl if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 3120285809Sscottl { 3121285809Sscottl DM_DBG1(("dmHandleZoneViolation: invalid port or aborted discovery!!!\n")); 3122285809Sscottl return; 3123285809Sscottl } 3124285809Sscottl /* for MCN */ 3125285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3126285809Sscottl /* remove the expander from the discovering list */ 3127285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3128285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3129285809Sscottl { 3130285809Sscottl /* continue upstream discovering */ 3131285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3132285809Sscottl } 3133285809Sscottl else /* DISCOVERY_DOWN_STREAM or DISCOVERY_CONFIG_ROUTING */ 3134285809Sscottl { 3135285809Sscottl /* continue downstream discovering */ 3136285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3137285809Sscottl } 3138285809Sscottl return; 3139285809Sscottl} 3140285809Sscottl 3141285809Sscottl 3142285809SscottlosGLOBAL void 3143285809SscottldmUpStreamDiscoverExpanderPhySkip( 3144285809Sscottl dmRoot_t *dmRoot, 3145285809Sscottl dmIntPortContext_t *onePortContext, 3146285809Sscottl dmExpander_t *oneExpander 3147285809Sscottl ) 3148285809Sscottl 3149285809Sscottl{ 3150285809Sscottl dmDeviceData_t *oneDeviceData; 3151285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: start\n")); 3152285809Sscottl 3153285809Sscottl oneDeviceData = oneExpander->dmDevice; 3154285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3155285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3156285809Sscottl 3157285809Sscottl oneExpander->discoveringPhyId++; 3158285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3159285809Sscottl { 3160285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3161285809Sscottl { 3162285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3163285809Sscottl /* continue discovery for the next phy */ 3164285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 3165285809Sscottl } 3166285809Sscottl else 3167285809Sscottl { 3168285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: No More Phys\n")); 3169285809Sscottl 3170285809Sscottl /* for MCN */ 3171285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3172285809Sscottl /* remove the expander from the discovering list */ 3173285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3174285809Sscottl /* continue upstream discovering */ 3175285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3176285809Sscottl } 3177285809Sscottl } 3178285809Sscottl else 3179285809Sscottl { 3180285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3181285809Sscottl 3182285809Sscottl } 3183285809Sscottl 3184285809Sscottl DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3185285809Sscottl 3186285809Sscottl return; 3187285809Sscottl} 3188285809Sscottl 3189285809Sscottl 3190285809SscottlosGLOBAL void 3191285809SscottldmUpStreamDiscover2ExpanderPhySkip( 3192285809Sscottl dmRoot_t *dmRoot, 3193285809Sscottl dmIntPortContext_t *onePortContext, 3194285809Sscottl dmExpander_t *oneExpander 3195285809Sscottl ) 3196285809Sscottl{ 3197285809Sscottl dmDeviceData_t *oneDeviceData; 3198285809Sscottl 3199285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: start\n")); 3200285809Sscottl oneDeviceData = oneExpander->dmDevice; 3201285809Sscottl 3202285809Sscottl oneExpander->discoveringPhyId++; 3203285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3204285809Sscottl { 3205285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3206285809Sscottl { 3207285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM find more ...\n")); 3208285809Sscottl /* continue discovery for the next phy */ 3209285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 3210285809Sscottl } 3211285809Sscottl else 3212285809Sscottl { 3213285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 3214285809Sscottl 3215285809Sscottl /* for MCN */ 3216285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3217285809Sscottl /* remove the expander from the discovering list */ 3218285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3219285809Sscottl /* continue upstream discovering */ 3220285809Sscottl dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3221285809Sscottl } 3222285809Sscottl } 3223285809Sscottl else 3224285809Sscottl { 3225285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3226285809Sscottl } 3227285809Sscottl 3228285809Sscottl DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3229285809Sscottl 3230285809Sscottl 3231285809Sscottl return; 3232285809Sscottl} 3233285809Sscottl 3234285809SscottlosGLOBAL void 3235285809SscottldmDownStreamDiscoverExpanderPhySkip( 3236285809Sscottl dmRoot_t *dmRoot, 3237285809Sscottl dmIntPortContext_t *onePortContext, 3238285809Sscottl dmExpander_t *oneExpander 3239285809Sscottl ) 3240285809Sscottl{ 3241285809Sscottl dmDeviceData_t *oneDeviceData; 3242285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: start\n")); 3243285809Sscottl 3244285809Sscottl oneDeviceData = oneExpander->dmDevice; 3245285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3246285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3247285809Sscottl 3248285809Sscottl /* Increment the discovering phy id */ 3249285809Sscottl oneExpander->discoveringPhyId ++; 3250285809Sscottl 3251285809Sscottl /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3252285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3253285809Sscottl { 3254285809Sscottl /* If not the last phy */ 3255285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3256285809Sscottl { 3257285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3258285809Sscottl /* continue discovery for the next phy */ 3259285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 3260285809Sscottl } 3261285809Sscottl /* If the last phy */ 3262285809Sscottl else 3263285809Sscottl { 3264285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: No More Phys\n")); 3265285809Sscottl 3266285809Sscottl /* for MCN */ 3267285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3268285809Sscottl /* remove the expander from the discovering list */ 3269285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3270285809Sscottl /* continue downstream discovering */ 3271285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3272285809Sscottl } 3273285809Sscottl } 3274285809Sscottl else 3275285809Sscottl { 3276285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3277285809Sscottl } 3278285809Sscottl DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3279285809Sscottl 3280285809Sscottl 3281285809Sscottl return; 3282285809Sscottl} 3283285809Sscottl 3284285809SscottlosGLOBAL void 3285285809SscottldmDownStreamDiscover2ExpanderPhySkip( 3286285809Sscottl dmRoot_t *dmRoot, 3287285809Sscottl dmIntPortContext_t *onePortContext, 3288285809Sscottl dmExpander_t *oneExpander 3289285809Sscottl ) 3290285809Sscottl{ 3291285809Sscottl dmDeviceData_t *oneDeviceData; 3292285809Sscottl 3293285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: start\n")); 3294285809Sscottl 3295285809Sscottl oneDeviceData = oneExpander->dmDevice; 3296285809Sscottl /* Increment the discovering phy id */ 3297285809Sscottl oneExpander->discoveringPhyId ++; 3298285809Sscottl 3299285809Sscottl /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3300285809Sscottl if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3301285809Sscottl { 3302285809Sscottl /* If not the last phy */ 3303285809Sscottl if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3304285809Sscottl { 3305285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: More Phys to discover\n")); 3306285809Sscottl /* continue discovery for the next phy */ 3307285809Sscottl dmDiscoverSend(dmRoot, oneDeviceData); 3308285809Sscottl } 3309285809Sscottl /* If the last phy */ 3310285809Sscottl else 3311285809Sscottl { 3312285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: No More Phys\n")); 3313285809Sscottl 3314285809Sscottl /* for MCN */ 3315285809Sscottl dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3316285809Sscottl /* remove the expander from the discovering list */ 3317285809Sscottl dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3318285809Sscottl /* continue downstream discovering */ 3319285809Sscottl dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3320285809Sscottl } 3321285809Sscottl } 3322285809Sscottl else 3323285809Sscottl { 3324285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3325285809Sscottl } 3326285809Sscottl DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3327285809Sscottl return; 3328285809Sscottl} 3329285809Sscottl 3330285809SscottlosGLOBAL void 3331285809SscottldmExpanderUpStreamPhyAdd( 3332285809Sscottl dmRoot_t *dmRoot, 3333285809Sscottl dmExpander_t *oneExpander, 3334285809Sscottl bit8 phyId 3335285809Sscottl ) 3336285809Sscottl{ 3337285809Sscottl bit32 i; 3338285809Sscottl bit32 hasSet = agFALSE; 3339285809Sscottl 3340285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: start, phyid %d\n", phyId)); 3341285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3342285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3343285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3344285809Sscottl 3345285809Sscottl for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3346285809Sscottl { 3347285809Sscottl if ( oneExpander->upStreamPhys[i] == phyId ) 3348285809Sscottl { 3349285809Sscottl hasSet = agTRUE; 3350285809Sscottl break; 3351285809Sscottl } 3352285809Sscottl } 3353285809Sscottl 3354285809Sscottl if ( hasSet == agFALSE ) 3355285809Sscottl { 3356285809Sscottl oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId; 3357285809Sscottl } 3358285809Sscottl 3359285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3360285809Sscottl 3361285809Sscottl /* for debugging */ 3362285809Sscottl for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3363285809Sscottl { 3364285809Sscottl DM_DBG3(("dmExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i])); 3365285809Sscottl } 3366285809Sscottl return; 3367285809Sscottl} 3368285809Sscottl 3369285809SscottlosGLOBAL void 3370285809SscottldmExpanderDownStreamPhyAdd( 3371285809Sscottl dmRoot_t *dmRoot, 3372285809Sscottl dmExpander_t *oneExpander, 3373285809Sscottl bit8 phyId 3374285809Sscottl ) 3375285809Sscottl{ 3376285809Sscottl bit32 i; 3377285809Sscottl bit32 hasSet = agFALSE; 3378285809Sscottl 3379285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: start, phyid %d\n", phyId)); 3380285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3381285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3382285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3383285809Sscottl 3384285809Sscottl for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3385285809Sscottl { 3386285809Sscottl if ( oneExpander->downStreamPhys[i] == phyId ) 3387285809Sscottl { 3388285809Sscottl hasSet = agTRUE; 3389285809Sscottl break; 3390285809Sscottl } 3391285809Sscottl } 3392285809Sscottl 3393285809Sscottl if ( hasSet == agFALSE ) 3394285809Sscottl { 3395285809Sscottl oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId; 3396285809Sscottl } 3397285809Sscottl 3398285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3399285809Sscottl 3400285809Sscottl /* for debugging */ 3401285809Sscottl for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3402285809Sscottl { 3403285809Sscottl DM_DBG3(("dmExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i])); 3404285809Sscottl } 3405285809Sscottl return; 3406285809Sscottl} 3407285809Sscottl 3408285809SscottlosGLOBAL void 3409285809SscottldmDiscoveryReportMCN( 3410285809Sscottl dmRoot_t *dmRoot, 3411285809Sscottl dmIntPortContext_t *onePortContext 3412285809Sscottl ) 3413285809Sscottl{ 3414285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3415285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3416285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3417285809Sscottl dmList_t *DeviceListList; 3418285809Sscottl bit16 extension = 0; 3419285809Sscottl dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3420285809Sscottl 3421285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: start\n")); 3422285809Sscottl 3423285809Sscottl/* 3424285809Sscottl if full disocvery, report all devices using MCN 3425285809Sscottl if incremental discovery, 3426285809Sscottl 1. compare MCN and PrevMCN 3427285809Sscottl 2. report the changed ones; report MCN 3428285809Sscottl 3. set PrevMCN to MCN 3429285809Sscottl PrevMCN = MCN 3430285809Sscottl*/ 3431285809Sscottl 3432285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3433285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3434285809Sscottl { 3435285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3436285809Sscottl if ( oneDeviceData == agNULL) 3437285809Sscottl { 3438285809Sscottl DM_DBG1(("dmDiscoveryReportMCN: oneDeviceData is NULL!!!\n")); 3439285809Sscottl return; 3440285809Sscottl } 3441285809Sscottl DM_DBG3(("dmDiscoveryReportMCN: loop did %d\n", oneDeviceData->id)); 3442285809Sscottl if (oneDeviceData->dmPortContext == onePortContext) 3443285809Sscottl { 3444285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3445285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3446285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3447285809Sscottl 3448285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3449285809Sscottl { 3450285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: FULL_START\n")); 3451285809Sscottl } 3452285809Sscottl else 3453285809Sscottl { 3454285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: INCREMENTAL_START\n")); 3455285809Sscottl } 3456285809Sscottl /* 3457285809Sscottl if MCN is 0, the device is removed 3458285809Sscottl */ 3459285809Sscottl if (oneDeviceData->MCN != oneDeviceData->PrevMCN && oneDeviceData->MCN != 0) 3460285809Sscottl { 3461285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: reporting \n")); 3462285809Sscottl extension = oneDeviceData->dmDeviceInfo.ext; 3463285809Sscottl /* zero out MCN in extension */ 3464285809Sscottl extension = extension & 0x7FF; 3465285809Sscottl /* sets MCN in extension */ 3466285809Sscottl extension = extension | (oneDeviceData->MCN << 11); 3467285809Sscottl DEVINFO_PUT_EXT(&(oneDeviceData->dmDeviceInfo), extension); 3468285809Sscottl DM_DBG5(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", DEVINFO_GET_EXT_MCN(&(oneDeviceData->dmDeviceInfo)), oneDeviceData->PrevMCN)); 3469285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 3470285809Sscottl { 3471285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: attached expander case\n")); 3472285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3473285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceMCNChange); 3474285809Sscottl } 3475285809Sscottl else 3476285809Sscottl { 3477285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: No attached expander case\n")); 3478285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceMCNChange); 3479285809Sscottl } 3480285809Sscottl oneDeviceData->PrevMCN = oneDeviceData->MCN; 3481285809Sscottl } 3482285809Sscottl else 3483285809Sscottl { 3484285809Sscottl DM_DBG2(("dmDiscoveryReportMCN: No change; no reporting \n")); 3485285809Sscottl if (oneDeviceData->MCN == 0) 3486285809Sscottl { 3487285809Sscottl oneDeviceData->PrevMCN = oneDeviceData->MCN; 3488285809Sscottl } 3489285809Sscottl } 3490285809Sscottl 3491285809Sscottl } 3492285809Sscottl DeviceListList = DeviceListList->flink; 3493285809Sscottl } 3494285809Sscottl 3495285809Sscottl return; 3496285809Sscottl} 3497285809Sscottl 3498285809SscottlosGLOBAL void 3499285809SscottldmDiscoveryDumpMCN( 3500285809Sscottl dmRoot_t *dmRoot, 3501285809Sscottl dmIntPortContext_t *onePortContext 3502285809Sscottl ) 3503285809Sscottl{ 3504285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3505285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3506285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3507285809Sscottl dmList_t *DeviceListList; 3508285809Sscottl 3509285809Sscottl DM_DBG3(("dmDiscoveryDumpMCN: start\n")); 3510285809Sscottl 3511285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3512285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3513285809Sscottl { 3514285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3515285809Sscottl if (oneDeviceData == agNULL) 3516285809Sscottl { 3517285809Sscottl DM_DBG1(("dmDiscoveryDumpMCN: oneDeviceData is NULL!!!\n")); 3518285809Sscottl return; 3519285809Sscottl } 3520285809Sscottl DM_DBG3(("dmDiscoveryDumpMCN: loop did %d\n", oneDeviceData->id)); 3521285809Sscottl if (oneDeviceData->dmPortContext == onePortContext) 3522285809Sscottl { 3523285809Sscottl DM_DBG3(("dmDiscoveryDumpMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3524285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3525285809Sscottl DM_DBG3(("dmDiscoveryDumpMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3526285809Sscottl } 3527285809Sscottl DeviceListList = DeviceListList->flink; 3528285809Sscottl } 3529285809Sscottl 3530285809Sscottl return; 3531285809Sscottl} 3532285809Sscottl 3533285809SscottlosGLOBAL void 3534285809SscottldmDiscoveryResetMCN( 3535285809Sscottl dmRoot_t *dmRoot, 3536285809Sscottl dmIntPortContext_t *onePortContext 3537285809Sscottl ) 3538285809Sscottl{ 3539285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3540285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3541285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3542285809Sscottl dmList_t *DeviceListList; 3543285809Sscottl 3544285809Sscottl DM_DBG2(("dmDiscoveryResetMCN: start\n")); 3545285809Sscottl 3546285809Sscottl /* reinitialize the device data belonging to this portcontext */ 3547285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3548285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3549285809Sscottl { 3550285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3551285809Sscottl if (oneDeviceData == agNULL) 3552285809Sscottl { 3553285809Sscottl DM_DBG1(("dmDiscoveryResetMCN: oneDeviceData is NULL!!!\n")); 3554285809Sscottl return; 3555285809Sscottl } 3556285809Sscottl DM_DBG3(("dmDiscoveryResetMCN: loop did %d\n", oneDeviceData->id)); 3557285809Sscottl if (oneDeviceData->dmPortContext == onePortContext) 3558285809Sscottl { 3559285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 3560285809Sscottl { 3561285809Sscottl DM_DBG2(("dmDiscoveryResetMCN: resetting oneDeviceData->ExpDevice\n")); 3562285809Sscottl oneDeviceData->ExpDevice = agNULL; 3563285809Sscottl } 3564285809Sscottl DM_DBG3(("dmDiscoveryResetMCN: resetting MCN and MCNdone\n")); 3565285809Sscottl oneDeviceData->MCN = 0; 3566285809Sscottl 3567285809Sscottl oneDeviceData->MCNDone = agFALSE; 3568285809Sscottl DM_DBG2(("dmDiscoveryResetMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3569285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3570285809Sscottl } 3571285809Sscottl DeviceListList = DeviceListList->flink; 3572285809Sscottl } 3573285809Sscottl 3574285809Sscottl return; 3575285809Sscottl} 3576285809Sscottl 3577285809Sscottl 3578285809Sscottl/* 3579285809Sscottldo min(oneDeviceData, found-one) in all upstream and downstream 3580285809Sscottlfind ajcanent expanders and mark it done; sees only ajcacent targets 3581285809Sscottl*/ 3582285809SscottlosGLOBAL void 3583285809SscottldmUpdateAllAdjacent( 3584285809Sscottl dmRoot_t *dmRoot, 3585285809Sscottl dmIntPortContext_t *onePortContext, 3586285809Sscottl dmDeviceData_t *oneDeviceData /* current one */ 3587285809Sscottl ) 3588285809Sscottl{ 3589285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3590285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3591285809Sscottl dmDeviceData_t *tmponeDeviceData = agNULL; 3592285809Sscottl dmList_t *DeviceListList; 3593285809Sscottl 3594285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: start\n")); 3595285809Sscottl if (oneDeviceData == agNULL) 3596285809Sscottl { 3597285809Sscottl DM_DBG1(("dmUpdateAllAdjacent: oneDeviceData is NULL!!!\n")); 3598285809Sscottl return; 3599285809Sscottl } 3600285809Sscottl 3601285809Sscottl oneDeviceData->MCNDone = agTRUE; 3602285809Sscottl 3603285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3604285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3605285809Sscottl 3606285809Sscottl 3607285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3608285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3609285809Sscottl { 3610285809Sscottl tmponeDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3611285809Sscottl if ( tmponeDeviceData == agNULL) 3612285809Sscottl { 3613285809Sscottl DM_DBG1(("dmUpdateAllAdjacent: tmponeDeviceData is NULL!!!\n")); 3614285809Sscottl return; 3615285809Sscottl } 3616285809Sscottl DM_DBG3(("dmUpdateAllAdjacent: loop did %d\n", tmponeDeviceData->id)); 3617285809Sscottl if (tmponeDeviceData->dmPortContext == onePortContext && tmponeDeviceData->ExpDevice == oneDeviceData) 3618285809Sscottl { 3619285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: setting MCN DONE\n")); 3620285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3621285809Sscottl tmponeDeviceData->SASAddressID.sasAddressHi, tmponeDeviceData->SASAddressID.sasAddressLo)); 3622285809Sscottl tmponeDeviceData->MCNDone = agTRUE; 3623285809Sscottl if (oneDeviceData->directlyAttached == agFALSE) 3624285809Sscottl { 3625285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData MCN 0x%x\n", tmponeDeviceData->MCN)); 3626285809Sscottl DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3627285809Sscottl tmponeDeviceData->MCN = MIN(oneDeviceData->MCN, tmponeDeviceData->MCN); 3628285809Sscottl } 3629285809Sscottl 3630285809Sscottl } 3631285809Sscottl DeviceListList = DeviceListList->flink; 3632285809Sscottl } 3633285809Sscottl 3634285809Sscottl return; 3635285809Sscottl 3636285809Sscottl} 3637285809Sscottl 3638285809SscottlosGLOBAL void 3639285809SscottldmUpdateMCN( 3640285809Sscottl dmRoot_t *dmRoot, 3641285809Sscottl dmIntPortContext_t *onePortContext, 3642285809Sscottl dmDeviceData_t *AdjacentDeviceData, /* adjacent expander */ 3643285809Sscottl dmDeviceData_t *oneDeviceData /* current one */ 3644285809Sscottl ) 3645285809Sscottl{ 3646285809Sscottl 3647285809Sscottl DM_DBG2(("dmUpdateMCN: start\n")); 3648285809Sscottl 3649285809Sscottl if (AdjacentDeviceData == agNULL) 3650285809Sscottl { 3651285809Sscottl DM_DBG1(("dmUpdateMCN: AdjacentDeviceData is NULL!!!\n")); 3652285809Sscottl return; 3653285809Sscottl } 3654285809Sscottl 3655285809Sscottl if (oneDeviceData == agNULL) 3656285809Sscottl { 3657285809Sscottl DM_DBG1(("dmUpdateMCN: oneDeviceData is NULL!!!\n")); 3658285809Sscottl return; 3659285809Sscottl } 3660285809Sscottl 3661285809Sscottl DM_DBG2(("dmUpdateMCN: Current sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3662285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3663285809Sscottl 3664285809Sscottl DM_DBG2(("dmUpdateMCN: AdjacentDeviceData one sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3665285809Sscottl AdjacentDeviceData->SASAddressID.sasAddressHi, AdjacentDeviceData->SASAddressID.sasAddressLo)); 3666285809Sscottl 3667285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3668285809Sscottl { 3669285809Sscottl DM_DBG2(("dmUpdateMCN: DISCOVERY_UP_STREAM\n")); 3670285809Sscottl } 3671285809Sscottl 3672285809Sscottl if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3673285809Sscottl { 3674285809Sscottl DM_DBG2(("dmUpdateMCN: DISCOVERY_DOWN_STREAM\n")); 3675285809Sscottl } 3676285809Sscottl 3677285809Sscottl 3678285809Sscottl /* MCN */ 3679285809Sscottl 3680285809Sscottl /* directly attached one does not have MCN 3681285809Sscottl update only adjacent device data 3682285809Sscottl */ 3683285809Sscottl 3684285809Sscottl if (oneDeviceData->directlyAttached == agTRUE && AdjacentDeviceData->MCNDone == agFALSE) 3685285809Sscottl { 3686285809Sscottl AdjacentDeviceData->MCN++; 3687285809Sscottl DM_DBG2(("dmUpdateMCN: case 1 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3688285809Sscottl DM_DBG2(("dmUpdateMCN: case 1 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3689285809Sscottl } 3690285809Sscottl else if (AdjacentDeviceData->MCNDone == agFALSE) 3691285809Sscottl { 3692285809Sscottl AdjacentDeviceData->MCN++; 3693285809Sscottl AdjacentDeviceData->MCN = MIN(oneDeviceData->MCN, AdjacentDeviceData->MCN); 3694285809Sscottl DM_DBG2(("dmUpdateMCN: case 2 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3695285809Sscottl DM_DBG2(("dmUpdateMCN: case 2 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3696285809Sscottl } 3697285809Sscottl 3698285809Sscottl 3699285809Sscottl return; 3700285809Sscottl} 3701285809Sscottl/* go through expander list and device list array ??? */ 3702285809SscottlosGLOBAL dmDeviceData_t * 3703285809SscottldmPortSASDeviceFind( 3704285809Sscottl dmRoot_t *dmRoot, 3705285809Sscottl dmIntPortContext_t *onePortContext, 3706285809Sscottl bit32 sasAddrLo, 3707285809Sscottl bit32 sasAddrHi, 3708285809Sscottl dmDeviceData_t *CurrentDeviceData /* current expander */ 3709285809Sscottl ) 3710285809Sscottl{ 3711285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3712285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3713285809Sscottl dmDeviceData_t *oneDeviceData, *RetDeviceData=agNULL; 3714285809Sscottl dmList_t *DeviceListList; 3715285809Sscottl 3716285809Sscottl DM_DBG3(("dmPortSASDeviceFind: start\n")); 3717285809Sscottl DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", sasAddrHi, sasAddrLo)); 3718285809Sscottl 3719285809Sscottl DM_ASSERT((agNULL != dmRoot), ""); 3720285809Sscottl DM_ASSERT((agNULL != onePortContext), ""); 3721285809Sscottl 3722285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 3723285809Sscottl 3724285809Sscottl /* find a device's existence */ 3725285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3726285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3727285809Sscottl { 3728285809Sscottl DM_DBG3(("dmPortSASDeviceFind: Full discovery\n")); 3729285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3730285809Sscottl { 3731285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3732285809Sscottl if (oneDeviceData == agNULL) 3733285809Sscottl { 3734285809Sscottl DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3735285809Sscottl return agNULL; 3736285809Sscottl } 3737285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3738285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3739285809Sscottl (oneDeviceData->valid == agTRUE) && 3740285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 3741285809Sscottl ) 3742285809Sscottl { 3743285809Sscottl DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3744285809Sscottl DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3745285809Sscottl DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3746285809Sscottl RetDeviceData = oneDeviceData; 3747285809Sscottl dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3748285809Sscottl break; 3749285809Sscottl } 3750285809Sscottl DeviceListList = DeviceListList->flink; 3751285809Sscottl } 3752285809Sscottl } 3753285809Sscottl else 3754285809Sscottl { 3755285809Sscottl /* incremental discovery */ 3756285809Sscottl DM_DBG3(("dmPortSASDeviceFind: Incremental discovery\n")); 3757285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3758285809Sscottl { 3759285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3760285809Sscottl if (oneDeviceData == agNULL) 3761285809Sscottl { 3762285809Sscottl DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3763285809Sscottl return agNULL; 3764285809Sscottl } 3765285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3766285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3767285809Sscottl (oneDeviceData->valid2 == agTRUE) && 3768285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 3769285809Sscottl ) 3770285809Sscottl { 3771285809Sscottl DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3772285809Sscottl DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3773285809Sscottl DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3774285809Sscottl RetDeviceData = oneDeviceData; 3775285809Sscottl dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3776285809Sscottl break; 3777285809Sscottl } 3778285809Sscottl DeviceListList = DeviceListList->flink; 3779285809Sscottl } 3780285809Sscottl } 3781285809Sscottl 3782285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 3783285809Sscottl 3784285809Sscottl return RetDeviceData; 3785285809Sscottl} 3786285809Sscottl 3787285809Sscottlbit32 3788285809SscottldmNewEXPorNot( 3789285809Sscottl dmRoot_t *dmRoot, 3790285809Sscottl dmIntPortContext_t *onePortContext, 3791285809Sscottl dmSASSubID_t *dmSASSubID 3792285809Sscottl ) 3793285809Sscottl{ 3794285809Sscottl// dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3795285809Sscottl// dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3796285809Sscottl dmExpander_t *oneExpander = agNULL; 3797285809Sscottl dmList_t *ExpanderList; 3798285809Sscottl bit32 ret = agTRUE; 3799285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3800285809Sscottl 3801285809Sscottl DM_DBG3(("dmNewEXPorNot: start\n")); 3802285809Sscottl 3803285809Sscottl /* find a device's existence */ 3804285809Sscottl ExpanderList = onePortContext->discovery.discoveringExpanderList.flink; 3805285809Sscottl while (ExpanderList != &(onePortContext->discovery.discoveringExpanderList)) 3806285809Sscottl { 3807285809Sscottl oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3808285809Sscottl if ( oneExpander == agNULL) 3809285809Sscottl { 3810285809Sscottl DM_DBG1(("dmNewEXPorNot: oneExpander is NULL!!!\n")); 3811285809Sscottl return agFALSE; 3812285809Sscottl } 3813285809Sscottl oneDeviceData = oneExpander->dmDevice; 3814285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3815285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3816285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 3817285809Sscottl ) 3818285809Sscottl { 3819285809Sscottl DM_DBG3(("dmNewEXPorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3820285809Sscottl ret = agFALSE; 3821285809Sscottl break; 3822285809Sscottl } 3823285809Sscottl ExpanderList = ExpanderList->flink; 3824285809Sscottl } 3825285809Sscottl 3826285809Sscottl return ret; 3827285809Sscottl} 3828285809Sscottl 3829285809Sscottl 3830285809Sscottlbit32 3831285809SscottldmNewSASorNot( 3832285809Sscottl dmRoot_t *dmRoot, 3833285809Sscottl dmIntPortContext_t *onePortContext, 3834285809Sscottl dmSASSubID_t *dmSASSubID 3835285809Sscottl ) 3836285809Sscottl{ 3837285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3838285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3839285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3840285809Sscottl dmList_t *DeviceListList; 3841285809Sscottl bit32 ret = agTRUE; 3842285809Sscottl 3843285809Sscottl DM_DBG3(("dmNewSASorNot: start\n")); 3844285809Sscottl 3845285809Sscottl /* find a device's existence */ 3846285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 3847285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 3848285809Sscottl { 3849285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3850285809Sscottl if (oneDeviceData == agNULL) 3851285809Sscottl { 3852285809Sscottl DM_DBG1(("dmNewSASorNot: oneDeviceData is NULL!!!\n")); 3853285809Sscottl return agFALSE; 3854285809Sscottl } 3855285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3856285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3857285809Sscottl (oneDeviceData->dmPortContext == onePortContext) && 3858285809Sscottl (oneDeviceData->registered == agTRUE) 3859285809Sscottl ) 3860285809Sscottl { 3861285809Sscottl DM_DBG3(("dmNewSASorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3862285809Sscottl ret = agFALSE; 3863285809Sscottl break; 3864285809Sscottl } 3865285809Sscottl DeviceListList = DeviceListList->flink; 3866285809Sscottl } 3867285809Sscottl 3868285809Sscottl return ret; 3869285809Sscottl} 3870285809Sscottl/* 3871285809Sscottlcall 3872285809SscottlosGLOBAL bit32 3873285809SscottltddmReportDevice( 3874285809Sscottl dmRoot_t *dmRoot, 3875285809Sscottl dmPortContext_t *dmPortContext, 3876285809Sscottl dmDeviceInfo_t *dmDeviceInfo 3877285809Sscottl ) 3878285809Sscottlif not reported, report Device to TDM 3879285809Sscottl*/ 3880285809SscottlosGLOBAL dmDeviceData_t * 3881285809SscottldmPortSASDeviceAdd( 3882285809Sscottl dmRoot_t *dmRoot, 3883285809Sscottl dmIntPortContext_t *onePortContext, 3884285809Sscottl agsaSASIdentify_t sasIdentify, 3885285809Sscottl bit32 sasInitiator, 3886285809Sscottl bit8 connectionRate, 3887285809Sscottl bit32 itNexusTimeout, 3888285809Sscottl bit32 firstBurstSize, 3889285809Sscottl bit32 deviceType, 3890285809Sscottl dmDeviceData_t *oneExpDeviceData, 3891285809Sscottl dmExpander_t *dmExpander, 3892285809Sscottl bit8 phyID 3893285809Sscottl ) 3894285809Sscottl{ 3895285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 3896285809Sscottl bit8 dev_s_rate = 0; 3897285809Sscottl bit8 sasorsata = 1; 3898285809Sscottl dmSASSubID_t dmSASSubID; 3899285809Sscottl bit8 ExpanderConnectionRate = connectionRate; 3900285809Sscottl dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3901285809Sscottl bit16 extension = 0; 3902285809Sscottl bit32 current_link_rate = 0; 3903285809Sscottl 3904285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: start\n")); 3905285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: connectionRate %d\n", connectionRate)); 3906285809Sscottl 3907285809Sscottl dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 3908285809Sscottl dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 3909285809Sscottl dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 3910285809Sscottl dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 3911285809Sscottl 3912285809Sscottl if (oneExpDeviceData != agNULL) 3913285809Sscottl { 3914285809Sscottl ExpanderConnectionRate = DEVINFO_GET_LINKRATE(&oneExpDeviceData->agDeviceInfo); 3915285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: ExpanderConnectionRate 0x%x\n", ExpanderConnectionRate)); 3916285809Sscottl } 3917285809Sscottl if (oneExpDeviceData != agNULL) 3918285809Sscottl { 3919285809Sscottl if (oneExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 3920285809Sscottl oneExpDeviceData->SASAddressID.sasAddressLo == 0x0) 3921285809Sscottl { 3922285809Sscottl DM_DBG1(("dmPortSASDeviceAdd: 1st Wrong expander!!!\n")); 3923285809Sscottl } 3924285809Sscottl } 3925285809Sscottl /* old device and already reported to TDM */ 3926285809Sscottl if ( agFALSE == dmNewSASorNot( 3927285809Sscottl dmRoot, 3928285809Sscottl onePortContext, 3929285809Sscottl &dmSASSubID 3930285809Sscottl ) 3931285809Sscottl ) /* old device */ 3932285809Sscottl { 3933285809Sscottl 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)); 3934285809Sscottl /* allocate a new device and set the valid bit */ 3935285809Sscottl oneDeviceData = dmAddSASToSharedcontext( 3936285809Sscottl dmRoot, 3937285809Sscottl onePortContext, 3938285809Sscottl &dmSASSubID, 3939285809Sscottl oneExpDeviceData, 3940285809Sscottl phyID 3941285809Sscottl ); 3942285809Sscottl if (oneDeviceData == agNULL) 3943285809Sscottl { 3944285809Sscottl DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null!!!\n")); 3945285809Sscottl } 3946285809Sscottl /* If a device is allocated */ 3947285809Sscottl if ( oneDeviceData != agNULL ) 3948285809Sscottl { 3949285809Sscottl 3950285809Sscottl 3951285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3952285809Sscottl { 3953285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: OLD, UP_STREAM\n")); 3954285809Sscottl } 3955285809Sscottl if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3956285809Sscottl { 3957285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: OLD, DOWN_STREAM\n")); 3958285809Sscottl } 3959285809Sscottl 3960285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3961285809Sscottl { 3962285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 3963285809Sscottl oneDeviceData->MCN++; 3964285809Sscottl } 3965285809Sscottl else 3966285809Sscottl { 3967285809Sscottl /* incremental */ 3968285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 3969285809Sscottl if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 3970285809Sscottl { 3971285809Sscottl oneDeviceData->MCN++; 3972285809Sscottl } 3973285809Sscottl } 3974285809Sscottl 3975285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 3976285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3977285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3978285809Sscottl 3979285809Sscottl 3980285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 3981285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 3982285809Sscottl 3983285809Sscottl// oneDeviceData->sasIdentify = sasIdentify; 3984285809Sscottl dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 3985285809Sscottl 3986285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 3987285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 3988285809Sscottl 3989285809Sscottl /* parse sasIDframe to fill in agDeviceInfo */ 3990285809Sscottl DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 3991285809Sscottl DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 3992285809Sscottl DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 3993285809Sscottl DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 3994285809Sscottl 3995285809Sscottl oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 3996285809Sscottl 3997285809Sscottl /* adjusting connectionRate */ 3998285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3999285809Sscottl if (oneAttachedExpDeviceData != agNULL) 4000285809Sscottl { 4001285809Sscottl connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4002285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4003285809Sscottl connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4004285809Sscottl } 4005285809Sscottl else 4006285809Sscottl { 4007285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n")); 4008285809Sscottl } 4009285809Sscottl 4010285809Sscottl /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4011285809Sscottl sasorsata = (bit8)deviceType; 4012285809Sscottl /* sTSDK spec device typ */ 4013285809Sscottl dev_s_rate = dev_s_rate | (sasorsata << 4); 4014285809Sscottl dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4015285809Sscottl /* detect link rate change */ 4016285809Sscottl current_link_rate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); 4017285809Sscottl if (current_link_rate != (bit32)MIN(connectionRate, ExpanderConnectionRate)) 4018285809Sscottl { 4019285809Sscottl DM_DBG1(("dmPortSASDeviceAdd: link rate changed current 0x%x new 0x%x\n", current_link_rate, MIN(connectionRate, ExpanderConnectionRate))); 4020285809Sscottl DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4021285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 4022285809Sscottl { 4023285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4024285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceRateChange); 4025285809Sscottl } 4026285809Sscottl else 4027285809Sscottl { 4028285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4029285809Sscottl } 4030285809Sscottl } 4031285809Sscottl 4032285809Sscottl DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4033285809Sscottl 4034285809Sscottl 4035285809Sscottl DEVINFO_PUT_SAS_ADDRESSLO( 4036285809Sscottl &oneDeviceData->agDeviceInfo, 4037285809Sscottl SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4038285809Sscottl ); 4039285809Sscottl DEVINFO_PUT_SAS_ADDRESSHI( 4040285809Sscottl &oneDeviceData->agDeviceInfo, 4041285809Sscottl SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4042285809Sscottl ); 4043285809Sscottl oneDeviceData->agContext.osData = oneDeviceData; 4044285809Sscottl oneDeviceData->agContext.sdkData = agNULL; 4045285809Sscottl 4046285809Sscottl 4047285809Sscottl } 4048285809Sscottl return oneDeviceData; 4049285809Sscottl } /* old device */ 4050285809Sscottl 4051285809Sscottl 4052285809Sscottl /* new device */ 4053285809Sscottl 4054285809Sscottl 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)); 4055285809Sscottl 4056285809Sscottl /* allocate a new device and set the valid bit */ 4057285809Sscottl oneDeviceData = dmAddSASToSharedcontext( 4058285809Sscottl dmRoot, 4059285809Sscottl onePortContext, 4060285809Sscottl &dmSASSubID, 4061285809Sscottl oneExpDeviceData, 4062285809Sscottl phyID 4063285809Sscottl ); 4064285809Sscottl if (oneDeviceData == agNULL) 4065285809Sscottl { 4066285809Sscottl DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null !!!\n")); 4067285809Sscottl } 4068285809Sscottl 4069285809Sscottl /* If a device is allocated */ 4070285809Sscottl if ( oneDeviceData != agNULL ) 4071285809Sscottl { 4072285809Sscottl 4073285809Sscottl// DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 4074285809Sscottl// DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 4075285809Sscottl 4076285809Sscottl// oneDeviceData->sasIdentify = sasIdentify; 4077285809Sscottl dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 4078285809Sscottl 4079285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4080285809Sscottl { 4081285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: NEW, UP_STREAM\n")); 4082285809Sscottl } 4083285809Sscottl if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4084285809Sscottl { 4085285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: NEW, DOWN_STREAM\n")); 4086285809Sscottl } 4087285809Sscottl 4088285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4089285809Sscottl { 4090285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 4091285809Sscottl oneDeviceData->MCN++; 4092285809Sscottl } 4093285809Sscottl else 4094285809Sscottl { 4095285809Sscottl /* incremental */ 4096285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 4097285809Sscottl if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 4098285809Sscottl { 4099285809Sscottl oneDeviceData->MCN++; 4100285809Sscottl } 4101285809Sscottl } 4102285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 4103285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 4104285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 4105285809Sscottl 4106285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 4107285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 4108285809Sscottl 4109285809Sscottl /* parse sasIDframe to fill in agDeviceInfo */ 4110285809Sscottl DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 4111285809Sscottl DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 4112285809Sscottl DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 4113285809Sscottl DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 4114285809Sscottl 4115285809Sscottl oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 4116285809Sscottl 4117285809Sscottl /* adjusting connectionRate */ 4118285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4119285809Sscottl if (oneAttachedExpDeviceData != agNULL) 4120285809Sscottl { 4121285809Sscottl connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4122285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: 2nd connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4123285809Sscottl connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4124285809Sscottl } 4125285809Sscottl else 4126285809Sscottl { 4127285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n")); 4128285809Sscottl } 4129285809Sscottl 4130285809Sscottl /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4131285809Sscottl sasorsata = (bit8)deviceType; 4132285809Sscottl dev_s_rate = dev_s_rate | (sasorsata << 4); 4133285809Sscottl dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4134285809Sscottl DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4135285809Sscottl 4136285809Sscottl 4137285809Sscottl DEVINFO_PUT_SAS_ADDRESSLO( 4138285809Sscottl &oneDeviceData->agDeviceInfo, 4139285809Sscottl SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4140285809Sscottl ); 4141285809Sscottl DEVINFO_PUT_SAS_ADDRESSHI( 4142285809Sscottl &oneDeviceData->agDeviceInfo, 4143285809Sscottl SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4144285809Sscottl ); 4145285809Sscottl oneDeviceData->agContext.osData = oneDeviceData; 4146285809Sscottl oneDeviceData->agContext.sdkData = agNULL; 4147285809Sscottl 4148285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: did %d\n", oneDeviceData->id)); 4149285809Sscottl 4150285809Sscottl 4151285809Sscottl /* reporting to TDM; setting dmDeviceInfo */ 4152285809Sscottl DEVINFO_PUT_SMPTO(&oneDeviceData->dmDeviceInfo, DEFAULT_SMP_TIMEOUT); 4153285809Sscottl DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->dmDeviceInfo, (bit16)itNexusTimeout); 4154285809Sscottl DEVINFO_PUT_FBS(&oneDeviceData->dmDeviceInfo, (bit16)firstBurstSize); 4155285809Sscottl DEVINFO_PUT_FLAG(&oneDeviceData->dmDeviceInfo, 1); 4156285809Sscottl DEVINFO_PUT_INITIATOR_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.initiator_ssp_stp_smp); 4157285809Sscottl DEVINFO_PUT_TARGET_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.target_ssp_stp_smp); 4158285809Sscottl extension = phyID; 4159285809Sscottl 4160285809Sscottl /* setting 6th bit of dev_s_rate */ 4161285809Sscottl if (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE || 4162285809Sscottl oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 4163285809Sscottl { 4164285809Sscottl extension = (bit16)(extension | (1 << 8)); 4165285809Sscottl } 4166285809Sscottl DEVINFO_PUT_EXT(&oneDeviceData->dmDeviceInfo, extension); 4167285809Sscottl 4168285809Sscottl DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4169285809Sscottl 4170285809Sscottl DEVINFO_PUT_SAS_ADDRESSLO( 4171285809Sscottl &oneDeviceData->dmDeviceInfo, 4172285809Sscottl SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4173285809Sscottl ); 4174285809Sscottl DEVINFO_PUT_SAS_ADDRESSHI( 4175285809Sscottl &oneDeviceData->dmDeviceInfo, 4176285809Sscottl SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4177285809Sscottl ); 4178285809Sscottl 4179285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 4180285809Sscottl { 4181285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: attached expander case\n")); 4182285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4183285809Sscottl /* 4184285809Sscottl Puts attached expander's SAS address into dmDeviceInfo 4185285809Sscottl */ 4186285809Sscottl DEVINFO_PUT_SAS_ADDRESSLO( 4187285809Sscottl &oneAttachedExpDeviceData->dmDeviceInfo, 4188285809Sscottl oneAttachedExpDeviceData->SASAddressID.sasAddressLo 4189285809Sscottl ); 4190285809Sscottl DEVINFO_PUT_SAS_ADDRESSHI( 4191285809Sscottl &oneAttachedExpDeviceData->dmDeviceInfo, 4192285809Sscottl oneAttachedExpDeviceData->SASAddressID.sasAddressHi 4193285809Sscottl ); 4194285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: oneAttachedExpDeviceData addrHi 0x%08x addrLo 0x%08x PhyID 0x%x ext 0x%x\n", 4195285809Sscottl DM_GET_SAS_ADDRESSHI(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressHi), 4196285809Sscottl DM_GET_SAS_ADDRESSLO(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressLo), 4197285809Sscottl phyID, extension)); 4198285809Sscottl 4199285809Sscottl if (oneAttachedExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 4200285809Sscottl oneAttachedExpDeviceData->SASAddressID.sasAddressLo == 0x0) 4201285809Sscottl { 4202285809Sscottl DM_DBG1(("dmPortSASDeviceAdd: 2nd Wrong expander!!!\n")); 4203285809Sscottl } 4204285809Sscottl if (oneDeviceData->reported == agFALSE) 4205285809Sscottl { 4206285809Sscottl oneDeviceData->registered = agTRUE; 4207285809Sscottl oneDeviceData->reported = agTRUE; 4208285809Sscottl if (deviceType == STP_DEVICE_TYPE) 4209285809Sscottl { 4210285809Sscottl /*STP device, DM need send SMP Report Phy SATA to get the SATA device type */ 4211285809Sscottl oneAttachedExpDeviceData->dmExpander->dmDeviceToProcess = oneDeviceData; 4212285809Sscottl dmReportPhySataSend(dmRoot, oneAttachedExpDeviceData, phyID); 4213285809Sscottl } 4214285809Sscottl else 4215285809Sscottl { 4216285809Sscottl /* SAS or SMP device */ 4217285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceArrival); 4218285809Sscottl } 4219285809Sscottl } 4220285809Sscottl } 4221285809Sscottl else 4222285809Sscottl { 4223285809Sscottl DM_DBG3(("dmPortSASDeviceAdd: NO attached expander case\n")); 4224285809Sscottl if (oneDeviceData->reported == agFALSE) 4225285809Sscottl { 4226285809Sscottl oneDeviceData->registered = agTRUE; 4227285809Sscottl oneDeviceData->reported = agTRUE; 4228285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4229285809Sscottl } 4230285809Sscottl } 4231285809Sscottl } 4232285809Sscottl 4233285809Sscottl return oneDeviceData; 4234285809Sscottl} 4235285809Sscottl 4236285809SscottlosGLOBAL dmDeviceData_t * 4237285809SscottldmFindRegNValid( 4238285809Sscottl dmRoot_t *dmRoot, 4239285809Sscottl dmIntPortContext_t *onePortContext, 4240285809Sscottl dmSASSubID_t *dmSASSubID 4241285809Sscottl ) 4242285809Sscottl{ 4243285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4244285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4245285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 4246285809Sscottl dmList_t *DeviceListList; 4247285809Sscottl bit32 found = agFALSE; 4248285809Sscottl DM_DBG3(("dmFindRegNValid: start\n")); 4249285809Sscottl 4250285809Sscottl /* find a device's existence */ 4251285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 4252285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4253285809Sscottl { 4254285809Sscottl DM_DBG3(("dmFindRegNValid: Full discovery\n")); 4255285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 4256285809Sscottl { 4257285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4258285809Sscottl if (oneDeviceData == agNULL) 4259285809Sscottl { 4260285809Sscottl DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4261285809Sscottl return agFALSE; 4262285809Sscottl } 4263285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4264285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4265285809Sscottl (oneDeviceData->valid == agTRUE) && 4266285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 4267285809Sscottl ) 4268285809Sscottl { 4269285809Sscottl DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4270285809Sscottl DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4271285809Sscottl DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4272285809Sscottl found = agTRUE; 4273285809Sscottl break; 4274285809Sscottl } 4275285809Sscottl DeviceListList = DeviceListList->flink; 4276285809Sscottl } 4277285809Sscottl } 4278285809Sscottl else 4279285809Sscottl { 4280285809Sscottl /* incremental discovery */ 4281285809Sscottl DM_DBG3(("dmFindRegNValid: Incremental discovery\n")); 4282285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 4283285809Sscottl { 4284285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4285285809Sscottl if (oneDeviceData == agNULL) 4286285809Sscottl { 4287285809Sscottl DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4288285809Sscottl return agFALSE; 4289285809Sscottl } 4290285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4291285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4292285809Sscottl (oneDeviceData->valid2 == agTRUE) && 4293285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 4294285809Sscottl ) 4295285809Sscottl { 4296285809Sscottl DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4297285809Sscottl DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4298285809Sscottl DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4299285809Sscottl found = agTRUE; 4300285809Sscottl break; 4301285809Sscottl } 4302285809Sscottl DeviceListList = DeviceListList->flink; 4303285809Sscottl } 4304285809Sscottl } 4305285809Sscottl 4306285809Sscottl 4307285809Sscottl 4308285809Sscottl if (found == agFALSE) 4309285809Sscottl { 4310285809Sscottl DM_DBG3(("dmFindRegNValid: end returning NULL\n")); 4311285809Sscottl return agNULL; 4312285809Sscottl } 4313285809Sscottl else 4314285809Sscottl { 4315285809Sscottl DM_DBG3(("dmFindRegNValid: end returning NOT NULL\n")); 4316285809Sscottl return oneDeviceData; 4317285809Sscottl } 4318285809Sscottl} 4319285809Sscottl 4320285809SscottlosGLOBAL void 4321285809SscottldmNotifyBC( 4322285809Sscottl dmRoot_t *dmRoot, 4323285809Sscottl dmPortContext_t *dmPortContext, 4324285809Sscottl bit32 type) 4325285809Sscottl{ 4326285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 4327285809Sscottl 4328285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4329285809Sscottl 4330285809Sscottl DM_DBG3(("dmNotifyBC: start\n")); 4331285809Sscottl 4332285809Sscottl if (onePortContext == agNULL) 4333285809Sscottl { 4334285809Sscottl DM_DBG1(("dmNotifyBC: onePortContext is NULL, wrong!!!\n")); 4335285809Sscottl return; 4336285809Sscottl } 4337285809Sscottl 4338285809Sscottl if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4339285809Sscottl { 4340285809Sscottl if (onePortContext->DiscoveryAbortInProgress == agFALSE) 4341285809Sscottl { 4342285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4343285809Sscottl { 4344285809Sscottl DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE\n")); 4345285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4346285809Sscottl onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4347285809Sscottl /* processed broadcast change */ 4348285809Sscottl onePortContext->discovery.SeenBC = agFALSE; 4349285809Sscottl } 4350285809Sscottl else 4351285809Sscottl { 4352285809Sscottl DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4353285809Sscottl onePortContext->discovery.SeenBC = agTRUE; 4354285809Sscottl } 4355285809Sscottl } 4356285809Sscottl } 4357285809Sscottl else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4358285809Sscottl { 4359285809Sscottl DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4360285809Sscottl } 4361285809Sscottl else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4362285809Sscottl { 4363285809Sscottl DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4364285809Sscottl } 4365285809Sscottl else 4366285809Sscottl { 4367285809Sscottl DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4368285809Sscottl } 4369285809Sscottl return; 4370285809Sscottl} 4371285809Sscottl 4372285809Sscottl 4373285809Sscottl#ifdef WORKED 4374285809Sscottl/* triggers incremental discovery */ 4375285809SscottlosGLOBAL void 4376285809SscottldmNotifyBC( 4377285809Sscottl dmRoot_t *dmRoot, 4378285809Sscottl dmPortContext_t *dmPortContext, 4379285809Sscottl bit32 type) 4380285809Sscottl{ 4381285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 4382285809Sscottl 4383285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4384285809Sscottl 4385285809Sscottl DM_DBG3(("dmNotifyBC: start\n")); 4386285809Sscottl 4387285809Sscottl 4388285809Sscottl if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4389285809Sscottl { 4390285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4391285809Sscottl { 4392285809Sscottl DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE; does incremental discovery\n")); 4393285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4394285809Sscottl onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4395285809Sscottl /* processed broadcast change */ 4396285809Sscottl onePortContext->discovery.SeenBC = agFALSE; 4397285809Sscottl if (onePortContext->discovery.ResetTriggerred == agTRUE) 4398285809Sscottl { 4399285809Sscottl DM_DBG3(("dmNotifyBC: tdsaBCTimer\n")); 4400285809Sscottl dmBCTimer(dmRoot, onePortContext); 4401285809Sscottl } 4402285809Sscottl else 4403285809Sscottl { 4404285809Sscottl dmDiscover( 4405285809Sscottl dmRoot, 4406285809Sscottl dmPortContext, 4407285809Sscottl DM_DISCOVERY_OPTION_INCREMENTAL_START 4408285809Sscottl ); 4409285809Sscottl } 4410285809Sscottl } 4411285809Sscottl else 4412285809Sscottl { 4413285809Sscottl DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4414285809Sscottl onePortContext->discovery.SeenBC = agTRUE; 4415285809Sscottl } 4416285809Sscottl } 4417285809Sscottl else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4418285809Sscottl { 4419285809Sscottl DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4420285809Sscottl } 4421285809Sscottl else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4422285809Sscottl { 4423285809Sscottl DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4424285809Sscottl } 4425285809Sscottl else 4426285809Sscottl { 4427285809Sscottl DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4428285809Sscottl } 4429285809Sscottl return; 4430285809Sscottl} 4431285809Sscottl#endif 4432285809Sscottl 4433285809SscottlosGLOBAL bit32 4434285809SscottldmResetFailedDiscovery( 4435285809Sscottl dmRoot_t *dmRoot, 4436285809Sscottl dmPortContext_t *dmPortContext) 4437285809Sscottl{ 4438285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 4439285809Sscottl 4440285809Sscottl DM_DBG1(("dmResetFailedDiscovery: start\n")); 4441285809Sscottl 4442285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4443285809Sscottl 4444285809Sscottl if (onePortContext == agNULL) 4445285809Sscottl { 4446285809Sscottl DM_DBG1(("dmResetFailedDiscovery: onePortContext is NULL, wrong!!!\n")); 4447285809Sscottl return DM_RC_FAILURE; 4448285809Sscottl } 4449285809Sscottl 4450285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4451285809Sscottl { 4452285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 4453285809Sscottl } 4454285809Sscottl else 4455285809Sscottl { 4456285809Sscottl DM_DBG1(("dmResetFailedDiscovery: discovery is NOT DM_DSTATE_COMPLETED_WITH_FAILURE. It is 0x%x\n", onePortContext->DiscoveryState)); 4457285809Sscottl return DM_RC_FAILURE; 4458285809Sscottl } 4459285809Sscottl 4460285809Sscottl return DM_RC_SUCCESS; 4461285809Sscottl} 4462285809Sscottl 4463285809SscottlosGLOBAL bit32 4464285809SscottldmQueryDiscovery( 4465285809Sscottl dmRoot_t *dmRoot, 4466285809Sscottl dmPortContext_t *dmPortContext) 4467285809Sscottl{ 4468285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 4469285809Sscottl 4470285809Sscottl DM_DBG3(("dmQueryDiscovery: start\n")); 4471285809Sscottl 4472285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4473285809Sscottl 4474285809Sscottl if (onePortContext == agNULL) 4475285809Sscottl { 4476285809Sscottl DM_DBG1(("dmQueryDiscovery: onePortContext is NULL, wrong!!!\n")); 4477285809Sscottl return DM_RC_FAILURE; 4478285809Sscottl } 4479285809Sscottl 4480285809Sscottl /* call tddmQueryDiscoveryCB() */ 4481285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4482285809Sscottl { 4483285809Sscottl tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscCompleted); 4484285809Sscottl } 4485285809Sscottl else if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4486285809Sscottl { 4487285809Sscottl tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscFailed); 4488285809Sscottl } 4489285809Sscottl else 4490285809Sscottl { 4491285809Sscottl tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscInProgress); 4492285809Sscottl } 4493285809Sscottl 4494285809Sscottl return DM_RC_SUCCESS; 4495285809Sscottl} 4496285809Sscottl 4497285809Sscottl 4498285809Sscottl/* 4499285809Sscottl should only for an expander 4500285809Sscottl*/ 4501285809SscottlosGLOBAL bit32 4502285809SscottldmRegisterDevice( 4503285809Sscottl dmRoot_t *dmRoot, 4504285809Sscottl dmPortContext_t *dmPortContext, 4505285809Sscottl dmDeviceInfo_t *dmDeviceInfo, 4506285809Sscottl agsaDevHandle_t *agDevHandle 4507285809Sscottl ) 4508285809Sscottl{ 4509285809Sscottl 4510285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 4511285809Sscottl dmExpander_t *oneExpander = agNULL; 4512285809Sscottl bit32 sasAddressHi, sasAddressLo; 4513285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 4514285809Sscottl dmSASSubID_t dmSASSubID; 4515285809Sscottl 4516285809Sscottl DM_DBG3(("dmRegisterDevice: start\n")); 4517285809Sscottl 4518285809Sscottl onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4519285809Sscottl if (onePortContext == agNULL) 4520285809Sscottl { 4521285809Sscottl DM_DBG1(("dmRegisterDevice: onePortContext is NULL!!!\n")); 4522285809Sscottl return DM_RC_FAILURE; 4523285809Sscottl } 4524285809Sscottl 4525285809Sscottl if (onePortContext->valid == agFALSE) 4526285809Sscottl { 4527285809Sscottl DM_DBG1(("dmRegisterDevice: invalid port!!!\n")); 4528285809Sscottl return DM_RC_FAILURE; 4529285809Sscottl } 4530285809Sscottl 4531285809Sscottl onePortContext->RegFailed = agFALSE; 4532285809Sscottl 4533285809Sscottl /* tdssAddSASToSharedcontext() from ossaHwCB() 4534285809SscottlosGLOBAL void 4535285809SscottltdssAddSASToSharedcontext( 4536285809Sscottl tdsaPortContext_t *tdsaPortContext_Instance, 4537285809Sscottl agsaRoot_t *agRoot, 4538285809Sscottl agsaDevHandle_t *agDevHandle, 4539285809Sscottl tdsaSASSubID_t *agSASSubID, 4540285809Sscottl bit32 registered, 4541285809Sscottl bit8 phyID, 4542285809Sscottl bit32 flag 4543285809Sscottl ); 4544285809Sscottlfrom discovery 4545285809SscottlosGLOBAL tdsaDeviceData_t * 4546285809SscottltdssNewAddSASToSharedcontext( 4547285809Sscottl agsaRoot_t *agRoot, 4548285809Sscottl tdsaPortContext_t *onePortContext, 4549285809Sscottl tdsaSASSubID_t *agSASSubID, 4550285809Sscottl tdsaDeviceData_t *oneExpDeviceData, 4551285809Sscottl bit8 phyID 4552285809Sscottl ); 4553285809Sscottl 4554285809Sscottl */ 4555285809Sscottl /* start here */ 4556285809Sscottl dmSASSubID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4557285809Sscottl dmSASSubID.sasAddressLo = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressLo); 4558285809Sscottl dmSASSubID.initiator_ssp_stp_smp = dmDeviceInfo->initiator_ssp_stp_smp; 4559285809Sscottl dmSASSubID.target_ssp_stp_smp = dmDeviceInfo->target_ssp_stp_smp; 4560285809Sscottl 4561285809Sscottl oneDeviceData = dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, agNULL, 0xFF); 4562285809Sscottl if (oneDeviceData == agNULL) 4563285809Sscottl { 4564285809Sscottl DM_DBG1(("dmRegisterDevice: oneDeviceData is NULL!!!\n")); 4565285809Sscottl return DM_RC_FAILURE; 4566285809Sscottl } 4567285809Sscottl oneDeviceData->agDeviceInfo.devType_S_Rate = dmDeviceInfo->devType_S_Rate; 4568285809Sscottl dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressHi, dmDeviceInfo->sasAddressHi, 4); 4569285809Sscottl dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressLo, dmDeviceInfo->sasAddressLo, 4); 4570285809Sscottl /* finds the type of expanders */ 4571285809Sscottl if (DEVINFO_GET_EXT_SMP(dmDeviceInfo)) 4572285809Sscottl { 4573285809Sscottl if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_EDGE_EXPANDER_DEVICE) 4574285809Sscottl { 4575285809Sscottl oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4576285809Sscottl } 4577285809Sscottl else if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_FANOUT_EXPANDER_DEVICE) 4578285809Sscottl { 4579285809Sscottl oneDeviceData->SASSpecDeviceType = SAS_FANOUT_EXPANDER_DEVICE; 4580285809Sscottl } 4581285809Sscottl else 4582285809Sscottl { 4583285809Sscottl /* default */ 4584285809Sscottl DM_DBG4(("dmRegisterDevice: no expander type. default to edge expander\n")); 4585285809Sscottl oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4586285809Sscottl } 4587285809Sscottl } 4588285809Sscottl 4589285809Sscottl if (DEVINFO_GET_EXT_MCN(dmDeviceInfo) == 0xF) 4590285809Sscottl { 4591285809Sscottl DM_DBG1(("dmRegisterDevice: directly attached expander\n")); 4592285809Sscottl oneDeviceData->directlyAttached = agTRUE; 4593285809Sscottl oneDeviceData->dmDeviceInfo.ext = (bit16)(oneDeviceData->dmDeviceInfo.ext | (0xF << 11)); 4594285809Sscottl } 4595285809Sscottl else 4596285809Sscottl { 4597285809Sscottl DM_DBG1(("dmRegisterDevice: NOT directly attached expander\n")); 4598285809Sscottl oneDeviceData->directlyAttached = agFALSE; 4599285809Sscottl } 4600285809Sscottl 4601285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 4602285809Sscottl { 4603285809Sscottl DM_DBG3(("dmRegisterDevice: DM_DSTATE_NOT_STARTED\n")); 4604285809Sscottl /* before the discovery is started */ 4605285809Sscottl oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 4606285809Sscottl if ( oneExpander != agNULL) 4607285809Sscottl { 4608285809Sscottl oneExpander->agDevHandle = agDevHandle; 4609285809Sscottl /* update SAS address field */ 4610285809Sscottl oneExpander->dmDevice->SASAddressID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4611285809Sscottl oneExpander->dmDevice->SASAddressID.sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4612285809Sscottl DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi, oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4613285809Sscottl dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 4614285809Sscottl } 4615285809Sscottl else 4616285809Sscottl { 4617285809Sscottl DM_DBG1(("dmRegisterDevice: failed to allocate expander !!!\n")); 4618285809Sscottl /* remember that the registration failed so that a discovery can't be started */ 4619285809Sscottl onePortContext->RegFailed = agTRUE; 4620285809Sscottl return DM_RC_FAILURE; 4621285809Sscottl } 4622285809Sscottl } 4623285809Sscottl else 4624285809Sscottl { 4625285809Sscottl /* 4626285809Sscottl the discovery has started. Alloc and add have been done. 4627285809Sscottl find an expander using dmDeviceInfo, and update the expander's agDevHandle 4628285809Sscottl call dmExpFind() 4629285809Sscottl */ 4630285809Sscottl DM_DBG3(("dmRegisterDevice: NOT DM_DSTATE_NOT_STARTED\n")); 4631285809Sscottl sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4632285809Sscottl sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4633285809Sscottl DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 4634285809Sscottl oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 4635285809Sscottl if ( oneExpander != agNULL) 4636285809Sscottl { 4637285809Sscottl oneExpander->agDevHandle = agDevHandle; 4638285809Sscottl } 4639285809Sscottl else 4640285809Sscottl { 4641285809Sscottl DM_DBG1(("dmRegisterDevice: not allowed case, wrong !!!\n")); 4642285809Sscottl return DM_RC_FAILURE; 4643285809Sscottl } 4644285809Sscottl } 4645285809Sscottl 4646285809Sscottl return DM_RC_SUCCESS; 4647285809Sscottl} 4648285809Sscottl 4649285809SscottlosGLOBAL dmExpander_t * 4650285809SscottldmDiscoveringExpanderAlloc( 4651285809Sscottl dmRoot_t *dmRoot, 4652285809Sscottl dmIntPortContext_t *onePortContext, 4653285809Sscottl dmDeviceData_t *oneDeviceData 4654285809Sscottl ) 4655285809Sscottl{ 4656285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4657285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4658285809Sscottl dmExpander_t *oneExpander = agNULL; 4659285809Sscottl dmList_t *ExpanderList; 4660285809Sscottl 4661285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: start\n")); 4662285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: did %d\n", oneDeviceData->id)); 4663285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4664285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4665285809Sscottl 4666285809Sscottl if (onePortContext->valid == agFALSE) 4667285809Sscottl { 4668285809Sscottl DM_DBG1(("dmDiscoveringExpanderAlloc: invalid port!!!\n")); 4669285809Sscottl return agNULL; 4670285809Sscottl } 4671285809Sscottl 4672285809Sscottl 4673285809Sscottl /* check exitence in dmAllShared->mainExpanderList */ 4674285809Sscottl oneExpander = dmExpMainListFind(dmRoot, 4675285809Sscottl onePortContext, 4676285809Sscottl oneDeviceData->SASAddressID.sasAddressHi, 4677285809Sscottl oneDeviceData->SASAddressID.sasAddressLo); 4678285809Sscottl 4679285809Sscottl if (oneExpander == agNULL) 4680285809Sscottl { 4681285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4682285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->freeExpanderList))) 4683285809Sscottl { 4684285809Sscottl DM_DBG1(("dmDiscoveringExpanderAlloc: no free expanders pid %d!!!\n", onePortContext->id)); 4685285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4686285809Sscottl return agNULL; 4687285809Sscottl } 4688285809Sscottl else 4689285809Sscottl { 4690285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4691285809Sscottl } 4692285809Sscottl 4693285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4694285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(dmAllShared->freeExpanderList)); 4695285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4696285809Sscottl 4697285809Sscottl oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4698285809Sscottl } 4699285809Sscottl 4700285809Sscottl if (oneExpander != agNULL) 4701285809Sscottl { 4702285809Sscottl DM_DBG1(("dmDiscoveringExpanderAlloc: pid %d exp id %d \n", onePortContext->id, oneExpander->id)); 4703285809Sscottl 4704285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4705285809Sscottl DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 4706285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4707285809Sscottl 4708285809Sscottl oneExpander->dmDevice = oneDeviceData; 4709285809Sscottl oneExpander->dmUpStreamExpander = agNULL; 4710285809Sscottl oneExpander->dmCurrentDownStreamExpander = agNULL; 4711285809Sscottl oneExpander->dmReturnginExpander = agNULL; 4712285809Sscottl oneExpander->hasUpStreamDevice = agFALSE; 4713285809Sscottl oneExpander->numOfUpStreamPhys = 0; 4714285809Sscottl oneExpander->currentUpStreamPhyIndex = 0; 4715285809Sscottl oneExpander->discoveringPhyId = 0; 4716285809Sscottl oneExpander->underDiscovering = agFALSE; 4717285809Sscottl dm_memset( &(oneExpander->currentIndex), 0, sizeof(oneExpander->currentIndex)); 4718285809Sscottl 4719285809Sscottl oneDeviceData->dmExpander = oneExpander; 4720285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 4721285809Sscottl DM_DBG3(("dmDiscoveringExpanderAlloc: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 4722285809Sscottl 4723285809Sscottl } 4724285809Sscottl 4725285809Sscottl return oneExpander; 4726285809Sscottl} 4727285809Sscottl 4728285809SscottlosGLOBAL void 4729285809SscottldmDiscoveringExpanderAdd( 4730285809Sscottl dmRoot_t *dmRoot, 4731285809Sscottl dmIntPortContext_t *onePortContext, 4732285809Sscottl dmExpander_t *oneExpander 4733285809Sscottl ) 4734285809Sscottl{ 4735285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: start\n")); 4736285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: expander id %d\n", oneExpander->id)); 4737285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4738285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4739285809Sscottl 4740285809Sscottl if (onePortContext->valid == agFALSE) 4741285809Sscottl { 4742285809Sscottl DM_DBG1(("dmDiscoveringExpanderAdd: invalid port!!!\n")); 4743285809Sscottl return; 4744285809Sscottl } 4745285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4746285809Sscottl { 4747285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: UPSTREAM\n")); 4748285809Sscottl } 4749285809Sscottl else if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4750285809Sscottl { 4751285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: DOWNSTREAM\n")); 4752285809Sscottl } 4753285809Sscottl else 4754285809Sscottl { 4755285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: status %d\n", onePortContext->discovery.status)); 4756285809Sscottl } 4757285809Sscottl 4758285809Sscottl if ( oneExpander->underDiscovering == agFALSE) 4759285809Sscottl { 4760285809Sscottl DM_DBG3(("dmDiscoveringExpanderAdd: ADDED \n")); 4761285809Sscottl 4762285809Sscottl oneExpander->underDiscovering = agTRUE; 4763285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4764285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 4765285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4766285809Sscottl } 4767285809Sscottl 4768285809Sscottl return; 4769285809Sscottl} 4770285809Sscottl 4771285809SscottlosGLOBAL dmExpander_t * 4772285809SscottldmFindConfigurableExp( 4773285809Sscottl dmRoot_t *dmRoot, 4774285809Sscottl dmIntPortContext_t *onePortContext, 4775285809Sscottl dmExpander_t *oneExpander 4776285809Sscottl ) 4777285809Sscottl{ 4778285809Sscottl dmExpander_t *tempExpander; 4779285809Sscottl dmIntPortContext_t *tmpOnePortContext = onePortContext; 4780285809Sscottl dmExpander_t *ret = agNULL; 4781285809Sscottl DM_DBG3(("dmFindConfigurableExp: start\n")); 4782285809Sscottl 4783285809Sscottl if (oneExpander == agNULL) 4784285809Sscottl { 4785285809Sscottl DM_DBG3(("dmFindConfigurableExp: NULL expander\n")); 4786285809Sscottl return agNULL; 4787285809Sscottl } 4788285809Sscottl 4789285809Sscottl DM_DBG3(("dmFindConfigurableExp: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4790285809Sscottl DM_DBG3(("dmFindConfigurableExp: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4791285809Sscottl 4792285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4793285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4794285809Sscottl { 4795285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4796285809Sscottl DM_DBG3(("dmFindConfigurableExp: empty UpdiscoveringExpanderList\n")); 4797285809Sscottl return agNULL; 4798285809Sscottl } 4799285809Sscottl else 4800285809Sscottl { 4801285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4802285809Sscottl } 4803285809Sscottl tempExpander = oneExpander->dmUpStreamExpander; 4804285809Sscottl while (tempExpander) 4805285809Sscottl { 4806285809Sscottl DM_DBG3(("dmFindConfigurableExp: loop exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4807285809Sscottl DM_DBG3(("dmFindConfigurableExp: loop exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4808285809Sscottl if (tempExpander->configRouteTable) 4809285809Sscottl { 4810285809Sscottl DM_DBG3(("dmFindConfigurableExp: found configurable expander\n")); 4811285809Sscottl ret = tempExpander; 4812285809Sscottl break; 4813285809Sscottl } 4814285809Sscottl tempExpander = tempExpander->dmUpStreamExpander; 4815285809Sscottl } 4816285809Sscottl 4817285809Sscottl return ret; 4818285809Sscottl} 4819285809Sscottl 4820285809SscottlosGLOBAL bit32 4821285809SscottldmDuplicateConfigSASAddr( 4822285809Sscottl dmRoot_t *dmRoot, 4823285809Sscottl dmExpander_t *oneExpander, 4824285809Sscottl bit32 configSASAddressHi, 4825285809Sscottl bit32 configSASAddressLo 4826285809Sscottl ) 4827285809Sscottl{ 4828285809Sscottl bit32 i; 4829285809Sscottl bit32 ret = agFALSE; 4830285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: start\n")); 4831285809Sscottl 4832285809Sscottl if (oneExpander == agNULL) 4833285809Sscottl { 4834285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: NULL expander\n")); 4835285809Sscottl return agTRUE; 4836285809Sscottl } 4837285809Sscottl 4838285809Sscottl if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi && 4839285809Sscottl oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo 4840285809Sscottl ) 4841285809Sscottl { 4842285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: unnecessary\n")); 4843285809Sscottl return agTRUE; 4844285809Sscottl } 4845285809Sscottl 4846285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4847285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4848285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressHi 0x%08x\n", configSASAddressHi)); 4849285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressLo 0x%08x\n", configSASAddressLo)); 4850285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4851285809Sscottl for(i=0;i<oneExpander->configSASAddrTableIndex;i++) 4852285809Sscottl { 4853285809Sscottl if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi && 4854285809Sscottl oneExpander->configSASAddressLoTable[i] == configSASAddressLo 4855285809Sscottl ) 4856285809Sscottl { 4857285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: FOUND\n")); 4858285809Sscottl ret = agTRUE; 4859285809Sscottl break; 4860285809Sscottl } 4861285809Sscottl } 4862285809Sscottl /* new one; let's add it */ 4863285809Sscottl if (ret == agFALSE) 4864285809Sscottl { 4865285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: adding configSAS Addr\n")); 4866285809Sscottl DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4867285809Sscottl oneExpander->configSASAddressHiTable[oneExpander->configSASAddrTableIndex] = configSASAddressHi; 4868285809Sscottl oneExpander->configSASAddressLoTable[oneExpander->configSASAddrTableIndex] = configSASAddressLo; 4869285809Sscottl oneExpander->configSASAddrTableIndex++; 4870285809Sscottl } 4871285809Sscottl 4872285809Sscottl return ret; 4873285809Sscottl} 4874285809Sscottl 4875285809SscottlosGLOBAL bit16 4876285809SscottldmFindCurrentDownStreamPhyIndex( 4877285809Sscottl dmRoot_t *dmRoot, 4878285809Sscottl dmExpander_t *oneExpander 4879285809Sscottl ) 4880285809Sscottl{ 4881285809Sscottl dmExpander_t *DownStreamExpander; 4882285809Sscottl bit16 index = 0; 4883285809Sscottl bit16 i; 4884285809Sscottl bit8 phyId = 0; 4885285809Sscottl 4886285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: start\n")); 4887285809Sscottl 4888285809Sscottl if (oneExpander == agNULL) 4889285809Sscottl { 4890285809Sscottl DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, oneExpander is NULL!!!\n")); 4891285809Sscottl return 0; 4892285809Sscottl } 4893285809Sscottl 4894285809Sscottl DownStreamExpander = oneExpander->dmCurrentDownStreamExpander; 4895285809Sscottl 4896285809Sscottl if (DownStreamExpander == agNULL) 4897285809Sscottl { 4898285809Sscottl DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, DownStreamExpander is NULL!!!\n")); 4899285809Sscottl return 0; 4900285809Sscottl } 4901285809Sscottl 4902285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4903285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4904285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 4905285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 4906285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: numOfDownStreamPhys %d\n", oneExpander->numOfDownStreamPhys)); 4907285809Sscottl 4908285809Sscottl phyId = DownStreamExpander->upStreamPhys[0]; 4909285809Sscottl 4910285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: phyId %d\n", phyId)); 4911285809Sscottl 4912285809Sscottl for (i=0; i<oneExpander->numOfDownStreamPhys;i++) 4913285809Sscottl { 4914285809Sscottl if (oneExpander->downStreamPhys[i] == phyId) 4915285809Sscottl { 4916285809Sscottl index = i; 4917285809Sscottl break; 4918285809Sscottl } 4919285809Sscottl } 4920285809Sscottl DM_DBG3(("dmFindCurrentDownStreamPhyIndex: index %d\n", index)); 4921285809Sscottl return index; 4922285809Sscottl} 4923285809Sscottl 4924285809SscottlosGLOBAL bit32 4925285809SscottldmFindDiscoveringExpander( 4926285809Sscottl dmRoot_t *dmRoot, 4927285809Sscottl dmIntPortContext_t *onePortContext, 4928285809Sscottl dmExpander_t *oneExpander 4929285809Sscottl ) 4930285809Sscottl{ 4931285809Sscottl dmList_t *ExpanderList; 4932285809Sscottl dmExpander_t *tempExpander; 4933285809Sscottl dmIntPortContext_t *tmpOnePortContext = onePortContext; 4934285809Sscottl bit32 ret = agFALSE; 4935285809Sscottl 4936285809Sscottl 4937285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: start\n")); 4938285809Sscottl 4939285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4940285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4941285809Sscottl 4942285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4943285809Sscottl { 4944285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: empty discoveringExpanderList\n")); 4945285809Sscottl return ret; 4946285809Sscottl } 4947285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 4948285809Sscottl while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 4949285809Sscottl { 4950285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4951285809Sscottl if (tempExpander == oneExpander) 4952285809Sscottl { 4953285809Sscottl if (tempExpander != agNULL) 4954285809Sscottl { 4955285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: match, expander id %d\n", tempExpander->id)); 4956285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4957285809Sscottl DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4958285809Sscottl } 4959285809Sscottl ret = agTRUE; 4960285809Sscottl break; 4961285809Sscottl } 4962285809Sscottl 4963285809Sscottl ExpanderList = ExpanderList->flink; 4964285809Sscottl } 4965285809Sscottl 4966285809Sscottl 4967285809Sscottl return ret; 4968285809Sscottl} 4969285809Sscottl 4970285809Sscottl 4971285809SscottlosGLOBAL void 4972285809SscottldmDiscoveringExpanderRemove( 4973285809Sscottl dmRoot_t *dmRoot, 4974285809Sscottl dmIntPortContext_t *onePortContext, 4975285809Sscottl dmExpander_t *oneExpander 4976285809Sscottl ) 4977285809Sscottl{ 4978285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4979285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4980285809Sscottl 4981285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: start\n")); 4982285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: expander id %d\n", oneExpander->id)); 4983285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4984285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4985285809Sscottl 4986285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: BEFORE\n")); 4987285809Sscottl dmDumpAllExp(dmRoot, onePortContext, oneExpander); 4988285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 4989285809Sscottl dmDumpAllFreeExp(dmRoot); 4990285809Sscottl 4991285809Sscottl // if is temporary till smp problem is fixed 4992285809Sscottl if (dmFindDiscoveringExpander(dmRoot, onePortContext, oneExpander) == agTRUE) 4993285809Sscottl { 4994285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: oneDeviceData %p did %d\n", oneExpander->dmDevice, oneExpander->dmDevice->id)); 4995285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 4996285809Sscottl 4997285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 4998285809Sscottl { 4999285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: before !!! wrong !!!\n")); 5000285809Sscottl } 5001285809Sscottl oneExpander->underDiscovering = agFALSE; 5002285809Sscottl oneExpander->discoveringPhyId = 0; 5003285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5004285809Sscottl DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 5005285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5006285809Sscottl 5007285809Sscottl if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 5008285809Sscottl { 5009285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: DISCOVERY_UP_STREAM\n")); 5010285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5011285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->upNode), &(onePortContext->discovery.UpdiscoveringExpanderList)); 5012285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5013285809Sscottl onePortContext->discovery.NumOfUpExp++; 5014285809Sscottl } 5015285809Sscottl else 5016285809Sscottl { 5017285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: Status %d\n", onePortContext->discovery.status)); 5018285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5019285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->mainExpanderList)); 5020285809Sscottl// DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 5021285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5022285809Sscottl } 5023285809Sscottl // error checking 5024285809Sscottl if (oneExpander != oneExpander->dmDevice->dmExpander) 5025285809Sscottl { 5026285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: after !!! wrong !!!\n")); 5027285809Sscottl } 5028285809Sscottl 5029285809Sscottl } //end temp if 5030285809Sscottl else 5031285809Sscottl { 5032285809Sscottl DM_DBG1(("dmDiscoveringExpanderRemove: !!! problem !!!\n")); 5033285809Sscottl } 5034285809Sscottl 5035285809Sscottl DM_DBG3(("dmDiscoveringExpanderRemove: AFTER\n")); 5036285809Sscottl 5037285809Sscottl dmDumpAllExp(dmRoot, onePortContext, oneExpander); 5038285809Sscottl dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 5039285809Sscottl dmDumpAllFreeExp(dmRoot); 5040285809Sscottl 5041285809Sscottl return; 5042285809Sscottl} 5043285809Sscottl 5044285809Sscottl/* 5045285809Sscottl returns an expander with sasAddrLo, sasAddrHi from dmAllShared->mainExpanderList 5046285809Sscottl*/ 5047285809SscottlosGLOBAL dmExpander_t * 5048285809SscottldmExpMainListFind( 5049285809Sscottl dmRoot_t *dmRoot, 5050285809Sscottl dmIntPortContext_t *onePortContext, 5051285809Sscottl bit32 sasAddrHi, 5052285809Sscottl bit32 sasAddrLo 5053285809Sscottl ) 5054285809Sscottl{ 5055285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5056285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5057285809Sscottl dmList_t *ExpanderList; 5058285809Sscottl dmExpander_t *tempExpander; 5059285809Sscottl 5060285809Sscottl DM_DBG3(("dmExpMainListFind: start\n")); 5061285809Sscottl 5062285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5063285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 5064285809Sscottl { 5065285809Sscottl DM_DBG1(("dmExpMainListFind: empty mainExpanderList\n")); 5066285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5067285809Sscottl return agNULL; 5068285809Sscottl } 5069285809Sscottl else 5070285809Sscottl { 5071285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5072285809Sscottl } 5073285809Sscottl ExpanderList = dmAllShared->mainExpanderList.flink; 5074285809Sscottl while (ExpanderList != &(dmAllShared->mainExpanderList)) 5075285809Sscottl { 5076285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5077285809Sscottl if (tempExpander == agNULL) 5078285809Sscottl { 5079285809Sscottl DM_DBG1(("dmExpMainListFind: tempExpander is NULL!!!\n")); 5080285809Sscottl return agNULL; 5081285809Sscottl } 5082285809Sscottl DM_DBG3(("dmExpMainListFind: expander id %d\n", tempExpander->id)); 5083285809Sscottl DM_DBG3(("dmExpMainListFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5084285809Sscottl DM_DBG3(("dmExpMainListFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5085285809Sscottl if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5086285809Sscottl (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5087285809Sscottl (tempExpander->dmDevice->dmPortContext == onePortContext) 5088285809Sscottl ) 5089285809Sscottl { 5090285809Sscottl DM_DBG3(("dmExpMainListFind: found expander id %d\n", tempExpander->id)); 5091285809Sscottl DM_DBG3(("dmExpMainListFind: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5092285809Sscottl DM_DBG3(("dmExpMainListFind: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5093285809Sscottl return tempExpander; 5094285809Sscottl } 5095285809Sscottl ExpanderList = ExpanderList->flink; 5096285809Sscottl } 5097285809Sscottl return agNULL; 5098285809Sscottl 5099285809Sscottl} 5100285809Sscottl 5101285809Sscottl/* 5102285809Sscottl returns an expander with sasAddrLo, sasAddrHi from discoveringExpanderList 5103285809Sscottl*/ 5104285809SscottlosGLOBAL dmExpander_t * 5105285809SscottldmExpFind( 5106285809Sscottl dmRoot_t *dmRoot, 5107285809Sscottl dmIntPortContext_t *onePortContext, 5108285809Sscottl bit32 sasAddrHi, 5109285809Sscottl bit32 sasAddrLo 5110285809Sscottl ) 5111285809Sscottl{ 5112285809Sscottl dmList_t *ExpanderList; 5113285809Sscottl dmExpander_t *tempExpander; 5114285809Sscottl dmIntPortContext_t *tmpOnePortContext = onePortContext; 5115285809Sscottl DM_DBG3(("dmExpFind: start\n")); 5116285809Sscottl 5117285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5118285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5119285809Sscottl { 5120285809Sscottl DM_DBG3(("dmExpFind tdsaDumpAllExp: empty discoveringExpanderList\n")); 5121285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5122285809Sscottl return agNULL; 5123285809Sscottl } 5124285809Sscottl else 5125285809Sscottl { 5126285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5127285809Sscottl } 5128285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5129285809Sscottl while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5130285809Sscottl { 5131285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5132285809Sscottl if (tempExpander == agNULL) 5133285809Sscottl { 5134285809Sscottl DM_DBG1(("dmExpFind: tempExpander is NULL!!!\n")); 5135285809Sscottl return agNULL; 5136285809Sscottl } 5137285809Sscottl DM_DBG3(("dmExpFind: expander id %d\n", tempExpander->id)); 5138285809Sscottl DM_DBG3(("dmExpFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5139285809Sscottl DM_DBG3(("dmExpFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5140285809Sscottl if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5141285809Sscottl (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5142285809Sscottl (tempExpander->dmDevice->dmPortContext == onePortContext) 5143285809Sscottl ) 5144285809Sscottl { 5145285809Sscottl DM_DBG3(("dmExpFind: found\n")); 5146285809Sscottl return tempExpander; 5147285809Sscottl } 5148285809Sscottl ExpanderList = ExpanderList->flink; 5149285809Sscottl } 5150285809Sscottl return agNULL; 5151285809Sscottl} 5152285809Sscottl 5153285809SscottlosGLOBAL bit32 5154285809SscottldmDiscoverCheck( 5155285809Sscottl dmRoot_t *dmRoot, 5156285809Sscottl dmIntPortContext_t *onePortContext 5157285809Sscottl ) 5158285809Sscottl{ 5159285809Sscottl DM_DBG3(("dmDiscoverCheck: start\n")); 5160285809Sscottl 5161285809Sscottl if (onePortContext == agNULL) 5162285809Sscottl { 5163285809Sscottl DM_DBG1(("dmDiscoverCheck: onePortContext is NULL!!!\n")); 5164285809Sscottl return agTRUE; 5165285809Sscottl } 5166285809Sscottl if (onePortContext->valid == agFALSE) 5167285809Sscottl { 5168285809Sscottl DM_DBG1(("dmDiscoverCheck: invalid port!!!\n")); 5169285809Sscottl return agTRUE; 5170285809Sscottl } 5171285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5172285809Sscottl onePortContext->discovery.status == DISCOVERY_SAS_DONE 5173285809Sscottl ) 5174285809Sscottl { 5175285809Sscottl DM_DBG1(("dmDiscoverCheck: aborted discovery!!!\n")); 5176285809Sscottl tddmDiscoverCB( 5177285809Sscottl dmRoot, 5178285809Sscottl onePortContext->dmPortContext, 5179285809Sscottl dmDiscAborted 5180285809Sscottl ); 5181285809Sscottl return agTRUE; 5182285809Sscottl } 5183285809Sscottl 5184285809Sscottl return agFALSE; 5185285809Sscottl} 5186285809Sscottl 5187285809Sscottl/* ??? needs to handle pending SMPs 5188285809Sscottl move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList 5189285809Sscottl*/ 5190285809SscottlosGLOBAL void 5191285809SscottldmDiscoverAbort( 5192285809Sscottl dmRoot_t *dmRoot, 5193285809Sscottl dmIntPortContext_t *onePortContext 5194285809Sscottl ) 5195285809Sscottl{ 5196285809Sscottl DM_DBG1(("dmDiscoverAbort: start\n")); 5197285809Sscottl 5198285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5199285809Sscottl onePortContext->discovery.status == DISCOVERY_SAS_DONE) 5200285809Sscottl { 5201285809Sscottl DM_DBG1(("dmDiscoverAbort: not allowed case!!! onePortContext->DiscoveryState 0x%x onePortContext->discovery.status 0x%x\n", 5202285809Sscottl onePortContext->DiscoveryState, onePortContext->discovery.status)); 5203285809Sscottl return; 5204285809Sscottl } 5205285809Sscottl 5206285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5207285809Sscottl onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5208285809Sscottl 5209285809Sscottl /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5210285809Sscottl dmCleanAllExp(dmRoot, onePortContext); 5211285809Sscottl 5212285809Sscottl 5213285809Sscottl return; 5214285809Sscottl 5215285809Sscottl 5216285809Sscottl} 5217285809Sscottl 5218285809Sscottl/* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5219285809SscottlosGLOBAL void 5220285809SscottldmCleanAllExp( 5221285809Sscottl dmRoot_t *dmRoot, 5222285809Sscottl dmIntPortContext_t *onePortContext 5223285809Sscottl ) 5224285809Sscottl{ 5225285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5226285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5227285809Sscottl dmList_t *ExpanderList; 5228285809Sscottl dmExpander_t *tempExpander; 5229285809Sscottl dmExpander_t *oneExpander = agNULL; 5230285809Sscottl dmIntPortContext_t *tmpOnePortContext = onePortContext; 5231285809Sscottl 5232285809Sscottl DM_DBG3(("dmCleanAllExp: start\n")); 5233285809Sscottl DM_DBG3(("dmCleanAllExp: pid %d\n", onePortContext->id)); 5234285809Sscottl 5235285809Sscottl DM_DBG3(("dmCleanAllExp: before all clean up\n")); 5236285809Sscottl dmDumpAllFreeExp(dmRoot); 5237285809Sscottl 5238285809Sscottl /* clean up UpdiscoveringExpanderList*/ 5239285809Sscottl DM_DBG3(("dmCleanAllExp: clean discoveringExpanderList\n")); 5240285809Sscottl if (!DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5241285809Sscottl { 5242285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5243285809Sscottl while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5244285809Sscottl { 5245285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5246285809Sscottl if (tempExpander == agNULL) 5247285809Sscottl { 5248285809Sscottl DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5249285809Sscottl return; 5250285809Sscottl } 5251285809Sscottl DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5252285809Sscottl DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5253285809Sscottl DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5254285809Sscottl 5255285809Sscottl oneExpander = dmExpMainListFind(dmRoot, 5256285809Sscottl tmpOnePortContext, 5257285809Sscottl tempExpander->dmDevice->SASAddressID.sasAddressHi, 5258285809Sscottl tempExpander->dmDevice->SASAddressID.sasAddressLo); 5259285809Sscottl if (oneExpander == agNULL) 5260285809Sscottl { 5261285809Sscottl DM_DBG3(("dmCleanAllExp: moving\n")); 5262285809Sscottl DM_DBG3(("dmCleanAllExp: moving, exp id %d\n", tempExpander->id)); 5263285809Sscottl /* putting back to the free pool */ 5264285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5265285809Sscottl DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 5266285809Sscottl// DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 5267285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5268285809Sscottl 5269285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5270285809Sscottl { 5271285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5272285809Sscottl break; 5273285809Sscottl } 5274285809Sscottl else 5275285809Sscottl { 5276285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5277285809Sscottl } 5278285809Sscottl ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5279285809Sscottl } 5280285809Sscottl else 5281285809Sscottl { 5282285809Sscottl DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5283285809Sscottl ExpanderList = ExpanderList->flink; 5284285809Sscottl } 5285285809Sscottl } 5286285809Sscottl } 5287285809Sscottl else 5288285809Sscottl { 5289285809Sscottl DM_DBG3(("dmCleanAllExp: empty discoveringExpanderList\n")); 5290285809Sscottl } 5291285809Sscottl 5292285809Sscottl /* reset discoveringExpanderList */ 5293285809Sscottl DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.discoveringExpanderList)); 5294285809Sscottl 5295285809Sscottl /* clean up UpdiscoveringExpanderList*/ 5296285809Sscottl DM_DBG3(("dmCleanAllExp: clean UpdiscoveringExpanderList\n")); 5297285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5298285809Sscottl { 5299285809Sscottl DM_DBG3(("dmCleanAllExp: empty UpdiscoveringExpanderList\n")); 5300285809Sscottl return; 5301285809Sscottl } 5302285809Sscottl ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5303285809Sscottl while (ExpanderList != &(tmpOnePortContext->discovery.UpdiscoveringExpanderList)) 5304285809Sscottl { 5305285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, upNode, ExpanderList); 5306285809Sscottl if (tempExpander == agNULL) 5307285809Sscottl { 5308285809Sscottl DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5309285809Sscottl return; 5310285809Sscottl } 5311285809Sscottl DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5312285809Sscottl DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5313285809Sscottl DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5314285809Sscottl oneExpander = dmExpMainListFind(dmRoot, 5315285809Sscottl tmpOnePortContext, 5316285809Sscottl tempExpander->dmDevice->SASAddressID.sasAddressHi, 5317285809Sscottl tempExpander->dmDevice->SASAddressID.sasAddressLo); 5318285809Sscottl if (oneExpander == agNULL) 5319285809Sscottl { 5320285809Sscottl DM_DBG3(("dmCleanAllExp: moving\n")); 5321285809Sscottl DM_DBG3(("dmCleanAllExp: moving exp id %d\n", tempExpander->id)); 5322285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5323285809Sscottl DMLIST_DEQUEUE_THIS(&(tempExpander->upNode)); 5324285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5325285809Sscottl 5326285809Sscottl if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5327285809Sscottl { 5328285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5329285809Sscottl break; 5330285809Sscottl } 5331285809Sscottl else 5332285809Sscottl { 5333285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5334285809Sscottl } 5335285809Sscottl ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5336285809Sscottl } 5337285809Sscottl else 5338285809Sscottl { 5339285809Sscottl DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5340285809Sscottl ExpanderList = ExpanderList->flink; 5341285809Sscottl } 5342285809Sscottl } 5343285809Sscottl 5344285809Sscottl /* reset UpdiscoveringExpanderList */ 5345285809Sscottl DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList)); 5346285809Sscottl 5347285809Sscottl DM_DBG3(("dmCleanAllExp: after all clean up\n")); 5348285809Sscottl dmDumpAllFreeExp(dmRoot); 5349285809Sscottl 5350285809Sscottl return; 5351285809Sscottl} 5352285809Sscottl 5353285809SscottlosGLOBAL void 5354285809SscottldmInternalRemovals( 5355285809Sscottl dmRoot_t *dmRoot, 5356285809Sscottl dmIntPortContext_t *onePortContext 5357285809Sscottl ) 5358285809Sscottl{ 5359285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5360285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5361285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 5362285809Sscottl dmList_t *DeviceListList; 5363285809Sscottl 5364285809Sscottl 5365285809Sscottl DM_DBG3(("dmInternalRemovals: start\n")); 5366285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5367285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5368285809Sscottl { 5369285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5370285809Sscottl DM_DBG3(("dmInternalRemovals: empty device list\n")); 5371285809Sscottl return; 5372285809Sscottl } 5373285809Sscottl else 5374285809Sscottl { 5375285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5376285809Sscottl } 5377285809Sscottl 5378285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 5379285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 5380285809Sscottl { 5381285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5382285809Sscottl if (oneDeviceData == agNULL) 5383285809Sscottl { 5384285809Sscottl DM_DBG1(("dmInternalRemovals: oneDeviceData is NULL!!!\n")); 5385285809Sscottl return; 5386285809Sscottl } 5387285809Sscottl DM_DBG3(("dmInternalRemovals: loop did %d\n", oneDeviceData->id)); 5388285809Sscottl DM_DBG3(("dmInternalRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5389285809Sscottl DM_DBG3(("dmInternalRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5390285809Sscottl DM_DBG3(("dmInternalRemovals: valid %d\n", oneDeviceData->valid)); 5391285809Sscottl DM_DBG3(("dmInternalRemovals: valid2 %d\n", oneDeviceData->valid2)); 5392285809Sscottl DM_DBG3(("dmInternalRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5393285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 5394285809Sscottl { 5395285809Sscottl DM_DBG3(("dmInternalRemovals: right portcontext pid %d\n", onePortContext->id)); 5396285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 5397285809Sscottl { 5398285809Sscottl DM_DBG3(("dmInternalRemovals: incremental discovery\n")); 5399285809Sscottl oneDeviceData->valid2 = agFALSE; 5400285809Sscottl } 5401285809Sscottl else 5402285809Sscottl { 5403285809Sscottl DM_DBG3(("dmInternalRemovals: full discovery\n")); 5404285809Sscottl oneDeviceData->valid = agFALSE; 5405285809Sscottl } 5406285809Sscottl DeviceListList = DeviceListList->flink; 5407285809Sscottl } 5408285809Sscottl else 5409285809Sscottl { 5410285809Sscottl if (oneDeviceData->dmPortContext != agNULL) 5411285809Sscottl { 5412285809Sscottl DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5413285809Sscottl } 5414285809Sscottl else 5415285809Sscottl { 5416285809Sscottl DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5417285809Sscottl } 5418285809Sscottl DeviceListList = DeviceListList->flink; 5419285809Sscottl } 5420285809Sscottl } 5421285809Sscottl 5422285809Sscottl 5423285809Sscottl return; 5424285809Sscottl} 5425285809Sscottl 5426285809SscottlosGLOBAL void 5427285809SscottldmDiscoveryResetProcessed( 5428285809Sscottl dmRoot_t *dmRoot, 5429285809Sscottl dmIntPortContext_t *onePortContext 5430285809Sscottl ) 5431285809Sscottl{ 5432285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5433285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5434285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 5435285809Sscottl dmList_t *DeviceListList; 5436285809Sscottl 5437285809Sscottl DM_DBG3(("dmDiscoveryResetProcessed: start\n")); 5438285809Sscottl 5439285809Sscottl /* reinitialize the device data belonging to this portcontext */ 5440285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 5441285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 5442285809Sscottl { 5443285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5444285809Sscottl if (oneDeviceData == agNULL) 5445285809Sscottl { 5446285809Sscottl DM_DBG1(("dmDiscoveryResetProcessed: oneDeviceData is NULL!!!\n")); 5447285809Sscottl return; 5448285809Sscottl } 5449285809Sscottl DM_DBG3(("dmDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id)); 5450285809Sscottl if (oneDeviceData->dmPortContext == onePortContext) 5451285809Sscottl { 5452285809Sscottl DM_DBG3(("dmDiscoveryResetProcessed: resetting procssed flag\n")); 5453285809Sscottl oneDeviceData->processed = agFALSE; 5454285809Sscottl } 5455285809Sscottl DeviceListList = DeviceListList->flink; 5456285809Sscottl } 5457285809Sscottl 5458285809Sscottl return; 5459285809Sscottl} 5460285809Sscottl 5461285809Sscottl/* 5462285809Sscottl calls 5463285809SscottlosGLOBAL void 5464285809SscottltddmDiscoverCB( 5465285809Sscottl dmRoot_t *dmRoot, 5466285809Sscottl dmPortContext_t *dmPortContext, 5467285809Sscottl bit32 eventStatus 5468285809Sscottl ) 5469285809Sscottl 5470285809Sscottl*/ 5471285809SscottlosGLOBAL void 5472285809SscottldmDiscoverDone( 5473285809Sscottl dmRoot_t *dmRoot, 5474285809Sscottl dmIntPortContext_t *onePortContext, 5475285809Sscottl bit32 flag 5476285809Sscottl ) 5477285809Sscottl{ 5478285809Sscottl 5479285809Sscottl DM_DBG3(("dmDiscoverDone: start\n")); 5480285809Sscottl DM_DBG3(("dmDiscoverDone: pid %d\n", onePortContext->id)); 5481285809Sscottl 5482285809Sscottl /* Set discovery status */ 5483285809Sscottl onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5484285809Sscottl 5485285809Sscottl 5486285809Sscottl /* clean up expanders data strucures; move to free exp when device is cleaned */ 5487285809Sscottl dmCleanAllExp(dmRoot, onePortContext); 5488285809Sscottl 5489285809Sscottl dmDumpAllMainExp(dmRoot, onePortContext); 5490285809Sscottl 5491285809Sscottl dmDiscoveryResetProcessed(dmRoot, onePortContext); 5492285809Sscottl 5493285809Sscottl dmDiscoveryDumpMCN(dmRoot, onePortContext); 5494285809Sscottl 5495285809Sscottl if (onePortContext->discovery.SeenBC == agTRUE) 5496285809Sscottl { 5497285809Sscottl DM_DBG3(("dmDiscoverDone: broadcast change; discover again\n")); 5498285809Sscottl dmDiscoveryResetMCN(dmRoot, onePortContext); 5499285809Sscottl 5500285809Sscottl dmInternalRemovals(dmRoot, onePortContext); 5501285809Sscottl 5502285809Sscottl /* processed broadcast change */ 5503285809Sscottl onePortContext->discovery.SeenBC = agFALSE; 5504285809Sscottl if (onePortContext->discovery.ResetTriggerred == agTRUE) 5505285809Sscottl { 5506285809Sscottl DM_DBG3(("dmDiscoverDone: dmBCTimer\n")); 5507285809Sscottl dmBCTimer(dmRoot, onePortContext); 5508285809Sscottl } 5509285809Sscottl else 5510285809Sscottl { 5511285809Sscottl 5512285809Sscottl dmIncrementalDiscover(dmRoot, onePortContext, agTRUE); 5513285809Sscottl } 5514285809Sscottl } 5515285809Sscottl else 5516285809Sscottl { 5517285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5518285809Sscottl 5519285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 5520285809Sscottl { 5521285809Sscottl if (flag == DM_RC_SUCCESS) 5522285809Sscottl { 5523285809Sscottl 5524285809Sscottl dmResetReported(dmRoot, 5525285809Sscottl onePortContext 5526285809Sscottl ); 5527285809Sscottl 5528285809Sscottl dmDiscoveryReportMCN(dmRoot, 5529285809Sscottl onePortContext 5530285809Sscottl ); 5531285809Sscottl 5532285809Sscottl 5533285809Sscottl /* call tddmDiscoverCB() */ 5534285809Sscottl tddmDiscoverCB( 5535285809Sscottl dmRoot, 5536285809Sscottl onePortContext->dmPortContext, 5537285809Sscottl dmDiscCompleted 5538285809Sscottl ); 5539285809Sscottl } 5540285809Sscottl else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5541285809Sscottl { 5542285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5543285809Sscottl DM_DBG1(("dmDiscoverDone: Error; clean up!!!\n")); 5544285809Sscottl 5545285809Sscottl dmDiscoveryInvalidateDevices(dmRoot, 5546285809Sscottl onePortContext 5547285809Sscottl ); 5548285809Sscottl 5549285809Sscottl tddmDiscoverCB( 5550285809Sscottl dmRoot, 5551285809Sscottl onePortContext->dmPortContext, 5552285809Sscottl dmDiscFailed 5553285809Sscottl ); 5554285809Sscottl } 5555285809Sscottl } 5556285809Sscottl else 5557285809Sscottl { 5558285809Sscottl if (flag == DM_RC_SUCCESS) 5559285809Sscottl { 5560285809Sscottl dmReportChanges(dmRoot, 5561285809Sscottl onePortContext 5562285809Sscottl ); 5563285809Sscottl dmDiscoveryReportMCN(dmRoot, 5564285809Sscottl onePortContext 5565285809Sscottl ); 5566285809Sscottl tddmDiscoverCB( 5567285809Sscottl dmRoot, 5568285809Sscottl onePortContext->dmPortContext, 5569285809Sscottl dmDiscCompleted 5570285809Sscottl ); 5571285809Sscottl } 5572285809Sscottl else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5573285809Sscottl { 5574285809Sscottl onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5575285809Sscottl dmDiscoveryInvalidateDevices(dmRoot, 5576285809Sscottl onePortContext 5577285809Sscottl ); 5578285809Sscottl 5579285809Sscottl tddmDiscoverCB( 5580285809Sscottl dmRoot, 5581285809Sscottl onePortContext->dmPortContext, 5582285809Sscottl dmDiscFailed 5583285809Sscottl ); 5584285809Sscottl } 5585285809Sscottl } 5586285809Sscottl } 5587285809Sscottl return; 5588285809Sscottl} 5589285809Sscottl 5590285809Sscottl/* called by dmDiscoveryErrorRemovals() or dmReportRemovals() on discovery failure */ 5591285809SscottlosGLOBAL void 5592285809SscottldmSubReportRemovals( 5593285809Sscottl dmRoot_t *dmRoot, 5594285809Sscottl dmIntPortContext_t *onePortContext, 5595285809Sscottl dmDeviceData_t *oneDeviceData, 5596285809Sscottl bit32 flag 5597285809Sscottl ) 5598285809Sscottl{ 5599285809Sscottl dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5600285809Sscottl DM_DBG3(("dmSubReportRemovals: start\n")); 5601285809Sscottl 5602285809Sscottl DM_DBG3(("dmSubReportRemovals: flag 0x%x\n", flag)); 5603285809Sscottl if (flag == dmDeviceRemoval) 5604285809Sscottl { 5605285809Sscottl oneDeviceData->registered = agFALSE; 5606285809Sscottl } 5607285809Sscottl 5608285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 5609285809Sscottl { 5610285809Sscottl DM_DBG3(("dmSubReportRemovals: attached expander case\n")); 5611285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5612285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5613285809Sscottl } 5614285809Sscottl else 5615285809Sscottl { 5616285809Sscottl DM_DBG3(("dmSubReportRemovals: NO attached expander case\n")); 5617285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5618285809Sscottl } 5619285809Sscottl 5620285809Sscottl 5621285809Sscottl /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5622285809Sscottl oneDeviceData->reported = agFALSE; 5623285809Sscottl return; 5624285809Sscottl} 5625285809Sscottl 5626285809Sscottl 5627285809Sscottl/* called by dmReportChanges() on discovery success */ 5628285809SscottlosGLOBAL void 5629285809SscottldmSubReportChanges( 5630285809Sscottl dmRoot_t *dmRoot, 5631285809Sscottl dmIntPortContext_t *onePortContext, 5632285809Sscottl dmDeviceData_t *oneDeviceData, 5633285809Sscottl bit32 flag 5634285809Sscottl ) 5635285809Sscottl{ 5636285809Sscottl dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5637285809Sscottl DM_DBG3(("dmSubReportChanges: start\n")); 5638285809Sscottl 5639285809Sscottl DM_DBG3(("dmSubReportChanges: flag 0x%x\n", flag)); 5640285809Sscottl if (flag == dmDeviceRemoval) 5641285809Sscottl { 5642285809Sscottl oneDeviceData->registered = agFALSE; 5643285809Sscottl } 5644285809Sscottl if (oneDeviceData->reported == agFALSE) 5645285809Sscottl { 5646285809Sscottl if (oneDeviceData->ExpDevice != agNULL) 5647285809Sscottl { 5648285809Sscottl DM_DBG3(("dmSubReportChanges: attached expander case\n")); 5649285809Sscottl oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5650285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5651285809Sscottl } 5652285809Sscottl else 5653285809Sscottl { 5654285809Sscottl DM_DBG3(("dmSubReportChanges: NO attached expander case\n")); 5655285809Sscottl tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5656285809Sscottl } 5657285809Sscottl } 5658285809Sscottl else 5659285809Sscottl { 5660285809Sscottl DM_DBG3(("dmSubReportChanges: skip; been reported\n")); 5661285809Sscottl } 5662285809Sscottl 5663285809Sscottl 5664285809Sscottl /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5665285809Sscottl oneDeviceData->reported = agFALSE; 5666285809Sscottl return; 5667285809Sscottl} 5668285809Sscottl 5669285809Sscottl/* 5670285809Sscottl should add or remove be reported per device??? 5671285809Sscottl*/ 5672285809SscottlosGLOBAL void 5673285809SscottldmReportChanges( 5674285809Sscottl dmRoot_t *dmRoot, 5675285809Sscottl dmIntPortContext_t *onePortContext 5676285809Sscottl ) 5677285809Sscottl{ 5678285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5679285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5680285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 5681285809Sscottl dmList_t *DeviceListList; 5682285809Sscottl bit32 added = agFALSE, removed = agFALSE; 5683285809Sscottl// dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5684285809Sscottl 5685285809Sscottl DM_DBG3(("dmReportChanges: start\n")); 5686285809Sscottl 5687285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5688285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5689285809Sscottl { 5690285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5691285809Sscottl DM_DBG3(("dmReportChanges: empty device list\n")); 5692285809Sscottl return; 5693285809Sscottl } 5694285809Sscottl else 5695285809Sscottl { 5696285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5697285809Sscottl } 5698285809Sscottl 5699285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 5700285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 5701285809Sscottl { 5702285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5703285809Sscottl if (oneDeviceData == agNULL) 5704285809Sscottl { 5705285809Sscottl DM_DBG1(("dmReportChanges: oneDeviceData is NULL!!!\n")); 5706285809Sscottl return; 5707285809Sscottl } 5708285809Sscottl DM_DBG3(("dmReportChanges: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5709285809Sscottl DM_DBG3(("dmReportChanges: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5710285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 5711285809Sscottl { 5712285809Sscottl DM_DBG3(("dmReportChanges: right portcontext\n")); 5713285809Sscottl if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5714285809Sscottl oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5715285809Sscottl ) 5716285809Sscottl { 5717285809Sscottl DM_DBG1(("dmReportChanges: keep, not reporting did 0x%x\n", oneDeviceData->id)); 5718285809Sscottl oneDeviceData->valid = agTRUE; 5719285809Sscottl oneDeviceData->valid2 = agFALSE; 5720285809Sscottl } 5721285809Sscottl else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) ) 5722285809Sscottl { 5723285809Sscottl DM_DBG3(("dmReportChanges: same\n")); 5724285809Sscottl /* reset valid bit */ 5725285809Sscottl oneDeviceData->valid = oneDeviceData->valid2; 5726285809Sscottl oneDeviceData->valid2 = agFALSE; 5727285809Sscottl dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceNoChange); 5728285809Sscottl } 5729285809Sscottl else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) ) 5730285809Sscottl { 5731285809Sscottl DM_DBG3(("dmReportChanges: removed\n")); 5732285809Sscottl removed = agTRUE; 5733285809Sscottl /* reset valid bit */ 5734285809Sscottl oneDeviceData->valid = oneDeviceData->valid2; 5735285809Sscottl oneDeviceData->valid2 = agFALSE; 5736285809Sscottl 5737285809Sscottl onePortContext->RegisteredDevNums--; 5738285809Sscottl dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5739285809Sscottl } 5740285809Sscottl else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) ) 5741285809Sscottl { 5742285809Sscottl DM_DBG3(("dmReportChanges: added\n")); 5743285809Sscottl added = agTRUE; 5744285809Sscottl /* reset valid bit */ 5745285809Sscottl oneDeviceData->valid = oneDeviceData->valid2; 5746285809Sscottl oneDeviceData->valid2 = agFALSE; 5747285809Sscottl dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceArrival); 5748285809Sscottl } 5749285809Sscottl else 5750285809Sscottl { 5751285809Sscottl DM_DBG3(("dmReportChanges: else\n")); 5752285809Sscottl } 5753285809Sscottl } 5754285809Sscottl else 5755285809Sscottl { 5756285809Sscottl DM_DBG3(("dmReportChanges: different portcontext\n")); 5757285809Sscottl } 5758285809Sscottl DeviceListList = DeviceListList->flink; 5759285809Sscottl } 5760285809Sscottl /* 5761285809Sscottl osGLOBAL void 5762285809SscottltddmReportDevice( 5763285809Sscottl dmRoot_t *dmRoot, 5764285809Sscottl dmPortContext_t *dmPortContext, 5765285809Sscottl dmDeviceInfo_t *dmDeviceInfo, 5766285809Sscottl dmDeviceInfo_t *dmExpDeviceInfo, 5767285809Sscottl bit32 flag 5768285809Sscottl 5769285809Sscottl ) 5770285809Sscottl 5771285809Sscottl */ 5772285809Sscottl 5773285809Sscottl /* arrival or removal at once */ 5774285809Sscottl if (added == agTRUE) 5775285809Sscottl { 5776285809Sscottl DM_DBG3(("dmReportChanges: added at the end\n")); 5777285809Sscottl#if 0 /* TBD */ 5778285809Sscottl ostiInitiatorEvent( 5779285809Sscottl tiRoot, 5780285809Sscottl onePortContext->tiPortalContext, 5781285809Sscottl agNULL, 5782285809Sscottl tiIntrEventTypeDeviceChange, 5783285809Sscottl tiDeviceArrival, 5784285809Sscottl agNULL 5785285809Sscottl ); 5786285809Sscottl#endif 5787285809Sscottl 5788285809Sscottl } 5789285809Sscottl if (removed == agTRUE) 5790285809Sscottl { 5791285809Sscottl DM_DBG3(("dmReportChanges: removed at the end\n")); 5792285809Sscottl#if 0 /* TBD */ 5793285809Sscottl ostiInitiatorEvent( 5794285809Sscottl tiRoot, 5795285809Sscottl onePortContext->tiPortalContext, 5796285809Sscottl agNULL, 5797285809Sscottl tiIntrEventTypeDeviceChange, 5798285809Sscottl tiDeviceRemoval, 5799285809Sscottl agNULL 5800285809Sscottl ); 5801285809Sscottl#endif 5802285809Sscottl } 5803285809Sscottl 5804285809Sscottl if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE) 5805285809Sscottl { 5806285809Sscottl DM_DBG3(("dmReportChanges: missed chance to report. forced to report OK\n")); 5807285809Sscottl onePortContext->discovery.forcedOK = agFALSE; 5808285809Sscottl#if 0 /* TBD */ 5809285809Sscottl ostiInitiatorEvent( 5810285809Sscottl tiRoot, 5811285809Sscottl onePortContext->tiPortalContext, 5812285809Sscottl agNULL, 5813285809Sscottl tiIntrEventTypeDiscovery, 5814285809Sscottl tiDiscOK, 5815285809Sscottl agNULL 5816285809Sscottl ); 5817285809Sscottl#endif 5818285809Sscottl } 5819285809Sscottl 5820285809Sscottl if (added == agFALSE && removed == agFALSE) 5821285809Sscottl { 5822285809Sscottl DM_DBG3(("dmReportChanges: the same\n")); 5823285809Sscottl } 5824285809Sscottl 5825285809Sscottl return; 5826285809Sscottl} 5827285809Sscottl 5828285809SscottlosGLOBAL void 5829285809SscottldmReportRemovals( 5830285809Sscottl dmRoot_t *dmRoot, 5831285809Sscottl dmIntPortContext_t *onePortContext, 5832285809Sscottl bit32 flag 5833285809Sscottl ) 5834285809Sscottl{ 5835285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5836285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5837285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 5838285809Sscottl dmList_t *DeviceListList; 5839285809Sscottl bit32 removed = agFALSE; 5840285809Sscottl 5841285809Sscottl DM_DBG1(("dmReportRemovals: start\n")); 5842285809Sscottl 5843285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5844285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5845285809Sscottl { 5846285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5847285809Sscottl DM_DBG3(("dmReportRemovals: empty device list\n")); 5848285809Sscottl return; 5849285809Sscottl } 5850285809Sscottl else 5851285809Sscottl { 5852285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5853285809Sscottl } 5854285809Sscottl 5855285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 5856285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 5857285809Sscottl { 5858285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5859285809Sscottl if (oneDeviceData == agNULL) 5860285809Sscottl { 5861285809Sscottl DM_DBG1(("dmReportRemovals: oneDeviceData is NULL!!!\n")); 5862285809Sscottl return; 5863285809Sscottl } 5864285809Sscottl DM_DBG3(("dmReportRemovals: loop did %d\n", oneDeviceData->id)); 5865285809Sscottl DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5866285809Sscottl DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5867285809Sscottl DM_DBG3(("dmReportRemovals: valid %d\n", oneDeviceData->valid)); 5868285809Sscottl DM_DBG3(("dmReportRemovals: valid2 %d\n", oneDeviceData->valid2)); 5869285809Sscottl DM_DBG3(("dmReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5870285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 5871285809Sscottl { 5872285809Sscottl DM_DBG3(("dmReportRemovals: right portcontext pid %d\n", onePortContext->id)); 5873285809Sscottl if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5874285809Sscottl oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5875285809Sscottl ) 5876285809Sscottl { 5877285809Sscottl DM_DBG1(("dmReportRemovals: keeping\n")); 5878285809Sscottl oneDeviceData->valid = agTRUE; 5879285809Sscottl oneDeviceData->valid2 = agFALSE; 5880285809Sscottl } 5881285809Sscottl else if (oneDeviceData->valid == agTRUE) 5882285809Sscottl { 5883285809Sscottl DM_DBG3(("dmReportRemovals: removing\n")); 5884285809Sscottl 5885285809Sscottl /* notify only reported devices to OS layer*/ 5886285809Sscottl if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || 5887285809Sscottl DEVICE_IS_STP_TARGET(oneDeviceData) || 5888285809Sscottl DEVICE_IS_SATA_DEVICE(oneDeviceData) 5889285809Sscottl ) 5890285809Sscottl { 5891285809Sscottl removed = agTRUE; 5892285809Sscottl } 5893285809Sscottl 5894285809Sscottl /* all targets except expanders */ 5895285809Sscottl DM_DBG3(("dmReportRemovals: did %d\n", oneDeviceData->id)); 5896285809Sscottl DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5897285809Sscottl DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5898285809Sscottl onePortContext->RegisteredDevNums--; 5899285809Sscottl dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5900285809Sscottl 5901285809Sscottl 5902285809Sscottl /* reset valid bit */ 5903285809Sscottl oneDeviceData->valid = agFALSE; 5904285809Sscottl oneDeviceData->valid2 = agFALSE; 5905285809Sscottl 5906285809Sscottl 5907285809Sscottl } 5908285809Sscottl /* called by port invalid case */ 5909285809Sscottl if (flag == agTRUE) 5910285809Sscottl { 5911285809Sscottl oneDeviceData->dmPortContext = agNULL; 5912285809Sscottl } 5913285809Sscottl DeviceListList = DeviceListList->flink; 5914285809Sscottl } 5915285809Sscottl else 5916285809Sscottl { 5917285809Sscottl if (oneDeviceData->dmPortContext != agNULL) 5918285809Sscottl { 5919285809Sscottl DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5920285809Sscottl } 5921285809Sscottl else 5922285809Sscottl { 5923285809Sscottl DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5924285809Sscottl } 5925285809Sscottl DeviceListList = DeviceListList->flink; 5926285809Sscottl } 5927285809Sscottl } 5928285809Sscottl 5929285809Sscottl if (removed == agTRUE) 5930285809Sscottl { 5931285809Sscottl DM_DBG3(("dmReportRemovals: removed at the end\n")); 5932285809Sscottl#if 0 /* TBD */ 5933285809Sscottl ostiInitiatorEvent( 5934285809Sscottl tiRoot, 5935285809Sscottl onePortContext->tiPortalContext, 5936285809Sscottl agNULL, 5937285809Sscottl tiIntrEventTypeDeviceChange, 5938285809Sscottl tiDeviceRemoval, 5939285809Sscottl agNULL 5940285809Sscottl ); 5941285809Sscottl#endif 5942285809Sscottl } 5943285809Sscottl 5944285809Sscottl return; 5945285809Sscottl} 5946285809Sscottl 5947285809SscottlosGLOBAL void 5948285809SscottldmResetReported( 5949285809Sscottl dmRoot_t *dmRoot, 5950285809Sscottl dmIntPortContext_t *onePortContext 5951285809Sscottl ) 5952285809Sscottl{ 5953285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5954285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5955285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 5956285809Sscottl dmList_t *DeviceListList; 5957285809Sscottl 5958285809Sscottl DM_DBG3(("dmResetReported: start\n")); 5959285809Sscottl 5960285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5961285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5962285809Sscottl { 5963285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5964285809Sscottl DM_DBG3(("dmResetReported: empty device list\n")); 5965285809Sscottl return; 5966285809Sscottl } 5967285809Sscottl else 5968285809Sscottl { 5969285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5970285809Sscottl } 5971285809Sscottl 5972285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 5973285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 5974285809Sscottl { 5975285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5976285809Sscottl if (oneDeviceData == agNULL) 5977285809Sscottl { 5978285809Sscottl DM_DBG1(("dmResetReported: oneDeviceData is NULL!!!\n")); 5979285809Sscottl return; 5980285809Sscottl } 5981285809Sscottl DM_DBG3(("dmResetReported: loop did %d\n", oneDeviceData->id)); 5982285809Sscottl DM_DBG3(("dmResetReported: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5983285809Sscottl DM_DBG3(("dmResetReported: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5984285809Sscottl DM_DBG3(("dmResetReported: valid %d\n", oneDeviceData->valid)); 5985285809Sscottl DM_DBG3(("dmResetReported: valid2 %d\n", oneDeviceData->valid2)); 5986285809Sscottl DM_DBG3(("dmResetReported: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5987285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 5988285809Sscottl { 5989285809Sscottl DM_DBG3(("dmResetReported: right portcontext pid %d\n", onePortContext->id)); 5990285809Sscottl oneDeviceData->reported = agFALSE; 5991285809Sscottl DeviceListList = DeviceListList->flink; 5992285809Sscottl } 5993285809Sscottl else 5994285809Sscottl { 5995285809Sscottl if (oneDeviceData->dmPortContext != agNULL) 5996285809Sscottl { 5997285809Sscottl DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5998285809Sscottl } 5999285809Sscottl else 6000285809Sscottl { 6001285809Sscottl DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6002285809Sscottl } 6003285809Sscottl DeviceListList = DeviceListList->flink; 6004285809Sscottl } 6005285809Sscottl } 6006285809Sscottl 6007285809Sscottl return; 6008285809Sscottl} 6009285809Sscottl 6010285809Sscottl/* called on discover failure */ 6011285809SscottlosGLOBAL void 6012285809SscottldmDiscoveryInvalidateDevices( 6013285809Sscottl dmRoot_t *dmRoot, 6014285809Sscottl dmIntPortContext_t *onePortContext 6015285809Sscottl ) 6016285809Sscottl{ 6017285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6018285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6019285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6020285809Sscottl dmList_t *DeviceListList; 6021285809Sscottl 6022285809Sscottl DM_DBG1(("dmDiscoveryInvalidateDevices: start\n")); 6023285809Sscottl 6024285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6025285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6026285809Sscottl { 6027285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6028285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: empty device list\n")); 6029285809Sscottl return; 6030285809Sscottl } 6031285809Sscottl else 6032285809Sscottl { 6033285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6034285809Sscottl } 6035285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6036285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6037285809Sscottl { 6038285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6039285809Sscottl if (oneDeviceData == agNULL) 6040285809Sscottl { 6041285809Sscottl DM_DBG1(("dmDiscoveryInvalidateDevices: oneDeviceData is NULL!!!\n")); 6042285809Sscottl return; 6043285809Sscottl } 6044285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: loop did %d\n", oneDeviceData->id)); 6045285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6046285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6047285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: valid %d\n", oneDeviceData->valid)); 6048285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: valid2 %d\n", oneDeviceData->valid2)); 6049285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6050285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 6051285809Sscottl { 6052285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: right portcontext pid %d\n", onePortContext->id)); 6053285809Sscottl if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6054285809Sscottl oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6055285809Sscottl ) 6056285809Sscottl { 6057285809Sscottl DM_DBG1(("dmDiscoveryInvalidateDevices: keeping\n")); 6058285809Sscottl oneDeviceData->valid = agTRUE; 6059285809Sscottl oneDeviceData->valid2 = agFALSE; 6060285809Sscottl } 6061285809Sscottl else 6062285809Sscottl { 6063285809Sscottl oneDeviceData->valid = agFALSE; 6064285809Sscottl oneDeviceData->valid2 = agFALSE; 6065285809Sscottl oneDeviceData->registered = agFALSE; 6066285809Sscottl oneDeviceData->reported = agFALSE; 6067285809Sscottl /* all targets other than expanders */ 6068285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: did %d\n", oneDeviceData->id)); 6069285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6070285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6071285809Sscottl onePortContext->RegisteredDevNums--; 6072285809Sscottl } 6073285809Sscottl DeviceListList = DeviceListList->flink; 6074285809Sscottl } 6075285809Sscottl else 6076285809Sscottl { 6077285809Sscottl if (oneDeviceData->dmPortContext != agNULL) 6078285809Sscottl { 6079285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6080285809Sscottl } 6081285809Sscottl else 6082285809Sscottl { 6083285809Sscottl DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6084285809Sscottl } 6085285809Sscottl DeviceListList = DeviceListList->flink; 6086285809Sscottl } 6087285809Sscottl } 6088285809Sscottl 6089285809Sscottl return; 6090285809Sscottl} 6091285809Sscottl 6092285809Sscottl 6093285809Sscottl/* 6094285809Sscottl should DM report the device removal to TDM on an error case? 6095285809Sscottl or 6096285809Sscottl DM simply removes the devices 6097285809Sscottl For now, the second option. 6098285809Sscottl*/ 6099285809SscottlosGLOBAL void 6100285809SscottldmDiscoveryErrorRemovals( 6101285809Sscottl dmRoot_t *dmRoot, 6102285809Sscottl dmIntPortContext_t *onePortContext 6103285809Sscottl ) 6104285809Sscottl{ 6105285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6106285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6107285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6108285809Sscottl dmList_t *DeviceListList; 6109285809Sscottl 6110285809Sscottl DM_DBG1(("dmDiscoveryErrorRemovals: start\n")); 6111285809Sscottl 6112285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6113285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6114285809Sscottl { 6115285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6116285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: empty device list\n")); 6117285809Sscottl return; 6118285809Sscottl } 6119285809Sscottl else 6120285809Sscottl { 6121285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6122285809Sscottl } 6123285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6124285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6125285809Sscottl { 6126285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6127285809Sscottl if (oneDeviceData == agNULL) 6128285809Sscottl { 6129285809Sscottl DM_DBG1(("dmDiscoveryErrorRemovals: oneDeviceData is NULL!!!\n")); 6130285809Sscottl return; 6131285809Sscottl } 6132285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: loop did %d\n", oneDeviceData->id)); 6133285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6134285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6135285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: valid %d\n", oneDeviceData->valid)); 6136285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: valid2 %d\n", oneDeviceData->valid2)); 6137285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6138285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 6139285809Sscottl { 6140285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: right portcontext pid %d\n", onePortContext->id)); 6141285809Sscottl if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6142285809Sscottl oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6143285809Sscottl ) 6144285809Sscottl { 6145285809Sscottl DM_DBG1(("dmDiscoveryErrorRemovals: keeping\n")); 6146285809Sscottl oneDeviceData->valid = agTRUE; 6147285809Sscottl oneDeviceData->valid2 = agFALSE; 6148285809Sscottl } 6149285809Sscottl else 6150285809Sscottl { 6151285809Sscottl oneDeviceData->valid = agFALSE; 6152285809Sscottl oneDeviceData->valid2 = agFALSE; 6153285809Sscottl 6154285809Sscottl /* all targets other than expanders */ 6155285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: did %d\n", oneDeviceData->id)); 6156285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6157285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6158285809Sscottl onePortContext->RegisteredDevNums--; 6159285809Sscottl dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 6160285809Sscottl 6161285809Sscottl } 6162285809Sscottl DeviceListList = DeviceListList->flink; 6163285809Sscottl } 6164285809Sscottl else 6165285809Sscottl { 6166285809Sscottl if (oneDeviceData->dmPortContext != agNULL) 6167285809Sscottl { 6168285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6169285809Sscottl } 6170285809Sscottl else 6171285809Sscottl { 6172285809Sscottl DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6173285809Sscottl } 6174285809Sscottl DeviceListList = DeviceListList->flink; 6175285809Sscottl } 6176285809Sscottl } 6177285809Sscottl 6178285809Sscottl return; 6179285809Sscottl} 6180285809Sscottl 6181285809Sscottl/* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */ 6182285809SscottlosGLOBAL void 6183285809SscottldmDiscoveryExpanderCleanUp( 6184285809Sscottl dmRoot_t *dmRoot, 6185285809Sscottl dmIntPortContext_t *onePortContext 6186285809Sscottl ) 6187285809Sscottl{ 6188285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6189285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6190285809Sscottl dmExpander_t *oneExpander = agNULL; 6191285809Sscottl dmList_t *ExpanderList = agNULL; 6192285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6193285809Sscottl 6194285809Sscottl DM_DBG3(("dmDiscoveryExpanderCleanUp: start\n")); 6195285809Sscottl /* 6196285809Sscottl be sure to call 6197285809Sscottl osGLOBAL void 6198285809Sscottl dmExpanderDeviceDataReInit( 6199285809Sscottl dmRoot_t *dmRoot, 6200285809Sscottl dmExpander_t *oneExpander 6201285809Sscottl ); 6202285809Sscottl 6203285809Sscottl */ 6204285809Sscottl 6205285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6206285809Sscottl if (!DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6207285809Sscottl { 6208285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6209285809Sscottl ExpanderList = dmAllShared->mainExpanderList.flink; 6210285809Sscottl while (ExpanderList != &(dmAllShared->mainExpanderList)) 6211285809Sscottl { 6212285809Sscottl oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6213285809Sscottl if (oneExpander == agNULL) 6214285809Sscottl { 6215285809Sscottl DM_DBG1(("dmDiscoveryExpanderCleanUp: oneExpander is NULL!!!\n")); 6216285809Sscottl return; 6217285809Sscottl } 6218285809Sscottl oneDeviceData = oneExpander->dmDevice; 6219285809Sscottl DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6220285809Sscottl DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6221285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 6222285809Sscottl { 6223285809Sscottl dmExpanderDeviceDataReInit(dmRoot, oneExpander); 6224285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6225285809Sscottl DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 6226285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 6227285809Sscottl 6228285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6229285809Sscottl { 6230285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6231285809Sscottl break; 6232285809Sscottl } 6233285809Sscottl else 6234285809Sscottl { 6235285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6236285809Sscottl } 6237285809Sscottl ExpanderList = dmAllShared->mainExpanderList.flink; 6238285809Sscottl } 6239285809Sscottl else 6240285809Sscottl { 6241285809Sscottl ExpanderList = ExpanderList->flink; 6242285809Sscottl } 6243285809Sscottl } 6244285809Sscottl } 6245285809Sscottl else 6246285809Sscottl { 6247285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6248285809Sscottl DM_DBG3(("dmDiscoveryExpanderCleanUp: empty mainExpanderList\n")); 6249285809Sscottl } 6250285809Sscottl return; 6251285809Sscottl 6252285809Sscottl} 6253285809Sscottl 6254285809Sscottl 6255285809Sscottl/* moves all devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */ 6256285809SscottlosGLOBAL void 6257285809SscottldmDiscoveryDeviceCleanUp( 6258285809Sscottl dmRoot_t *dmRoot, 6259285809Sscottl dmIntPortContext_t *onePortContext 6260285809Sscottl ) 6261285809Sscottl{ 6262285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6263285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6264285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6265285809Sscottl dmList_t *DeviceListList; 6266285809Sscottl 6267285809Sscottl DM_DBG3(("dmDiscoveryDeviceCleanUp: start\n")); 6268285809Sscottl 6269285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6270285809Sscottl if (!DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6271285809Sscottl { 6272285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6273285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6274285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6275285809Sscottl { 6276285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6277285809Sscottl if (oneDeviceData == agNULL) 6278285809Sscottl { 6279285809Sscottl DM_DBG1(("dmDiscoveryDeviceCleanUp: oneDeviceData is NULL!!!\n")); 6280285809Sscottl return; 6281285809Sscottl } 6282285809Sscottl DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6283285809Sscottl DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6284285809Sscottl if ( oneDeviceData->dmPortContext == onePortContext) 6285285809Sscottl { 6286285809Sscottl dmDeviceDataReInit(dmRoot, oneDeviceData); 6287285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6288285809Sscottl DMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 6289285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(dmAllShared->FreeDeviceList)); 6290285809Sscottl 6291285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6292285809Sscottl { 6293285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6294285809Sscottl break; 6295285809Sscottl } 6296285809Sscottl else 6297285809Sscottl { 6298285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6299285809Sscottl } 6300285809Sscottl onePortContext->RegisteredDevNums--; 6301285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6302285809Sscottl } 6303285809Sscottl else 6304285809Sscottl { 6305285809Sscottl DeviceListList = DeviceListList->flink; 6306285809Sscottl } 6307285809Sscottl } 6308285809Sscottl } 6309285809Sscottl else 6310285809Sscottl { 6311285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6312285809Sscottl DM_DBG3(("dmDiscoveryDeviceCleanUp: empty MainDeviceList\n")); 6313285809Sscottl } 6314285809Sscottl return; 6315285809Sscottl} 6316285809Sscottl 6317285809Sscottl 6318285809Sscottl 6319285809SscottlosGLOBAL void 6320285809SscottldmDumpAllExp( 6321285809Sscottl dmRoot_t *dmRoot, 6322285809Sscottl dmIntPortContext_t *onePortContext, 6323285809Sscottl dmExpander_t *oneExpander 6324285809Sscottl ) 6325285809Sscottl{ 6326285809Sscottl DM_DBG3(("dmDumpAllExp: start\n")); 6327285809Sscottl return; 6328285809Sscottl} 6329285809Sscottl 6330285809Sscottl 6331285809SscottlosGLOBAL void 6332285809SscottldmDumpAllUpExp( 6333285809Sscottl dmRoot_t *dmRoot, 6334285809Sscottl dmIntPortContext_t *onePortContext, 6335285809Sscottl dmExpander_t *oneExpander 6336285809Sscottl ) 6337285809Sscottl{ 6338285809Sscottl DM_DBG3(("dmDumpAllUpExp: start\n")); 6339285809Sscottl return; 6340285809Sscottl} 6341285809Sscottl 6342285809SscottlosGLOBAL void 6343285809SscottldmDumpAllFreeExp( 6344285809Sscottl dmRoot_t *dmRoot 6345285809Sscottl ) 6346285809Sscottl{ 6347285809Sscottl DM_DBG3(("dmDumpAllFreeExp: start\n")); 6348285809Sscottl return; 6349285809Sscottl} 6350285809Sscottl 6351285809SscottlosGLOBAL void 6352285809SscottldmDumpAllMainExp( 6353285809Sscottl dmRoot_t *dmRoot, 6354285809Sscottl dmIntPortContext_t *onePortContext 6355285809Sscottl ) 6356285809Sscottl{ 6357285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6358285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6359285809Sscottl dmList_t *ExpanderList; 6360285809Sscottl dmExpander_t *tempExpander; 6361285809Sscottl 6362285809Sscottl DM_DBG3(("dmDumpAllMainExp: start\n")); 6363285809Sscottl 6364285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6365285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6366285809Sscottl { 6367285809Sscottl DM_DBG3(("dmDumpAllMainExp: empty discoveringExpanderList\n")); 6368285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6369285809Sscottl return; 6370285809Sscottl } 6371285809Sscottl else 6372285809Sscottl { 6373285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6374285809Sscottl } 6375285809Sscottl 6376285809Sscottl ExpanderList = dmAllShared->mainExpanderList.flink; 6377285809Sscottl while (ExpanderList != &(dmAllShared->mainExpanderList)) 6378285809Sscottl { 6379285809Sscottl tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6380285809Sscottl if (tempExpander == agNULL) 6381285809Sscottl { 6382285809Sscottl DM_DBG1(("dmDumpAllMainExp: tempExpander is NULL!!!\n")); 6383285809Sscottl return; 6384285809Sscottl } 6385285809Sscottl DM_DBG3(("dmDumpAllMainExp: expander id %d\n", tempExpander->id)); 6386285809Sscottl DM_DBG3(("dmDumpAllMainExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6387285809Sscottl DM_DBG3(("dmDumpAllMainExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6388285809Sscottl if ((tempExpander->dmDevice->dmPortContext == onePortContext) 6389285809Sscottl ) 6390285809Sscottl { 6391285809Sscottl DM_DBG3(("dmDumpAllMainExp: found expander id %d\n", tempExpander->id)); 6392285809Sscottl DM_DBG3(("dmDumpAllMainExp: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6393285809Sscottl DM_DBG3(("dmDumpAllMainExp: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6394285809Sscottl } 6395285809Sscottl ExpanderList = ExpanderList->flink; 6396285809Sscottl } 6397285809Sscottl return; 6398285809Sscottl} 6399285809Sscottl 6400285809Sscottl 6401285809SscottlosGLOBAL void 6402285809SscottldmDumpAllMainDevice( 6403285809Sscottl dmRoot_t *dmRoot, 6404285809Sscottl dmIntPortContext_t *onePortContext 6405285809Sscottl ) 6406285809Sscottl{ 6407285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6408285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6409285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6410285809Sscottl dmList_t *DeviceListList; 6411285809Sscottl bit32 total = 0, port_total = 0; 6412285809Sscottl 6413285809Sscottl DM_DBG3(("dmDumpAllMainDevice: start\n")); 6414285809Sscottl 6415285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6416285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6417285809Sscottl { 6418285809Sscottl DM_DBG3(("dmDumpAllMainDevice: empty discoveringExpanderList\n")); 6419285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6420285809Sscottl return; 6421285809Sscottl } 6422285809Sscottl else 6423285809Sscottl { 6424285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6425285809Sscottl } 6426285809Sscottl 6427285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6428285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6429285809Sscottl { 6430285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6431285809Sscottl if (oneDeviceData == agNULL) 6432285809Sscottl { 6433285809Sscottl DM_DBG3(("dmDumpAllMainDevice: oneDeviceData is NULL!!!\n")); 6434285809Sscottl return; 6435285809Sscottl } 6436285809Sscottl DM_DBG3(("dmDumpAllMainDevice: oneDeviceData id %d\n", oneDeviceData->id)); 6437285809Sscottl DM_DBG3(("dmDumpAllMainDevice: addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6438285809Sscottl DM_DBG3(("dmDumpAllMainDevice: addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6439285809Sscottl total++; 6440285809Sscottl if ((oneDeviceData->dmPortContext == onePortContext) 6441285809Sscottl ) 6442285809Sscottl { 6443285809Sscottl DM_DBG3(("dmDumpAllMainDevice: found oneDeviceData id %d\n", oneDeviceData->id)); 6444285809Sscottl DM_DBG3(("dmDumpAllMainDevice: found addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6445285809Sscottl DM_DBG3(("dmDumpAllMainDevice: found addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6446285809Sscottl port_total++; 6447285809Sscottl } 6448285809Sscottl DeviceListList = DeviceListList->flink; 6449285809Sscottl } 6450285809Sscottl DM_DBG3(("dmDumpAllMainDevice: total %d port_totaol %d\n", total, port_total)); 6451285809Sscottl 6452285809Sscottl return; 6453285809Sscottl} 6454285809Sscottl 6455285809Sscottl 6456285809Sscottl 6457285809SscottlosGLOBAL dmDeviceData_t * 6458285809SscottldmAddSASToSharedcontext( 6459285809Sscottl dmRoot_t *dmRoot, 6460285809Sscottl dmIntPortContext_t *onePortContext, 6461285809Sscottl dmSASSubID_t *dmSASSubID, 6462285809Sscottl dmDeviceData_t *oneExpDeviceData, 6463285809Sscottl bit8 phyID 6464285809Sscottl ) 6465285809Sscottl{ 6466285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6467285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6468285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6469285809Sscottl dmList_t *DeviceListList; 6470285809Sscottl bit32 new_device = agTRUE; 6471285809Sscottl 6472285809Sscottl 6473285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: start\n")); 6474285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: oneportContext ID %d\n", onePortContext->id)); 6475285809Sscottl 6476285809Sscottl if (oneExpDeviceData != agNULL) 6477285809Sscottl { 6478285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6479285809Sscottl oneExpDeviceData->SASAddressID.sasAddressHi, oneExpDeviceData->SASAddressID.sasAddressLo)); 6480285809Sscottl } 6481285809Sscottl else 6482285809Sscottl { 6483285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData is NULL\n")); 6484285809Sscottl } 6485285809Sscottl /* find a device's existence */ 6486285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6487285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6488285809Sscottl { 6489285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6490285809Sscottl if (oneDeviceData == agNULL) 6491285809Sscottl { 6492285809Sscottl DM_DBG1(("dmAddSASToSharedcontext: oneDeviceData is NULL!!!\n")); 6493285809Sscottl return agNULL; 6494285809Sscottl } 6495285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 6496285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 6497285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 6498285809Sscottl ) 6499285809Sscottl { 6500285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6501285809Sscottl new_device = agFALSE; 6502285809Sscottl break; 6503285809Sscottl } 6504285809Sscottl DeviceListList = DeviceListList->flink; 6505285809Sscottl } 6506285809Sscottl 6507285809Sscottl /* new device */ 6508285809Sscottl if (new_device == agTRUE) 6509285809Sscottl { 6510285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: new device\n")); 6511285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6512285809Sscottl dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6513285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6514285809Sscottl if (!DMLIST_NOT_EMPTY(&(dmAllShared->FreeDeviceList))) 6515285809Sscottl { 6516285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6517285809Sscottl DM_DBG1(("dmAddSASToSharedcontext: empty DeviceData FreeLink\n")); 6518285809Sscottl dmDumpAllMainDevice(dmRoot, onePortContext); 6519285809Sscottl return agNULL; 6520285809Sscottl } 6521285809Sscottl 6522285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(dmAllShared->FreeDeviceList)); 6523285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6524285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, FreeLink, DeviceListList); 6525285809Sscottl 6526285809Sscottl if (oneDeviceData != agNULL) 6527285809Sscottl { 6528285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p pid %d did %d\n", oneDeviceData, onePortContext->id, oneDeviceData->id)); 6529285809Sscottl 6530285809Sscottl onePortContext->Count++; 6531285809Sscottl oneDeviceData->dmRoot = dmRoot; 6532285809Sscottl /* saving sas address */ 6533285809Sscottl oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6534285809Sscottl oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6535285809Sscottl oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6536285809Sscottl oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6537285809Sscottl oneDeviceData->dmPortContext = onePortContext; 6538285809Sscottl /* handles both SAS target and STP-target, SATA-device */ 6539285809Sscottl if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6540285809Sscottl { 6541285809Sscottl oneDeviceData->DeviceType = DM_SAS_DEVICE; 6542285809Sscottl } 6543285809Sscottl else 6544285809Sscottl { 6545285809Sscottl oneDeviceData->DeviceType = DM_SATA_DEVICE; 6546285809Sscottl } 6547285809Sscottl 6548285809Sscottl if (oneExpDeviceData != agNULL) 6549285809Sscottl { 6550285809Sscottl oneDeviceData->ExpDevice = oneExpDeviceData; 6551285809Sscottl } 6552285809Sscottl 6553285809Sscottl /* set phyID only when it has initial value of 0xFF */ 6554285809Sscottl if (oneDeviceData->phyID == 0xFF) 6555285809Sscottl { 6556285809Sscottl oneDeviceData->phyID = phyID; 6557285809Sscottl } 6558285809Sscottl /* incremental discovery */ 6559285809Sscottl /* add device to incremental-related link. Report using this link 6560285809Sscottl when incremental discovery is done */ 6561285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6562285809Sscottl { 6563285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6564285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6565285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6566285809Sscottl oneDeviceData->valid = agTRUE; 6567285809Sscottl } 6568285809Sscottl else 6569285809Sscottl { 6570285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6571285809Sscottl { 6572285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6573285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6574285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6575285809Sscottl oneDeviceData->valid2 = agTRUE; 6576285809Sscottl } 6577285809Sscottl else 6578285809Sscottl { 6579285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6580285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6581285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6582285809Sscottl oneDeviceData->valid = agTRUE; 6583285809Sscottl } 6584285809Sscottl } 6585285809Sscottl /* add the devicedata to the portcontext */ 6586285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6587285809Sscottl DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(dmAllShared->MainDeviceList)); 6588285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6589285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: one case pid %d did %d \n", onePortContext->id, oneDeviceData->id)); 6590285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: new case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6591285809Sscottl } 6592285809Sscottl } 6593285809Sscottl else /* old device */ 6594285809Sscottl { 6595285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: old device\n")); 6596285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 6597285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6598285809Sscottl dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6599285809Sscottl 6600285809Sscottl oneDeviceData->dmRoot = dmRoot; 6601285809Sscottl /* saving sas address */ 6602285809Sscottl oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6603285809Sscottl oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6604285809Sscottl oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6605285809Sscottl oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6606285809Sscottl oneDeviceData->dmPortContext = onePortContext; 6607285809Sscottl /* handles both SAS target and STP-target, SATA-device */ 6608285809Sscottl if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6609285809Sscottl { 6610285809Sscottl oneDeviceData->DeviceType = DM_SAS_DEVICE; 6611285809Sscottl } 6612285809Sscottl else 6613285809Sscottl { 6614285809Sscottl oneDeviceData->DeviceType = DM_SATA_DEVICE; 6615285809Sscottl } 6616285809Sscottl 6617285809Sscottl if (oneExpDeviceData != agNULL) 6618285809Sscottl { 6619285809Sscottl oneDeviceData->ExpDevice = oneExpDeviceData; 6620285809Sscottl } 6621285809Sscottl 6622285809Sscottl /* set phyID only when it has initial value of 0xFF */ 6623285809Sscottl if (oneDeviceData->phyID == 0xFF) 6624285809Sscottl { 6625285809Sscottl oneDeviceData->phyID = phyID; 6626285809Sscottl } 6627285809Sscottl 6628285809Sscottl if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6629285809Sscottl { 6630285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6631285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6632285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6633285809Sscottl oneDeviceData->valid = agTRUE; 6634285809Sscottl } 6635285809Sscottl else 6636285809Sscottl { 6637285809Sscottl if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6638285809Sscottl { 6639285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6640285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6641285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6642285809Sscottl oneDeviceData->valid2 = agTRUE; 6643285809Sscottl } 6644285809Sscottl else 6645285809Sscottl { 6646285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6647285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6648285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6649285809Sscottl oneDeviceData->valid = agTRUE; 6650285809Sscottl } 6651285809Sscottl } 6652285809Sscottl DM_DBG3(("dmAddSASToSharedcontext: old case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6653285809Sscottl 6654285809Sscottl } 6655285809Sscottl return oneDeviceData; 6656285809Sscottl} 6657285809Sscottl 6658285809Sscottl/* no checking of valid and valid2 */ 6659285809SscottlosGLOBAL dmDeviceData_t * 6660285809SscottldmDeviceFind( 6661285809Sscottl dmRoot_t *dmRoot, 6662285809Sscottl dmIntPortContext_t *onePortContext, 6663285809Sscottl bit32 sasAddrHi, 6664285809Sscottl bit32 sasAddrLo 6665285809Sscottl ) 6666285809Sscottl{ 6667285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6668285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6669285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 6670285809Sscottl dmList_t *DeviceListList; 6671285809Sscottl bit32 found = agFALSE; 6672285809Sscottl 6673285809Sscottl DM_DBG3(("dmDeviceFind: start\n")); 6674285809Sscottl /* find a device's existence */ 6675285809Sscottl DeviceListList = dmAllShared->MainDeviceList.flink; 6676285809Sscottl 6677285809Sscottl while (DeviceListList != &(dmAllShared->MainDeviceList)) 6678285809Sscottl { 6679285809Sscottl oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6680285809Sscottl if (oneDeviceData == agNULL) 6681285809Sscottl { 6682285809Sscottl DM_DBG1(("dmDeviceFind: oneDeviceData is NULL!!!\n")); 6683285809Sscottl return agNULL; 6684285809Sscottl } 6685285809Sscottl if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 6686285809Sscottl (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 6687285809Sscottl// (oneDeviceData->valid == agTRUE) && 6688285809Sscottl (oneDeviceData->dmPortContext == onePortContext) 6689285809Sscottl ) 6690285809Sscottl { 6691285809Sscottl DM_DBG3(("dmDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6692285809Sscottl DM_DBG3(("dmDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6693285809Sscottl DM_DBG3(("dmDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6694285809Sscottl found = agTRUE; 6695285809Sscottl break; 6696285809Sscottl } 6697285809Sscottl DeviceListList = DeviceListList->flink; 6698285809Sscottl } 6699285809Sscottl 6700285809Sscottl if (found == agFALSE) 6701285809Sscottl { 6702285809Sscottl DM_DBG3(("dmDeviceFind: end returning NULL\n")); 6703285809Sscottl return agNULL; 6704285809Sscottl } 6705285809Sscottl else 6706285809Sscottl { 6707285809Sscottl DM_DBG3(("dmDeviceFind: end returning NOT NULL\n")); 6708285809Sscottl return oneDeviceData; 6709285809Sscottl } 6710285809Sscottl 6711285809Sscottl} 6712285809Sscottl 6713285809Sscottl 6714285809SscottlosGLOBAL void 6715285809SscottldmBCTimer( 6716285809Sscottl dmRoot_t *dmRoot, 6717285809Sscottl dmIntPortContext_t *onePortContext 6718285809Sscottl ) 6719285809Sscottl{ 6720285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6721285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6722285809Sscottl dmDiscovery_t *discovery; 6723285809Sscottl 6724285809Sscottl DM_DBG3(("dmBCTimer: start\n")); 6725285809Sscottl 6726285809Sscottl discovery = &(onePortContext->discovery); 6727285809Sscottl 6728285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6729285809Sscottl if (discovery->BCTimer.timerRunning == agTRUE) 6730285809Sscottl { 6731285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6732285809Sscottl dmKillTimer( 6733285809Sscottl dmRoot, 6734285809Sscottl &discovery->BCTimer 6735285809Sscottl ); 6736285809Sscottl } 6737285809Sscottl else 6738285809Sscottl { 6739285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6740285809Sscottl } 6741285809Sscottl 6742285809Sscottl if (onePortContext->valid == agTRUE) 6743285809Sscottl { 6744285809Sscottl dmSetTimerRequest( 6745285809Sscottl dmRoot, 6746285809Sscottl &discovery->BCTimer, 6747285809Sscottl BC_TIMER_VALUE/dmAllShared->usecsPerTick, 6748285809Sscottl dmBCTimerCB, 6749285809Sscottl onePortContext, 6750285809Sscottl agNULL, 6751285809Sscottl agNULL 6752285809Sscottl ); 6753285809Sscottl 6754285809Sscottl dmAddTimer( 6755285809Sscottl dmRoot, 6756285809Sscottl &dmAllShared->timerlist, 6757285809Sscottl &discovery->BCTimer 6758285809Sscottl ); 6759285809Sscottl 6760285809Sscottl } 6761285809Sscottl 6762285809Sscottl 6763285809Sscottl return; 6764285809Sscottl} 6765285809Sscottl 6766285809Sscottl 6767285809SscottlosGLOBAL void 6768285809SscottldmBCTimerCB( 6769285809Sscottl dmRoot_t * dmRoot, 6770285809Sscottl void * timerData1, 6771285809Sscottl void * timerData2, 6772285809Sscottl void * timerData3 6773285809Sscottl ) 6774285809Sscottl{ 6775285809Sscottl dmIntPortContext_t *onePortContext; 6776285809Sscottl dmDiscovery_t *discovery; 6777285809Sscottl 6778285809Sscottl DM_DBG3(("dmBCTimerCB: start\n")); 6779285809Sscottl 6780285809Sscottl onePortContext = (dmIntPortContext_t *)timerData1; 6781285809Sscottl discovery = &(onePortContext->discovery); 6782285809Sscottl 6783285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6784285809Sscottl if (discovery->BCTimer.timerRunning == agTRUE) 6785285809Sscottl { 6786285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6787285809Sscottl dmKillTimer( 6788285809Sscottl dmRoot, 6789285809Sscottl &discovery->BCTimer 6790285809Sscottl ); 6791285809Sscottl } 6792285809Sscottl else 6793285809Sscottl { 6794285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6795285809Sscottl } 6796285809Sscottl 6797285809Sscottl discovery->ResetTriggerred = agFALSE; 6798285809Sscottl 6799285809Sscottl if (onePortContext->valid == agTRUE) 6800285809Sscottl { 6801285809Sscottl dmDiscover(dmRoot, 6802285809Sscottl onePortContext->dmPortContext, 6803285809Sscottl DM_DISCOVERY_OPTION_INCREMENTAL_START 6804285809Sscottl ); 6805285809Sscottl } 6806285809Sscottl return; 6807285809Sscottl} 6808285809Sscottl 6809285809Sscottl/* discovery related SMP timers */ 6810285809SscottlosGLOBAL void 6811285809SscottldmDiscoverySMPTimer(dmRoot_t *dmRoot, 6812285809Sscottl dmIntPortContext_t *onePortContext, 6813285809Sscottl bit32 functionCode, 6814285809Sscottl dmSMPRequestBody_t *dmSMPRequestBody 6815285809Sscottl ) 6816285809Sscottl{ 6817285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6818285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6819285809Sscottl dmDiscovery_t *discovery; 6820285809Sscottl 6821285809Sscottl DM_DBG3(("dmDiscoverySMPTimer: start\n")); 6822285809Sscottl DM_DBG3(("dmDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode)); 6823285809Sscottl 6824285809Sscottl /* start the SMP timer which works as SMP application timer */ 6825285809Sscottl discovery = &(onePortContext->discovery); 6826285809Sscottl 6827285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6828285809Sscottl if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6829285809Sscottl { 6830285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6831285809Sscottl dmKillTimer( 6832285809Sscottl dmRoot, 6833285809Sscottl &discovery->DiscoverySMPTimer 6834285809Sscottl ); 6835285809Sscottl } 6836285809Sscottl else 6837285809Sscottl { 6838285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6839285809Sscottl } 6840285809Sscottl 6841285809Sscottl 6842285809Sscottl dmSetTimerRequest( 6843285809Sscottl dmRoot, 6844285809Sscottl &discovery->DiscoverySMPTimer, 6845285809Sscottl SMP_TIMER_VALUE/dmAllShared->usecsPerTick, 6846285809Sscottl dmDiscoverySMPTimerCB, 6847285809Sscottl onePortContext, 6848285809Sscottl dmSMPRequestBody, 6849285809Sscottl agNULL 6850285809Sscottl ); 6851285809Sscottl 6852285809Sscottl dmAddTimer ( 6853285809Sscottl dmRoot, 6854285809Sscottl &dmAllShared->timerlist, 6855285809Sscottl &discovery->DiscoverySMPTimer 6856285809Sscottl ); 6857285809Sscottl 6858285809Sscottl return; 6859285809Sscottl} 6860285809Sscottl 6861285809Sscottl 6862285809SscottlosGLOBAL void 6863285809SscottldmDiscoverySMPTimerCB( 6864285809Sscottl dmRoot_t * dmRoot, 6865285809Sscottl void * timerData1, 6866285809Sscottl void * timerData2, 6867285809Sscottl void * timerData3 6868285809Sscottl ) 6869285809Sscottl{ 6870285809Sscottl agsaRoot_t *agRoot; 6871285809Sscottl dmIntPortContext_t *onePortContext; 6872285809Sscottl bit8 SMPFunction; 6873285809Sscottl#ifndef DIRECT_SMP 6874285809Sscottl dmSMPFrameHeader_t *dmSMPFrameHeader; 6875285809Sscottl bit8 smpHeader[4]; 6876285809Sscottl#endif 6877285809Sscottl dmSMPRequestBody_t *dmSMPRequestBody; 6878285809Sscottl dmDiscovery_t *discovery; 6879285809Sscottl dmDeviceData_t *oneDeviceData; 6880285809Sscottl agsaIORequest_t *agAbortIORequest = agNULL; 6881285809Sscottl agsaIORequest_t *agToBeAbortIORequest = agNULL; 6882285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6883285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6884285809Sscottl dmExpander_t *oneExpander = agNULL; 6885285809Sscottl dmSMPRequestBody_t *dmAbortSMPRequestBody = agNULL; 6886285809Sscottl dmList_t *SMPList; 6887285809Sscottl 6888285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: start!!!\n")); 6889285809Sscottl 6890285809Sscottl onePortContext = (dmIntPortContext_t *)timerData1; 6891285809Sscottl dmSMPRequestBody = (dmSMPRequestBody_t *)timerData2; 6892285809Sscottl 6893285809Sscottl discovery = &(onePortContext->discovery); 6894285809Sscottl oneDeviceData = dmSMPRequestBody->dmDevice; 6895285809Sscottl agToBeAbortIORequest = &(dmSMPRequestBody->agIORequest); 6896285809Sscottl agRoot = dmAllShared->agRoot; 6897285809Sscottl 6898285809Sscottl#ifdef DIRECT_SMP 6899285809Sscottl SMPFunction = dmSMPRequestBody->smpPayload[1]; 6900285809Sscottl#else 6901285809Sscottl saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpHeader, 4); 6902285809Sscottl dmSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 6903285809Sscottl SMPFunction = dmSMPFrameHeader->smpFunction; 6904285809Sscottl#endif 6905285809Sscottl 6906285809Sscottl DM_DBG3(("dmDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction)); 6907285809Sscottl 6908285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6909285809Sscottl if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6910285809Sscottl { 6911285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6912285809Sscottl dmKillTimer( 6913285809Sscottl dmRoot, 6914285809Sscottl &discovery->DiscoverySMPTimer 6915285809Sscottl ); 6916285809Sscottl } 6917285809Sscottl else 6918285809Sscottl { 6919285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6920285809Sscottl } 6921285809Sscottl 6922285809Sscottl//for debugging 6923285809Sscottl// saGetPendingPICI(agRoot); 6924285809Sscottl 6925285809Sscottl switch (SMPFunction) 6926285809Sscottl { 6927285809Sscottl case SMP_REPORT_GENERAL: /* fall through */ 6928285809Sscottl case SMP_DISCOVER: /* fall through */ 6929285809Sscottl case SMP_CONFIGURE_ROUTING_INFORMATION: /* fall through */ 6930285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function 0x%x !!!\n", SMPFunction)); 6931285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6932285809Sscottl return; /* no more things to do */ 6933285809Sscottl case SMP_REPORT_PHY_SATA: 6934285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA !!!\n")); 6935285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6936285809Sscottl break; 6937285809Sscottl default: 6938285809Sscottl /* do nothing */ 6939285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: Error, not allowed case!!!\n")); 6940285809Sscottl break; 6941285809Sscottl } 6942285809Sscottl 6943285809Sscottl if (oneDeviceData->registered == agTRUE && (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) ) 6944285809Sscottl { 6945285809Sscottl /* call to saSMPAbort(one) */ 6946285809Sscottl /* get an smp REQUEST from the free list */ 6947285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 6948285809Sscottl if (DMLIST_EMPTY(&(dmAllShared->freeSMPList))) 6949285809Sscottl { 6950285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: no free SMP, can't abort SMP!!!\n")); 6951285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6952285809Sscottl return; 6953285809Sscottl } 6954285809Sscottl else 6955285809Sscottl { 6956285809Sscottl DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList)); 6957285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6958285809Sscottl dmAbortSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList); 6959285809Sscottl if (dmAbortSMPRequestBody == agNULL) 6960285809Sscottl { 6961285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: dmAbortSMPRequestBody is NULL!!!\n")); 6962285809Sscottl return; 6963285809Sscottl } 6964285809Sscottl DM_DBG5(("dmDiscoverySMPTimerCB: SMP id %d\n", dmAbortSMPRequestBody->id)); 6965285809Sscottl } 6966285809Sscottl 6967285809Sscottl dmAbortSMPRequestBody->dmRoot = dmRoot; 6968285809Sscottl 6969285809Sscottl agAbortIORequest = &(dmAbortSMPRequestBody->agIORequest); 6970285809Sscottl agAbortIORequest->osData = (void *) dmAbortSMPRequestBody; 6971285809Sscottl agAbortIORequest->sdkData = agNULL; /* SALL takes care of this */ 6972285809Sscottl 6973285809Sscottl oneExpander = oneDeviceData->dmExpander; 6974285809Sscottl 6975285809Sscottl DM_DBG1(("dmDiscoverySMPTimerCB: calling saSMPAbort!!!\n")); 6976285809Sscottl saSMPAbort(agRoot, 6977285809Sscottl agAbortIORequest, 6978285809Sscottl 0, 6979285809Sscottl oneExpander->agDevHandle, 6980285809Sscottl 0, /* abort one */ 6981285809Sscottl agToBeAbortIORequest, 6982285809Sscottl dmSMPAbortCB 6983285809Sscottl ); 6984285809Sscottl } 6985285809Sscottl return; 6986285809Sscottl} 6987285809Sscottl 6988285809Sscottl 6989285809Sscottl 6990285809Sscottl 6991285809SscottlosGLOBAL void 6992285809SscottldmSMPBusyTimer(dmRoot_t *dmRoot, 6993285809Sscottl dmIntPortContext_t *onePortContext, 6994285809Sscottl dmDeviceData_t *oneDeviceData, 6995285809Sscottl dmSMPRequestBody_t *dmSMPRequestBody 6996285809Sscottl ) 6997285809Sscottl{ 6998285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6999285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7000285809Sscottl dmDiscovery_t *discovery; 7001285809Sscottl 7002285809Sscottl DM_DBG3(("dmSMPBusyTimer: start\n")); 7003285809Sscottl DM_DBG3(("dmSMPBusyTimer: pid %d\n", onePortContext->id)); 7004285809Sscottl 7005285809Sscottl discovery = &(onePortContext->discovery); 7006285809Sscottl 7007285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7008285809Sscottl if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7009285809Sscottl { 7010285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7011285809Sscottl dmKillTimer( 7012285809Sscottl dmRoot, 7013285809Sscottl &discovery->SMPBusyTimer 7014285809Sscottl ); 7015285809Sscottl } 7016285809Sscottl else 7017285809Sscottl { 7018285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7019285809Sscottl } 7020285809Sscottl 7021285809Sscottl dmSetTimerRequest( 7022285809Sscottl dmRoot, 7023285809Sscottl &discovery->SMPBusyTimer, 7024285809Sscottl SMP_BUSY_TIMER_VALUE/dmAllShared->usecsPerTick, 7025285809Sscottl dmSMPBusyTimerCB, 7026285809Sscottl onePortContext, 7027285809Sscottl oneDeviceData, 7028285809Sscottl dmSMPRequestBody 7029285809Sscottl ); 7030285809Sscottl 7031285809Sscottl dmAddTimer ( 7032285809Sscottl dmRoot, 7033285809Sscottl &dmAllShared->timerlist, 7034285809Sscottl &discovery->SMPBusyTimer 7035285809Sscottl ); 7036285809Sscottl 7037285809Sscottl 7038285809Sscottl return; 7039285809Sscottl} 7040285809Sscottl 7041285809SscottlosGLOBAL void 7042285809SscottldmSMPBusyTimerCB( 7043285809Sscottl dmRoot_t * dmRoot, 7044285809Sscottl void * timerData1, 7045285809Sscottl void * timerData2, 7046285809Sscottl void * timerData3 7047285809Sscottl ) 7048285809Sscottl{ 7049285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7050285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7051285809Sscottl agsaRoot_t *agRoot; 7052285809Sscottl dmIntPortContext_t *onePortContext; 7053285809Sscottl dmDeviceData_t *oneDeviceData; 7054285809Sscottl dmSMPRequestBody_t *dmSMPRequestBody; 7055285809Sscottl agsaSASRequestBody_t *agSASRequestBody; 7056285809Sscottl agsaIORequest_t *agIORequest; 7057285809Sscottl agsaDevHandle_t *agDevHandle; 7058285809Sscottl dmDiscovery_t *discovery; 7059285809Sscottl bit32 status = AGSA_RC_FAILURE; 7060285809Sscottl dmExpander_t *oneExpander = agNULL; 7061285809Sscottl 7062285809Sscottl 7063285809Sscottl DM_DBG3(("dmSMPBusyTimerCB: start\n")); 7064285809Sscottl 7065285809Sscottl onePortContext = (dmIntPortContext_t *)timerData1; 7066285809Sscottl oneDeviceData = (dmDeviceData_t *)timerData2; 7067285809Sscottl dmSMPRequestBody = (dmSMPRequestBody_t *)timerData3; 7068285809Sscottl agRoot = dmAllShared->agRoot; 7069285809Sscottl agIORequest = &(dmSMPRequestBody->agIORequest); 7070285809Sscottl oneExpander = oneDeviceData->dmExpander; 7071285809Sscottl agDevHandle = oneExpander->agDevHandle; 7072285809Sscottl agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 7073285809Sscottl discovery = &(onePortContext->discovery); 7074285809Sscottl 7075285809Sscottl discovery->SMPRetries++; 7076285809Sscottl 7077285809Sscottl if (discovery->SMPRetries < SMP_BUSY_RETRIES) 7078285809Sscottl { 7079285809Sscottl status = saSMPStart( 7080285809Sscottl agRoot, 7081285809Sscottl agIORequest, 7082285809Sscottl 0, 7083285809Sscottl agDevHandle, 7084285809Sscottl AGSA_SMP_INIT_REQ, 7085285809Sscottl agSASRequestBody, 7086285809Sscottl &dmsaSMPCompleted 7087285809Sscottl ); 7088285809Sscottl } 7089285809Sscottl 7090285809Sscottl if (status == AGSA_RC_SUCCESS) 7091285809Sscottl { 7092285809Sscottl discovery->SMPRetries = 0; 7093285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7094285809Sscottl if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7095285809Sscottl { 7096285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7097285809Sscottl dmKillTimer( 7098285809Sscottl dmRoot, 7099285809Sscottl &discovery->SMPBusyTimer 7100285809Sscottl ); 7101285809Sscottl } 7102285809Sscottl else 7103285809Sscottl { 7104285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7105285809Sscottl } 7106285809Sscottl } 7107285809Sscottl else if (status == AGSA_RC_FAILURE) 7108285809Sscottl { 7109285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7110285809Sscottl if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7111285809Sscottl { 7112285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7113285809Sscottl dmKillTimer( 7114285809Sscottl dmRoot, 7115285809Sscottl &discovery->SMPBusyTimer 7116285809Sscottl ); 7117285809Sscottl } 7118285809Sscottl else 7119285809Sscottl { 7120285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7121285809Sscottl } 7122285809Sscottl 7123285809Sscottl discovery->SMPRetries = 0; 7124285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7125285809Sscottl } 7126285809Sscottl else /* AGSA_RC_BUSY */ 7127285809Sscottl { 7128285809Sscottl if (discovery->SMPRetries >= SMP_BUSY_RETRIES) 7129285809Sscottl { 7130285809Sscottl /* done with retris; give up */ 7131285809Sscottl DM_DBG3(("dmSMPBusyTimerCB: retries are over\n")); 7132285809Sscottl 7133285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7134285809Sscottl if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7135285809Sscottl { 7136285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7137285809Sscottl dmKillTimer( 7138285809Sscottl dmRoot, 7139285809Sscottl &discovery->SMPBusyTimer 7140285809Sscottl ); 7141285809Sscottl } 7142285809Sscottl else 7143285809Sscottl { 7144285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7145285809Sscottl } 7146285809Sscottl 7147285809Sscottl discovery->SMPRetries = 0; 7148285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7149285809Sscottl 7150285809Sscottl } 7151285809Sscottl else 7152285809Sscottl { 7153285809Sscottl /* keep retrying */ 7154285809Sscottl dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 7155285809Sscottl } 7156285809Sscottl } 7157285809Sscottl 7158285809Sscottl return; 7159285809Sscottl} 7160285809Sscottl 7161285809Sscottl 7162285809Sscottl/* expander configuring timer */ 7163285809SscottlosGLOBAL void 7164285809SscottldmDiscoveryConfiguringTimer(dmRoot_t *dmRoot, 7165285809Sscottl dmIntPortContext_t *onePortContext, 7166285809Sscottl dmDeviceData_t *oneDeviceData 7167285809Sscottl ) 7168285809Sscottl{ 7169285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7170285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7171285809Sscottl dmDiscovery_t *discovery; 7172285809Sscottl 7173285809Sscottl DM_DBG3(("dmDiscoveryConfiguringTimer: start\n")); 7174285809Sscottl DM_DBG3(("dmDiscoveryConfiguringTimer: pid %d\n", onePortContext->id)); 7175285809Sscottl 7176285809Sscottl discovery = &(onePortContext->discovery); 7177285809Sscottl 7178285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7179285809Sscottl if (discovery->discoveryTimer.timerRunning == agTRUE) 7180285809Sscottl { 7181285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7182285809Sscottl dmKillTimer( 7183285809Sscottl dmRoot, 7184285809Sscottl &discovery->discoveryTimer 7185285809Sscottl ); 7186285809Sscottl } 7187285809Sscottl else 7188285809Sscottl { 7189285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7190285809Sscottl } 7191285809Sscottl 7192285809Sscottl DM_DBG3(("dmDiscoveryConfiguringTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7193285809Sscottl DM_DBG3(("dmDiscoveryConfiguringTimer: Timervalue %d\n", DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick)); 7194285809Sscottl 7195285809Sscottl dmSetTimerRequest( 7196285809Sscottl dmRoot, 7197285809Sscottl &discovery->discoveryTimer, 7198285809Sscottl DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick, 7199285809Sscottl dmDiscoveryConfiguringTimerCB, 7200285809Sscottl onePortContext, 7201285809Sscottl oneDeviceData, 7202285809Sscottl agNULL 7203285809Sscottl ); 7204285809Sscottl 7205285809Sscottl dmAddTimer ( 7206285809Sscottl dmRoot, 7207285809Sscottl &dmAllShared->timerlist, 7208285809Sscottl &discovery->discoveryTimer 7209285809Sscottl ); 7210285809Sscottl 7211285809Sscottl 7212285809Sscottl return; 7213285809Sscottl} 7214285809Sscottl 7215285809Sscottl 7216285809SscottlosGLOBAL void 7217285809SscottldmDiscoveryConfiguringTimerCB( 7218285809Sscottl dmRoot_t * dmRoot, 7219285809Sscottl void * timerData1, 7220285809Sscottl void * timerData2, 7221285809Sscottl void * timerData3 7222285809Sscottl ) 7223285809Sscottl{ 7224285809Sscottl dmIntPortContext_t *onePortContext = agNULL; 7225285809Sscottl dmDiscovery_t *discovery = agNULL; 7226285809Sscottl dmDeviceData_t *oneDeviceData = agNULL; 7227285809Sscottl 7228285809Sscottl onePortContext = (dmIntPortContext_t *)timerData1; 7229285809Sscottl oneDeviceData = (dmDeviceData_t *)timerData2; 7230285809Sscottl discovery = &(onePortContext->discovery); 7231285809Sscottl 7232285809Sscottl DM_DBG3(("dmDiscoveryConfiguringTimerCB: start\n")); 7233285809Sscottl 7234285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7235285809Sscottl if (discovery->discoveryTimer.timerRunning == agTRUE) 7236285809Sscottl { 7237285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7238285809Sscottl dmKillTimer( 7239285809Sscottl dmRoot, 7240285809Sscottl &discovery->discoveryTimer 7241285809Sscottl ); 7242285809Sscottl } 7243285809Sscottl else 7244285809Sscottl { 7245285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7246285809Sscottl } 7247285809Sscottl 7248285809Sscottl if (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) 7249285809Sscottl { 7250285809Sscottl dmReportGeneralSend(dmRoot, oneDeviceData); 7251285809Sscottl } 7252285809Sscottl return; 7253285809Sscottl} 7254285809Sscottl 7255285809SscottlosGLOBAL void 7256285809SscottldmConfigureRouteTimer(dmRoot_t *dmRoot, 7257285809Sscottl dmIntPortContext_t *onePortContext, 7258285809Sscottl dmExpander_t *oneExpander, 7259285809Sscottl smpRespDiscover_t *pdmSMPDiscoverResp, 7260285809Sscottl smpRespDiscover2_t *pdmSMPDiscover2Resp 7261285809Sscottl ) 7262285809Sscottl{ 7263285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7264285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7265285809Sscottl dmDiscovery_t *discovery; 7266285809Sscottl 7267285809Sscottl DM_DBG3(("dmConfigureRouteTimer: start\n")); 7268285809Sscottl 7269285809Sscottl DM_DBG3(("dmConfigureRouteTimer: pid %d\n", onePortContext->id)); 7270285809Sscottl 7271285809Sscottl discovery = &(onePortContext->discovery); 7272285809Sscottl 7273285809Sscottl DM_DBG3(("dmConfigureRouteTimer: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7274285809Sscottl 7275285809Sscottl DM_DBG3(("dmConfigureRouteTimer: discovery %p \n", discovery)); 7276285809Sscottl 7277285809Sscottl DM_DBG3(("dmConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7278285809Sscottl 7279285809Sscottl DM_DBG3(("dmConfigureRouteTimer: discovery->status %d\n", discovery->status)); 7280285809Sscottl 7281285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7282285809Sscottl if (discovery->configureRouteTimer.timerRunning == agTRUE) 7283285809Sscottl { 7284285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7285285809Sscottl dmKillTimer( 7286285809Sscottl dmRoot, 7287285809Sscottl &discovery->configureRouteTimer 7288285809Sscottl ); 7289285809Sscottl } 7290285809Sscottl else 7291285809Sscottl { 7292285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7293285809Sscottl } 7294285809Sscottl 7295285809Sscottl DM_DBG3(("dmConfigureRouteTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7296285809Sscottl DM_DBG3(("dmConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick)); 7297285809Sscottl 7298285809Sscottl if (oneExpander->SAS2 == 0) 7299285809Sscottl { 7300285809Sscottl /* SAS 1.1 */ 7301285809Sscottl dmSetTimerRequest( 7302285809Sscottl dmRoot, 7303285809Sscottl &discovery->configureRouteTimer, 7304285809Sscottl CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7305285809Sscottl dmConfigureRouteTimerCB, 7306285809Sscottl (void *)onePortContext, 7307285809Sscottl (void *)oneExpander, 7308285809Sscottl (void *)pdmSMPDiscoverResp 7309285809Sscottl ); 7310285809Sscottl } 7311285809Sscottl else 7312285809Sscottl { 7313285809Sscottl /* SAS 2 */ 7314285809Sscottl dmSetTimerRequest( 7315285809Sscottl dmRoot, 7316285809Sscottl &discovery->configureRouteTimer, 7317285809Sscottl CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7318285809Sscottl dmConfigureRouteTimerCB, 7319285809Sscottl (void *)onePortContext, 7320285809Sscottl (void *)oneExpander, 7321285809Sscottl (void *)pdmSMPDiscover2Resp 7322285809Sscottl ); 7323285809Sscottl } 7324285809Sscottl dmAddTimer ( 7325285809Sscottl dmRoot, 7326285809Sscottl &dmAllShared->timerlist, 7327285809Sscottl &discovery->configureRouteTimer 7328285809Sscottl ); 7329285809Sscottl 7330285809Sscottl return; 7331285809Sscottl} 7332285809Sscottl 7333285809Sscottl 7334285809SscottlosGLOBAL void 7335285809SscottldmConfigureRouteTimerCB( 7336285809Sscottl dmRoot_t * dmRoot, 7337285809Sscottl void * timerData1, 7338285809Sscottl void * timerData2, 7339285809Sscottl void * timerData3 7340285809Sscottl ) 7341285809Sscottl{ 7342285809Sscottl dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7343285809Sscottl dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7344285809Sscottl dmIntPortContext_t *onePortContext; 7345285809Sscottl dmExpander_t *oneExpander; 7346285809Sscottl smpRespDiscover_t *pdmSMPDiscoverResp = agNULL; 7347285809Sscottl smpRespDiscover2_t *pdmSMPDiscover2Resp = agNULL; 7348285809Sscottl dmDiscovery_t *discovery; 7349285809Sscottl 7350285809Sscottl 7351285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: start\n")); 7352285809Sscottl 7353285809Sscottl onePortContext = (dmIntPortContext_t *)timerData1; 7354285809Sscottl oneExpander = (dmExpander_t *)timerData2; 7355285809Sscottl if (oneExpander->SAS2 == 0) 7356285809Sscottl { 7357285809Sscottl pdmSMPDiscoverResp = (smpRespDiscover_t *)timerData3; 7358285809Sscottl } 7359285809Sscottl else 7360285809Sscottl { 7361285809Sscottl pdmSMPDiscover2Resp = (smpRespDiscover2_t *)timerData3; 7362285809Sscottl } 7363285809Sscottl discovery = &(onePortContext->discovery); 7364285809Sscottl 7365285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7366285809Sscottl 7367285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: discovery %p\n", discovery)); 7368285809Sscottl 7369285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7370285809Sscottl 7371285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: discovery.status %d\n", discovery->status)); 7372285809Sscottl 7373285809Sscottl discovery->configureRouteRetries++; 7374285809Sscottl if (discovery->configureRouteRetries >= dmAllShared->MaxRetryDiscovery) 7375285809Sscottl { 7376285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: retries are over\n")); 7377285809Sscottl 7378285809Sscottl tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7379285809Sscottl if (discovery->configureRouteTimer.timerRunning == agTRUE) 7380285809Sscottl { 7381285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7382285809Sscottl dmKillTimer( 7383285809Sscottl dmRoot, 7384285809Sscottl &discovery->configureRouteTimer 7385285809Sscottl ); 7386285809Sscottl } 7387285809Sscottl else 7388285809Sscottl { 7389285809Sscottl tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7390285809Sscottl } 7391285809Sscottl 7392285809Sscottl discovery->configureRouteRetries = 0; 7393285809Sscottl /* failed the discovery */ 7394285809Sscottl dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7395285809Sscottl 7396285809Sscottl return; 7397285809Sscottl } 7398285809Sscottl 7399285809Sscottl 7400285809Sscottl if (oneExpander->SAS2 == 0) 7401285809Sscottl { 7402285809Sscottl if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7403285809Sscottl { 7404285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscoverExpanderPhy\n")); 7405285809Sscottl dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 7406285809Sscottl discovery->configureRouteRetries = 0; 7407285809Sscottl 7408285809Sscottl dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp); 7409285809Sscottl } 7410285809Sscottl else 7411285809Sscottl { 7412285809Sscottl DM_DBG3(("dmConfigureRouteTimerCB: setting timer again\n")); 7413285809Sscottl /* set the timer again */ 7414285809Sscottl dmSetTimerRequest( 7415285809Sscottl dmRoot, 7416285809Sscottl &discovery->configureRouteTimer, 7417285809Sscottl CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7418285809Sscottl dmConfigureRouteTimerCB, 7419285809Sscottl (void *)onePortContext, 7420285809Sscottl (void *)oneExpander, 7421285809Sscottl (void *)pdmSMPDiscoverResp 7422285809Sscottl ); 7423285809Sscottl 7424285809Sscottl dmAddTimer ( 7425285809Sscottl dmRoot, 7426285809Sscottl &dmAllShared->timerlist, 7427285809Sscottl &discovery->configureRouteTimer 7428285809Sscottl ); 7429285809Sscottl } 7430285809Sscottl } /* SAS 1.1 */ 7431285809Sscottl else 7432285809Sscottl { 7433285809Sscottl /* SAS 2 */ 7434285809Sscottl if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7435285809Sscottl { 7436285809Sscottl DM_DBG2(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscover2ExpanderPhy\n")); 7437285809Sscottl dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 7438285809Sscottl 7439285809Sscottl dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp); 7440285809Sscottl } 7441285809Sscottl else 7442285809Sscottl { 7443285809Sscottl DM_DBG2(("dmConfigureRouteTimerCB: setting timer again\n")); 7444285809Sscottl /* set the timer again */ 7445285809Sscottl dmSetTimerRequest( 7446285809Sscottl dmRoot, 7447285809Sscottl &discovery->configureRouteTimer, 7448285809Sscottl CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7449285809Sscottl dmConfigureRouteTimerCB, 7450285809Sscottl (void *)onePortContext, 7451285809Sscottl (void *)oneExpander, 7452285809Sscottl (void *)pdmSMPDiscover2Resp 7453285809Sscottl ); 7454285809Sscottl 7455285809Sscottl dmAddTimer ( 7456285809Sscottl dmRoot, 7457285809Sscottl &dmAllShared->timerlist, 7458285809Sscottl &discovery->configureRouteTimer 7459285809Sscottl ); 7460285809Sscottl } 7461285809Sscottl } 7462285809Sscottl 7463285809Sscottl return; 7464285809Sscottl} 7465285809Sscottl#endif /* FDS_ DM */ 7466285809Sscottl 7467