1 /******************************************************************************* 2 ** 3 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4 * 5 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 *that the following conditions are met: 7 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 8 *following disclaimer. 9 *2. Redistributions in binary form must reproduce the above copyright notice, 10 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 11 *with the distribution. 12 * 13 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 18 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 21 ** 22 ********************************************************************************/ 23 #include <sys/cdefs.h> 24 __FBSDID("$FreeBSD$"); 25 #include <dev/pms/config.h> 26 27 #include <dev/pms/freebsd/driver/common/osenv.h> 28 #include <dev/pms/freebsd/driver/common/ostypes.h> 29 #include <dev/pms/freebsd/driver/common/osdebug.h> 30 31 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 34 35 #ifdef FDS_DM 36 #include <dev/pms/RefTisa/discovery/api/dm.h> 37 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 38 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 39 40 #include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 41 #include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 42 #include <dev/pms/RefTisa/discovery/dm/dmproto.h> 43 44 /*****************************************************************************/ 45 /*! \brief dmDiscover 46 * 47 * 48 * Purpose: A discovery is started by this function 49 * 50 * \param dmRoot: DM context handle. 51 * \param dmPortContext: Pointer to this instance of port context 52 * \param option: Discovery option 53 * 54 * \return: 55 * DM_RC_SUCCESS 56 * DM_RC_FAILURE 57 * 58 */ 59 /*****************************************************************************/ 60 osGLOBAL bit32 61 dmDiscover( 62 dmRoot_t *dmRoot, 63 dmPortContext_t *dmPortContext, 64 bit32 option) 65 { 66 dmIntPortContext_t *onePortContext = agNULL; 67 bit32 ret = DM_RC_FAILURE; 68 69 DM_DBG3(("dmDiscover: start\n")); 70 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 71 72 if (onePortContext == agNULL) 73 { 74 DM_DBG1(("dmDiscover: onePortContext is NULL!!!\n")); 75 return DM_RC_FAILURE; 76 } 77 78 if (onePortContext->valid == agFALSE) 79 { 80 DM_DBG1(("dmDiscover: invalid port!!!\n")); 81 return DM_RC_FAILURE; 82 } 83 84 if (onePortContext->RegFailed == agTRUE) 85 { 86 DM_DBG1(("dmDiscover: Registration failed!!!\n")); 87 return DM_RC_FAILURE; 88 } 89 90 switch ( option ) 91 { 92 case DM_DISCOVERY_OPTION_FULL_START: 93 DM_DBG3(("dmDiscover: full, pid %d\n", onePortContext->id)); 94 onePortContext->discovery.type = DM_DISCOVERY_OPTION_FULL_START; 95 dmDiscoveryResetMCN(dmRoot, onePortContext); 96 ret = dmFullDiscover(dmRoot, onePortContext); 97 break; 98 case DM_DISCOVERY_OPTION_INCREMENTAL_START: 99 DM_DBG3(("dmDiscover: incremental, pid %d\n", onePortContext->id)); 100 onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 101 dmDiscoveryResetMCN(dmRoot, onePortContext); 102 ret = dmIncrementalDiscover(dmRoot, onePortContext, agFALSE); 103 break; 104 case DM_DISCOVERY_OPTION_ABORT: 105 DM_DBG3(("dmDiscover: abort\n")); 106 if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 107 { 108 if (onePortContext->discovery.pendingSMP == 0) 109 { 110 dmDiscoverAbort(dmRoot, onePortContext); 111 tddmDiscoverCB( 112 dmRoot, 113 onePortContext->dmPortContext, 114 dmDiscAborted 115 ); 116 } 117 else 118 { 119 DM_DBG3(("dmDiscover: abortInProgress\n")); 120 onePortContext->DiscoveryAbortInProgress = agTRUE; 121 tddmDiscoverCB( 122 dmRoot, 123 dmPortContext, 124 dmDiscAbortInProgress 125 ); 126 } 127 } 128 else 129 { 130 DM_DBG3(("dmDiscover: no discovery to abort\n")); 131 tddmDiscoverCB( 132 dmRoot, 133 dmPortContext, 134 dmDiscAbortInvalid 135 ); 136 } 137 ret = DM_RC_SUCCESS; 138 break; 139 default: 140 break; 141 } 142 return ret; 143 } 144 145 osGLOBAL bit32 146 dmFullDiscover( 147 dmRoot_t *dmRoot, 148 dmIntPortContext_t *onePortContext 149 ) 150 { 151 dmExpander_t *oneExpander = agNULL; 152 dmSASSubID_t dmSASSubID; 153 dmDeviceData_t *oneExpDeviceData = agNULL; 154 155 DM_DBG1(("dmFullDiscover: start\n")); 156 157 if (onePortContext->valid == agFALSE) 158 { 159 DM_DBG1(("dmFullDiscover: invalid port!!!\n")); 160 return DM_RC_FAILURE; 161 } 162 163 if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 164 { 165 DM_DBG1(("dmFullDiscover: no two instances of discovery allowed!!!\n")); 166 return DM_RC_FAILURE; 167 } 168 169 onePortContext->DiscoveryState = DM_DSTATE_STARTED; 170 171 dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 172 dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 173 174 /* check OnePortContext->discovery.discoveringExpanderList */ 175 oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 176 if (oneExpander != agNULL) 177 { 178 oneExpDeviceData = oneExpander->dmDevice; 179 } 180 else 181 { 182 /* check dmAllShared->mainExpanderList */ 183 oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 184 if (oneExpander != agNULL) 185 { 186 oneExpDeviceData = oneExpander->dmDevice; 187 } 188 } 189 190 if (oneExpDeviceData != agNULL) 191 { 192 dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 193 dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 194 oneExpDeviceData->registered = agTRUE; 195 dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 196 } 197 else 198 { 199 DM_DBG1(("dmFullDiscover:oneExpDeviceData is NULL!!!\n")); 200 return DM_RC_FAILURE; 201 } 202 203 dmUpStreamDiscoverStart(dmRoot, onePortContext); 204 205 return DM_RC_SUCCESS; 206 } 207 208 osGLOBAL bit32 209 dmIncrementalDiscover( 210 dmRoot_t *dmRoot, 211 dmIntPortContext_t *onePortContext, 212 bit32 flag 213 ) 214 { 215 dmExpander_t *oneExpander = agNULL; 216 dmSASSubID_t dmSASSubID; 217 dmDeviceData_t *oneExpDeviceData = agNULL; 218 219 DM_DBG1(("dmIncrementalDiscover: start\n")); 220 221 if (onePortContext->valid == agFALSE) 222 { 223 DM_DBG1(("dmIncrementalDiscover: invalid port!!!\n")); 224 return DM_RC_FAILURE; 225 } 226 227 /* TDM triggerred; let go DM triggerred */ 228 if (flag == agFALSE) 229 { 230 if (onePortContext->DiscoveryState == DM_DSTATE_STARTED) 231 { 232 DM_DBG1(("dmIncrementalDiscover: no two instances of discovery allowed!!!\n")); 233 return DM_RC_FAILURE; 234 } 235 } 236 237 onePortContext->DiscoveryState = DM_DSTATE_STARTED; 238 onePortContext->discovery.type = DM_DISCOVERY_OPTION_INCREMENTAL_START; 239 240 dmSASSubID.sasAddressHi = onePortContext->sasRemoteAddressHi; 241 dmSASSubID.sasAddressLo = onePortContext->sasRemoteAddressLo; 242 243 /* check OnePortContext->discovery.discoveringExpanderList */ 244 oneExpander = dmExpFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 245 if (oneExpander != agNULL) 246 { 247 oneExpDeviceData = oneExpander->dmDevice; 248 } 249 else 250 { 251 /* check dmAllShared->mainExpanderList */ 252 oneExpander = dmExpMainListFind(dmRoot, onePortContext, dmSASSubID.sasAddressHi, dmSASSubID.sasAddressLo); 253 if (oneExpander != agNULL) 254 { 255 oneExpDeviceData = oneExpander->dmDevice; 256 } 257 } 258 259 if (oneExpDeviceData != agNULL) 260 { 261 dmSASSubID.initiator_ssp_stp_smp = oneExpDeviceData->initiator_ssp_stp_smp; 262 dmSASSubID.target_ssp_stp_smp = oneExpDeviceData->target_ssp_stp_smp; 263 oneExpDeviceData->registered = agTRUE; 264 dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, oneExpDeviceData, 0xFF); 265 } 266 else 267 { 268 DM_DBG1(("dmIncrementalDiscover:oneExpDeviceData is NULL!!!\n")); 269 return DM_RC_FAILURE; 270 } 271 272 dmUpStreamDiscoverStart(dmRoot, onePortContext); 273 274 return DM_RC_SUCCESS; 275 } 276 277 osGLOBAL void 278 dmUpStreamDiscoverStart( 279 dmRoot_t *dmRoot, 280 dmIntPortContext_t *onePortContext 281 ) 282 { 283 // dmExpander_t *oneExpander = agNULL; 284 bit32 sasAddressHi, sasAddressLo; 285 dmDeviceData_t *oneDeviceData; 286 dmExpander_t *oneExpander = agNULL; 287 288 DM_DBG3(("dmUpStreamDiscoverStart: start\n")); 289 if (onePortContext->valid == agFALSE) 290 { 291 DM_DBG1(("dmUpStreamDiscoverStart: invalid port!!!\n")); 292 return; 293 } 294 /* 295 at this point, the 1st expander should have been registered. 296 find an expander from onePortContext 297 */ 298 sasAddressHi = onePortContext->sasRemoteAddressHi; 299 sasAddressLo = onePortContext->sasRemoteAddressLo; 300 DM_DBG3(("dmUpStreamDiscoverStart: Port Remote AddrHi 0x%08x Remote AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 301 302 oneDeviceData = dmDeviceFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 303 304 // oneDeviceData = oneExpander->dmDevice; 305 // start here 306 onePortContext->discovery.status = DISCOVERY_UP_STREAM; 307 if (oneDeviceData == agNULL) 308 { 309 DM_DBG1(("dmUpStreamDiscoverStart: oneExpander is NULL, wrong!!!\n")); 310 return; 311 } 312 else 313 { 314 if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 315 || 316 (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 317 || 318 DEVICE_IS_SMP_TARGET(oneDeviceData) 319 ) 320 { 321 #if 1 /* for incremental discovery */ 322 /* start here: if not on discoveringExpanderList, alloc and add 323 dmNewEXPorNot() 324 */ 325 oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 326 if ( oneExpander == agNULL) 327 { 328 /* alloc and add */ 329 oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 330 if ( oneExpander != agNULL) 331 { 332 dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 333 } 334 else 335 { 336 DM_DBG1(("dmUpStreamDiscoverStart: failed to allocate expander or discovey aborted!!!\n")); 337 return; 338 } 339 } 340 #endif 341 342 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 343 } 344 else 345 { 346 DM_DBG1(("dmUpStreamDiscoverStart: oneDeviceData is not an Expander did %d, wrong!!!\n", oneDeviceData->id)); 347 return; 348 } 349 } 350 return; 351 } 352 353 /* sends report general */ 354 osGLOBAL void 355 dmUpStreamDiscovering( 356 dmRoot_t *dmRoot, 357 dmIntPortContext_t *onePortContext, 358 dmDeviceData_t *oneDeviceData 359 ) 360 { 361 dmList_t *ExpanderList; 362 dmExpander_t *oneNextExpander = agNULL; 363 364 DM_DBG3(("dmUpStreamDiscovering: start\n")); 365 366 if (onePortContext->valid == agFALSE) 367 { 368 DM_DBG1(("dmUpStreamDiscovering: invalid port!!!\n")); 369 return; 370 } 371 372 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 373 if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 374 { 375 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 376 DM_DBG3(("dmUpStreamDiscovering: should be the end\n")); 377 oneNextExpander = agNULL; 378 } 379 else 380 { 381 DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList)); 382 oneNextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 383 if ( oneNextExpander != agNULL) 384 { 385 DMLIST_ENQUEUE_AT_HEAD(&(oneNextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 386 DM_DBG3(("dmUpStreamDiscovering tdsaSASUpStreamDiscovering: dequeue head\n")); 387 DM_DBG3(("dmUpStreamDiscovering: expander id %d\n", oneNextExpander->id)); 388 } 389 else 390 { 391 DM_DBG1(("dmUpStreamDiscovering: oneNextExpander is NULL!!!\n")); 392 } 393 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 394 395 } 396 397 if (oneNextExpander != agNULL) 398 { 399 dmReportGeneralSend(dmRoot, oneNextExpander->dmDevice); 400 } 401 else 402 { 403 DM_DBG3(("dmUpStreamDiscovering: No more expander list\n")); 404 dmDownStreamDiscoverStart(dmRoot, onePortContext, oneDeviceData); 405 } 406 407 return; 408 } 409 410 osGLOBAL void 411 dmDownStreamDiscoverStart( 412 dmRoot_t *dmRoot, 413 dmIntPortContext_t *onePortContext, 414 dmDeviceData_t *oneDeviceData 415 ) 416 { 417 dmExpander_t *UpStreamExpander; 418 dmExpander_t *oneExpander; 419 420 DM_DBG3(("dmDownStreamDiscoverStart: start\n")); 421 422 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 423 { 424 DM_DBG1(("dmDownStreamDiscoverStart: invalid port or aborted discovery!!!\n")); 425 return; 426 } 427 428 /* set discovery status */ 429 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 430 431 /* If it's an expander */ 432 if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 433 || (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 434 || DEVICE_IS_SMP_TARGET(oneDeviceData) 435 ) 436 { 437 oneExpander = oneDeviceData->dmExpander; 438 UpStreamExpander = oneExpander->dmUpStreamExpander; 439 440 /* If the two expanders are the root of two edge sets; sub-to-sub */ 441 if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->dmUpStreamExpander == oneExpander ) ) 442 { 443 DM_DBG3(("dmDownStreamDiscoverStart: Root found pExpander=%p pUpStreamExpander=%p\n", 444 oneExpander, UpStreamExpander)); 445 //Saves the root expander 446 onePortContext->discovery.RootExp = oneExpander; 447 DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 448 DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 449 450 /* reset up stream inform for pExpander */ 451 oneExpander->dmUpStreamExpander = agNULL; 452 /* Add the pExpander to discovering list */ 453 dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 454 455 /* reset up stream inform for oneExpander */ 456 UpStreamExpander->dmUpStreamExpander = agNULL; 457 /* Add the UpStreamExpander to discovering list */ 458 dmDiscoveringExpanderAdd(dmRoot, onePortContext, UpStreamExpander); 459 } 460 /* If the two expanders are not the root of two edge sets. eg) one root */ 461 else 462 { 463 //Saves the root expander 464 onePortContext->discovery.RootExp = oneExpander; 465 466 DM_DBG3(("dmDownStreamDiscoverStart: NO Root pExpander=%p\n", oneExpander)); 467 DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 468 DM_DBG3(("dmDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 469 470 /* (2.2.2.1) Add the pExpander to discovering list */ 471 dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 472 } 473 } 474 475 /* Continue down stream discovering */ 476 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 477 478 return; 479 } 480 481 osGLOBAL void 482 dmDownStreamDiscovering( 483 dmRoot_t *dmRoot, 484 dmIntPortContext_t *onePortContext, 485 dmDeviceData_t *oneDeviceData 486 ) 487 { 488 dmExpander_t *NextExpander = agNULL; 489 dmList_t *ExpanderList; 490 491 DM_DBG3(("dmDownStreamDiscovering: start\n")); 492 493 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 494 { 495 DM_DBG1(("dmDownStreamDiscovering: invalid port or aborted discovery!!!\n")); 496 return; 497 } 498 499 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 500 if (DMLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 501 { 502 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 503 DM_DBG3(("dmDownStreamDiscovering: should be the end\n")); 504 NextExpander = agNULL; 505 } 506 else 507 { 508 DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList));; 509 NextExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 510 if ( NextExpander != agNULL) 511 { 512 DMLIST_ENQUEUE_AT_HEAD(&(NextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList));; 513 DM_DBG3(("dmDownStreamDiscovering tdsaSASDownStreamDiscovering: dequeue head\n")); 514 DM_DBG3(("dmDownStreamDiscovering: expander id %d\n", NextExpander->id)); 515 } 516 else 517 { 518 DM_DBG1(("dmDownStreamDiscovering: NextExpander is NULL!!!\n")); 519 } 520 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 521 522 } 523 524 /* If there is an expander for continue discoving */ 525 if ( NextExpander != agNULL) 526 { 527 DM_DBG3(("dmDownStreamDiscovering: Found pNextExpander=%p discoveryStatus=0x%x\n", 528 NextExpander, onePortContext->discovery.status)); 529 530 switch (onePortContext->discovery.status) 531 { 532 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 533 case DISCOVERY_DOWN_STREAM: 534 /* Send report general for the next expander */ 535 DM_DBG3(("dmDownStreamDiscovering: DownStream pNextExpander=%p\n", NextExpander)); 536 DM_DBG3(("dmDownStreamDiscovering: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 537 DM_DBG3(("dmDownStreamDiscovering: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 538 539 DM_DBG3(("dmDownStreamDiscovering: 2nd oneDeviceData %p did %d\n", NextExpander->dmDevice, NextExpander->dmDevice->id)); 540 DM_DBG3(("dmDownStreamDiscovering: 2nd oneExpander %p did %d\n", NextExpander, NextExpander->id)); 541 DM_DBG3(("dmDownStreamDiscovering: 2nd used oneExpander %p did %d\n", NextExpander->dmDevice->dmExpander, NextExpander->dmDevice->dmExpander->id)); 542 543 if (NextExpander != NextExpander->dmDevice->dmExpander) 544 { 545 DM_DBG3(("dmDownStreamDiscovering: wrong!!!\n")); 546 } 547 548 549 dmReportGeneralSend(dmRoot, NextExpander->dmDevice); 550 break; 551 /* If the discovery status is DISCOVERY_CONFIG_ROUTING */ 552 case DISCOVERY_CONFIG_ROUTING: 553 case DISCOVERY_REPORT_PHY_SATA: 554 555 /* set discovery status */ 556 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 557 558 DM_DBG3(("dmDownStreamDiscovering: pPort->discovery.status=DISCOVERY_CONFIG_ROUTING, make it DOWN_STREAM\n")); 559 /* If not the last phy */ 560 if ( NextExpander->discoveringPhyId < NextExpander->dmDevice->numOfPhys ) 561 { 562 DM_DBG3(("dmDownStreamDiscovering: pNextExpander->discoveringPhyId=0x%x pNextExpander->numOfPhys=0x%x. Send More Discover\n", 563 NextExpander->discoveringPhyId, NextExpander->dmDevice->numOfPhys)); 564 /* Send discover for the next expander */ 565 dmDiscoverSend(dmRoot, NextExpander->dmDevice); 566 } 567 /* If it's the last phy */ 568 else 569 { 570 DM_DBG3(("dmDownStreamDiscovering: Last Phy, remove expander%p start DownStream=%p\n", 571 NextExpander, NextExpander->dmDevice)); 572 dmDiscoveringExpanderRemove(dmRoot, onePortContext, NextExpander); 573 dmDownStreamDiscovering(dmRoot, onePortContext, NextExpander->dmDevice); 574 } 575 break; 576 577 default: 578 DM_DBG3(("dmDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status)); 579 } 580 } 581 /* If no expander for continue discoving */ 582 else 583 { 584 DM_DBG3(("dmDownStreamDiscovering: No more expander DONE\n")); 585 /* discover done */ 586 dmDiscoverDone(dmRoot, onePortContext, DM_RC_SUCCESS); 587 } 588 589 590 return; 591 } 592 593 osGLOBAL void 594 dmUpStreamDiscoverExpanderPhy( 595 dmRoot_t *dmRoot, 596 dmIntPortContext_t *onePortContext, 597 dmExpander_t *oneExpander, 598 smpRespDiscover_t *pDiscoverResp 599 ) 600 { 601 agsaSASIdentify_t sasIdentify; 602 dmSASSubID_t dmSASSubID; 603 bit32 attachedSasHi, attachedSasLo; 604 dmExpander_t *AttachedExpander = agNULL; 605 bit8 connectionRate; 606 dmDeviceData_t *oneDeviceData = agNULL; 607 dmDeviceData_t *AttachedDevice = agNULL; 608 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 609 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 610 611 612 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: start\n")); 613 614 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 615 { 616 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 617 return; 618 } 619 620 if (oneExpander != oneExpander->dmDevice->dmExpander) 621 { 622 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: wrong!!!\n")); 623 } 624 625 dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 626 627 oneDeviceData = oneExpander->dmDevice; 628 629 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 630 oneExpander->discoveringPhyId, 631 oneDeviceData->SASAddressID.sasAddressHi, 632 oneDeviceData->SASAddressID.sasAddressLo)); 633 634 DM_DBG3((" Attached device: %s\n", 635 ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 636 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 637 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 638 639 640 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 641 { 642 DM_DBG3((" SAS address : %08x-%08x\n", 643 DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 644 DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 645 DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 646 DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 647 DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 648 DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 649 DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 650 DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 651 DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 652 DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 653 DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 654 } 655 656 /* for debugging */ 657 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 658 { 659 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 660 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 661 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 662 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 663 return; 664 } 665 666 /* saving routing attribute for non self-configuring expanders */ 667 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = (bit8)DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 668 669 if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 670 { 671 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 672 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 673 { 674 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 675 676 /* discovery error */ 677 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 678 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 679 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 680 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 681 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 682 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 683 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 684 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 685 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 686 687 /* (2.1.3) discovery done */ 688 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 689 return; 690 } 691 } 692 else 693 { 694 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 695 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 696 { 697 /* Setup sasIdentify for the attached device */ 698 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 699 sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70); 700 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 701 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 702 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 703 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 704 705 /* incremental discovery */ 706 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 707 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 708 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 709 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 710 711 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 712 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 713 714 /* If the phy has subtractive routing attribute */ 715 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 716 { 717 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 718 /* Setup upstream phys */ 719 dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 720 /* If the expander already has an upsteam device set up */ 721 if (oneExpander->hasUpStreamDevice == agTRUE) 722 { 723 /* just to update MCN */ 724 dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 725 /* If the sas address doesn't match */ 726 if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 727 (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 728 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 729 DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 730 ) 731 { 732 /* TODO: discovery error, callback */ 733 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 734 /* call back to notify discovery error */ 735 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 736 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 737 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 738 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 739 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 740 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 741 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 742 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 743 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 744 /* discovery done */ 745 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 746 } 747 } 748 else 749 { 750 /* Setup SAS address for up stream device */ 751 oneExpander->hasUpStreamDevice = agTRUE; 752 oneExpander->upStreamSASAddressHi = attachedSasHi; 753 oneExpander->upStreamSASAddressLo = attachedSasLo; 754 if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 755 || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 756 { 757 /* Find the device from the discovered list */ 758 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 759 /* New device, If the device has been discovered before */ 760 if ( AttachedDevice != agNULL) /* old device */ 761 { 762 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Seen This Device Before\n")); 763 /* If attached device is an edge expander */ 764 if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 765 { 766 /* The attached device is an expander */ 767 AttachedExpander = AttachedDevice->dmExpander; 768 /* If the two expanders are the root of the two edge expander sets */ 769 if ( (AttachedExpander->upStreamSASAddressHi == 770 DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 771 && (AttachedExpander->upStreamSASAddressLo == 772 DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 773 { 774 /* Setup upstream expander for the pExpander */ 775 oneExpander->dmUpStreamExpander = AttachedExpander; 776 } 777 /* If the two expanders are not the root of the two edge expander sets */ 778 else 779 { 780 /* TODO: loop found, discovery error, callback */ 781 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: **** Topology Error loop detection!!!\n")); 782 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 783 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 784 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 785 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 786 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 787 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 788 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 789 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 790 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 791 /* discovery done */ 792 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 793 } 794 } 795 /* If attached device is not an edge expander */ 796 else 797 { 798 /*TODO: should not happen, ASSERT */ 799 DM_DBG3(("dmUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 800 } 801 } /* AttachedExpander != agNULL */ 802 /* New device, If the device has not been discovered before */ 803 else /* new device */ 804 { 805 /* Add the device */ 806 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: New device\n")); 807 /* read minimum rate from the configuration 808 onePortContext->LinkRate is SPC's local link rate 809 */ 810 connectionRate = (bit8)MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 811 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 812 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 813 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 814 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 815 { 816 /* incremental discovery */ 817 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 818 { 819 AttachedDevice = dmPortSASDeviceAdd( 820 dmRoot, 821 onePortContext, 822 sasIdentify, 823 agFALSE, 824 connectionRate, 825 dmAllShared->itNexusTimeout, 826 0, 827 STP_DEVICE_TYPE, 828 oneDeviceData, 829 oneExpander, 830 pDiscoverResp->phyIdentifier 831 ); 832 } 833 else 834 { 835 /* incremental discovery */ 836 AttachedDevice = dmFindRegNValid( 837 dmRoot, 838 onePortContext, 839 &dmSASSubID 840 ); 841 /* not registered and not valid; add this*/ 842 if (AttachedDevice == agNULL) 843 { 844 AttachedDevice = dmPortSASDeviceAdd( 845 dmRoot, 846 onePortContext, 847 sasIdentify, 848 agFALSE, 849 connectionRate, 850 dmAllShared->itNexusTimeout, 851 0, 852 STP_DEVICE_TYPE, 853 oneDeviceData, 854 oneExpander, 855 pDiscoverResp->phyIdentifier 856 ); 857 } 858 } 859 } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 860 else 861 { 862 /* incremental discovery */ 863 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 864 { 865 AttachedDevice = dmPortSASDeviceAdd( 866 dmRoot, 867 onePortContext, 868 sasIdentify, 869 agFALSE, 870 connectionRate, 871 dmAllShared->itNexusTimeout, 872 0, 873 SAS_DEVICE_TYPE, 874 oneDeviceData, 875 oneExpander, 876 pDiscoverResp->phyIdentifier 877 ); 878 } 879 else 880 { 881 /* incremental discovery */ 882 AttachedDevice = dmFindRegNValid( 883 dmRoot, 884 onePortContext, 885 &dmSASSubID 886 ); 887 /* not registered and not valid; add this*/ 888 if (AttachedDevice == agNULL) 889 { 890 AttachedDevice = dmPortSASDeviceAdd( 891 dmRoot, 892 onePortContext, 893 sasIdentify, 894 agFALSE, 895 connectionRate, 896 dmAllShared->itNexusTimeout, 897 0, 898 SAS_DEVICE_TYPE, 899 oneDeviceData, 900 oneExpander, 901 pDiscoverResp->phyIdentifier 902 ); 903 } 904 } 905 } 906 /* If the device is added successfully */ 907 if ( AttachedDevice != agNULL) 908 { 909 910 /* (3.1.2.3.2.3.2.1) callback about new device */ 911 if ( DISCRSP_IS_SSP_TARGET(pDiscoverResp) 912 || DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 913 || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 914 || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 915 { 916 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 917 attachedSasHi, attachedSasLo)); 918 } 919 else 920 { 921 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n")); 922 } 923 /* If the attached device is an expander */ 924 if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 925 || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 926 { 927 /* Allocate an expander data structure */ 928 AttachedExpander = dmDiscoveringExpanderAlloc( 929 dmRoot, 930 onePortContext, 931 AttachedDevice 932 ); 933 934 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander)); 935 /* If allocate successfully */ 936 if ( AttachedExpander != agNULL) 937 { 938 /* Add the pAttachedExpander to discovering list */ 939 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 940 /* Setup upstream expander for the pExpander */ 941 oneExpander->dmUpStreamExpander = AttachedExpander; 942 } 943 /* If failed to allocate */ 944 else 945 { 946 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 947 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 948 } 949 } 950 /* If the attached device is an end device */ 951 else 952 { 953 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: Found end device\n")); 954 /* LP2006-05-26 added upstream device to the newly found device */ 955 AttachedDevice->dmExpander = oneExpander; 956 oneExpander->dmUpStreamExpander = agNULL; 957 } 958 } 959 else 960 { 961 DM_DBG1(("dmUpStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 962 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 963 } 964 965 966 967 } /* else, new device */ 968 } /* onePortContext->sasLocalAddressLo != attachedSasLo */ 969 } /* else */ 970 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 971 } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 972 } /* big else */ 973 974 975 976 oneExpander->discoveringPhyId ++; 977 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 978 { 979 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 980 { 981 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 982 /* continue discovery for the next phy */ 983 dmDiscoverSend(dmRoot, oneDeviceData); 984 } 985 else 986 { 987 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 988 989 /* for MCN */ 990 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 991 /* remove the expander from the discovering list */ 992 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 993 /* continue upstream discovering */ 994 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 995 } 996 } 997 else 998 { 999 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1000 1001 } 1002 1003 DM_DBG3(("dmUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 1004 1005 return; 1006 } 1007 1008 osGLOBAL void 1009 dmUpStreamDiscover2ExpanderPhy( 1010 dmRoot_t *dmRoot, 1011 dmIntPortContext_t *onePortContext, 1012 dmExpander_t *oneExpander, 1013 smpRespDiscover2_t *pDiscoverResp 1014 ) 1015 { 1016 dmDeviceData_t *oneDeviceData; 1017 dmDeviceData_t *AttachedDevice = agNULL; 1018 dmExpander_t *AttachedExpander; 1019 agsaSASIdentify_t sasIdentify; 1020 bit8 connectionRate; 1021 bit32 attachedSasHi, attachedSasLo; 1022 dmSASSubID_t dmSASSubID; 1023 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1024 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1025 1026 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: start\n")); 1027 1028 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1029 { 1030 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 1031 return; 1032 } 1033 1034 if (oneExpander != oneExpander->dmDevice->dmExpander) 1035 { 1036 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: wrong!!!\n")); 1037 } 1038 1039 dm_memset(&sasIdentify, 0, sizeof(agsaSASIdentify_t)); 1040 1041 oneDeviceData = oneExpander->dmDevice; 1042 1043 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 1044 oneExpander->discoveringPhyId, 1045 oneDeviceData->SASAddressID.sasAddressHi, 1046 oneDeviceData->SASAddressID.sasAddressLo)); 1047 1048 DM_DBG2((" Attached device: %s\n", 1049 ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 1050 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 1051 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 1052 1053 1054 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1055 { 1056 DM_DBG2((" SAS address : %08x-%08x\n", 1057 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 1058 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 1059 DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 1060 DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 1061 DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1062 DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1063 DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1064 DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 1065 DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 1066 DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 1067 DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 1068 } 1069 1070 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 1071 { 1072 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 1073 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 1074 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 1075 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1076 return; 1077 } 1078 1079 /* saving routing attribute for non self-configuring expanders */ 1080 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 1081 1082 if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 1083 { 1084 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 1085 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1086 { 1087 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing on fanout expander device!!!\n")); 1088 1089 /* discovery error */ 1090 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1091 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1092 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1093 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1094 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1095 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1096 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1097 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1098 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1099 1100 /* (2.1.3) discovery done */ 1101 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1102 return; 1103 } 1104 } 1105 else 1106 { 1107 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 1108 1109 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1110 { 1111 /* Setup sasIdentify for the attached device */ 1112 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1113 sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 1114 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1115 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1116 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1117 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1118 1119 /* incremental discovery */ 1120 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1121 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1122 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1123 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1124 1125 attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1126 attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1127 1128 /* If the phy has subtractive routing attribute */ 1129 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1130 { 1131 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 1132 /* Setup upstream phys */ 1133 dmExpanderUpStreamPhyAdd(dmRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 1134 /* If the expander already has an upsteam device set up */ 1135 if (oneExpander->hasUpStreamDevice == agTRUE) 1136 { 1137 /* just to update MCN */ 1138 dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1139 /* If the sas address doesn't match */ 1140 if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 1141 (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 1142 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1143 SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1144 ) 1145 { 1146 /* TODO: discovery error, callback */ 1147 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1148 /* call back to notify discovery error */ 1149 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1150 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1151 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1152 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1153 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1154 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1155 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1156 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1157 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1158 /* discovery done */ 1159 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1160 } 1161 } 1162 else 1163 { 1164 /* Setup SAS address for up stream device */ 1165 oneExpander->hasUpStreamDevice = agTRUE; 1166 oneExpander->upStreamSASAddressHi = attachedSasHi; 1167 oneExpander->upStreamSASAddressLo = attachedSasLo; 1168 1169 if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 1170 || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 1171 { 1172 /* Find the device from the discovered list */ 1173 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1174 /* If the device has been discovered before */ 1175 if ( AttachedDevice != agNULL) 1176 { 1177 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Seen This Device Before\n")); 1178 /* If attached device is an edge expander */ 1179 if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 1180 { 1181 /* The attached device is an expander */ 1182 AttachedExpander = AttachedDevice->dmExpander; 1183 /* If the two expanders are the root of the two edge expander sets */ 1184 if ( (AttachedExpander->upStreamSASAddressHi == 1185 DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1186 && (AttachedExpander->upStreamSASAddressLo == 1187 DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 1188 { 1189 /* Setup upstream expander for the pExpander */ 1190 oneExpander->dmUpStreamExpander = AttachedExpander; 1191 } 1192 /* If the two expanders are not the root of the two edge expander sets */ 1193 else 1194 { 1195 /* TODO: loop found, discovery error, callback */ 1196 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: **** Topology Error loop detection!!!\n")); 1197 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1198 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1199 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1200 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1201 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1202 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1203 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1204 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1205 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1206 /* discovery done */ 1207 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1208 } 1209 } 1210 /* If attached device is not an edge expander */ 1211 else 1212 { 1213 /*TODO: should not happen, ASSERT */ 1214 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, *** Attached Device is not Edge. Confused!!!\n")); 1215 } 1216 } 1217 /* If the device has not been discovered before */ 1218 else 1219 { 1220 /* Add the device */ 1221 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: New device\n")); 1222 /* read minimum rate from the configuration 1223 onePortContext->LinkRate is SPC's local link rate 1224 */ 1225 connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 1226 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 1227 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 1228 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 1229 //hhhhhhhh 1230 if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 1231 { 1232 /* incremental discovery */ 1233 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1234 { 1235 AttachedDevice = dmPortSASDeviceAdd( 1236 dmRoot, 1237 onePortContext, 1238 sasIdentify, 1239 agFALSE, 1240 connectionRate, 1241 dmAllShared->itNexusTimeout, 1242 0, 1243 STP_DEVICE_TYPE, 1244 oneDeviceData, 1245 oneExpander, 1246 pDiscoverResp->phyIdentifier 1247 ); 1248 } 1249 else 1250 { 1251 /* incremental discovery */ 1252 AttachedDevice = dmFindRegNValid( 1253 dmRoot, 1254 onePortContext, 1255 &dmSASSubID 1256 ); 1257 /* not registered and not valid; add this*/ 1258 if (AttachedDevice == agNULL) 1259 { 1260 AttachedDevice = dmPortSASDeviceAdd( 1261 dmRoot, 1262 onePortContext, 1263 sasIdentify, 1264 agFALSE, 1265 connectionRate, 1266 dmAllShared->itNexusTimeout, 1267 0, 1268 STP_DEVICE_TYPE, 1269 oneDeviceData, 1270 oneExpander, 1271 pDiscoverResp->phyIdentifier 1272 ); 1273 } 1274 } 1275 } 1276 else 1277 { 1278 /* incremental discovery */ 1279 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1280 { 1281 AttachedDevice = dmPortSASDeviceAdd( 1282 dmRoot, 1283 onePortContext, 1284 sasIdentify, 1285 agFALSE, 1286 connectionRate, 1287 dmAllShared->itNexusTimeout, 1288 0, 1289 SAS_DEVICE_TYPE, 1290 oneDeviceData, 1291 oneExpander, 1292 pDiscoverResp->phyIdentifier 1293 ); 1294 } 1295 else 1296 { 1297 /* incremental discovery */ 1298 AttachedDevice = dmFindRegNValid( 1299 dmRoot, 1300 onePortContext, 1301 &dmSASSubID 1302 ); 1303 /* not registered and not valid; add this*/ 1304 if (AttachedDevice == agNULL) 1305 { 1306 AttachedDevice = dmPortSASDeviceAdd( 1307 dmRoot, 1308 onePortContext, 1309 sasIdentify, 1310 agFALSE, 1311 connectionRate, 1312 dmAllShared->itNexusTimeout, 1313 0, 1314 SAS_DEVICE_TYPE, 1315 oneDeviceData, 1316 oneExpander, 1317 pDiscoverResp->phyIdentifier 1318 ); 1319 } 1320 } 1321 } 1322 /* If the device is added successfully */ 1323 if ( AttachedDevice != agNULL) 1324 { 1325 1326 /* (3.1.2.3.2.3.2.1) callback about new device */ 1327 if ( SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp) 1328 || SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 1329 || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 1330 || SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 1331 { 1332 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 1333 attachedSasHi, attachedSasLo)); 1334 } 1335 else 1336 { 1337 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found a SAS STP device.\n")); 1338 } 1339 /* If the attached device is an expander */ 1340 if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1341 || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 1342 { 1343 /* Allocate an expander data structure */ 1344 AttachedExpander = dmDiscoveringExpanderAlloc( 1345 dmRoot, 1346 onePortContext, 1347 AttachedDevice 1348 ); 1349 1350 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found expander=%p\n", AttachedExpander)); 1351 /* If allocate successfully */ 1352 if ( AttachedExpander != agNULL) 1353 { 1354 /* Add the pAttachedExpander to discovering list */ 1355 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1356 /* Setup upstream expander for the pExpander */ 1357 oneExpander->dmUpStreamExpander = AttachedExpander; 1358 } 1359 /* If failed to allocate */ 1360 else 1361 { 1362 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 1363 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1364 } 1365 } 1366 /* If the attached device is an end device */ 1367 else 1368 { 1369 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: Found end device\n")); 1370 /* LP2006-05-26 added upstream device to the newly found device */ 1371 AttachedDevice->dmExpander = oneExpander; 1372 oneExpander->dmUpStreamExpander = agNULL; 1373 } 1374 } 1375 else 1376 { 1377 DM_DBG1(("dmUpStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 1378 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1379 } 1380 } 1381 } 1382 } 1383 } /* substractive routing */ 1384 } 1385 } 1386 1387 oneExpander->discoveringPhyId ++; 1388 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 1389 { 1390 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 1391 { 1392 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 1393 /* continue discovery for the next phy */ 1394 dmDiscoverSend(dmRoot, oneDeviceData); 1395 } 1396 else 1397 { 1398 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 1399 1400 /* for MCN */ 1401 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 1402 /* remove the expander from the discovering list */ 1403 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 1404 /* continue upstream discovering */ 1405 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 1406 } 1407 } 1408 else 1409 { 1410 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 1411 1412 } 1413 1414 DM_DBG2(("dmUpStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 1415 1416 return; 1417 } 1418 1419 1420 osGLOBAL void 1421 dmDownStreamDiscoverExpanderPhy( 1422 dmRoot_t *dmRoot, 1423 dmIntPortContext_t *onePortContext, 1424 dmExpander_t *oneExpander, 1425 smpRespDiscover_t *pDiscoverResp 1426 ) 1427 { 1428 agsaSASIdentify_t sasIdentify; 1429 dmSASSubID_t dmSASSubID; 1430 bit32 attachedSasHi, attachedSasLo; 1431 dmExpander_t *AttachedExpander; 1432 dmExpander_t *UpStreamExpander; 1433 dmExpander_t *ConfigurableExpander = agNULL; 1434 bit8 connectionRate, negotiatedPhyLinkRate; 1435 bit32 configSASAddressHi; 1436 bit32 configSASAddressLo; 1437 bit32 dupConfigSASAddr = agFALSE; 1438 dmDeviceData_t *oneDeviceData; 1439 dmDeviceData_t *AttachedDevice = agNULL; 1440 bit32 SAS2SAS11Check = agFALSE; 1441 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1442 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1443 1444 1445 1446 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: start\n")); 1447 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1448 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1449 1450 DM_ASSERT(dmRoot, "(dmDownStreamDiscoverExpanderPhy) dmRoot NULL"); 1451 DM_ASSERT(onePortContext, "(dmDownStreamDiscoverExpanderPhy) pPort NULL"); 1452 DM_ASSERT(oneExpander, "(dmDownStreamDiscoverExpanderPhy) pExpander NULL"); 1453 DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscoverExpanderPhy) pDiscoverResp NULL"); 1454 1455 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p\n", onePortContext, oneExpander)); 1456 1457 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1458 { 1459 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: invalid port or aborted discovery!!!\n")); 1460 return; 1461 } 1462 1463 if (oneExpander != oneExpander->dmDevice->dmExpander) 1464 { 1465 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: wrong!!!\n")); 1466 } 1467 1468 /* (1) Find the device structure of the expander */ 1469 oneDeviceData = oneExpander->dmDevice; 1470 1471 DM_ASSERT(oneDeviceData, "(dmDownStreamDiscoverExpanderPhy) pDevice NULL"); 1472 1473 /* for debugging */ 1474 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 1475 oneExpander->discoveringPhyId, 1476 oneDeviceData->SASAddressID.sasAddressHi, 1477 oneDeviceData->SASAddressID.sasAddressLo)); 1478 1479 DM_DBG3((" Attached device: %s\n", 1480 ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 1481 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 1482 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 1483 1484 1485 /* for debugging */ 1486 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 1487 { 1488 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 1489 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d !!!\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 1490 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 1491 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1492 return; 1493 } 1494 1495 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1496 { 1497 DM_DBG3((" SAS address : %08x-%08x\n", 1498 DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 1499 DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 1500 DM_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 1501 DM_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 1502 DM_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 1503 DM_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 1504 DM_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 1505 DM_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 1506 DM_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 1507 DM_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 1508 DM_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 1509 1510 } 1511 /* end for debugging */ 1512 1513 /* saving routing attribute for non self-configuring expanders */ 1514 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 1515 1516 oneExpander->discoverSMPAllowed = agTRUE; 1517 1518 /* If a device is attached */ 1519 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 1520 { 1521 /* Setup sasIdentify for the attached device */ 1522 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 1523 sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceType & 0x70; 1524 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 1525 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 1526 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 1527 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 1528 1529 /* incremental discovery */ 1530 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 1531 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 1532 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 1533 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 1534 1535 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 1536 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 1537 1538 /* If it's a direct routing */ 1539 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 1540 { 1541 /* If the attached device is an expander */ 1542 if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1543 || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 1544 1545 { 1546 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 1547 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1548 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1549 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1550 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1551 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1552 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1553 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1554 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1555 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1556 1557 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1558 return; 1559 } 1560 } 1561 1562 /* If the expander's attached device is not myself */ 1563 if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 1564 || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 1565 { 1566 /* Find the attached device from discovered list */ 1567 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 1568 /* If the device has not been discovered before */ 1569 if ( AttachedDevice == agNULL) //11 1570 { 1571 /* If the phy has subtractive routing attribute */ 1572 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 1573 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 1574 DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1575 ) 1576 { 1577 /* TODO: discovery error, callback */ 1578 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Deferred!!! **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 1579 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1580 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1581 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1582 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1583 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1584 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1585 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1586 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1587 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1588 1589 onePortContext->discovery.DeferredError = agTRUE; 1590 } 1591 else /* 11 */ 1592 { 1593 /* Add the device */ 1594 /* read minimum rate from the configuration 1595 onePortContext->LinkRate is SPC's local link rate 1596 */ 1597 connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 1598 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 1599 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 1600 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 1601 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 1602 { 1603 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1604 { 1605 AttachedDevice = dmPortSASDeviceAdd( 1606 dmRoot, 1607 onePortContext, 1608 sasIdentify, 1609 agFALSE, 1610 connectionRate, 1611 dmAllShared->itNexusTimeout, 1612 0, 1613 STP_DEVICE_TYPE, 1614 oneDeviceData, 1615 oneExpander, 1616 pDiscoverResp->phyIdentifier 1617 ); 1618 } 1619 else 1620 { 1621 /* incremental discovery */ 1622 AttachedDevice = dmFindRegNValid( 1623 dmRoot, 1624 onePortContext, 1625 &dmSASSubID 1626 ); 1627 /* not registered and not valid; add this*/ 1628 if (AttachedDevice == agNULL) 1629 { 1630 AttachedDevice = dmPortSASDeviceAdd( 1631 dmRoot, 1632 onePortContext, 1633 sasIdentify, 1634 agFALSE, 1635 connectionRate, 1636 dmAllShared->itNexusTimeout, 1637 0, 1638 STP_DEVICE_TYPE, 1639 oneDeviceData, 1640 oneExpander, 1641 pDiscoverResp->phyIdentifier 1642 ); 1643 } 1644 } 1645 } /* DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp) */ 1646 else /* 22 */ 1647 { 1648 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 1649 { 1650 AttachedDevice = dmPortSASDeviceAdd( 1651 dmRoot, 1652 onePortContext, 1653 sasIdentify, 1654 agFALSE, 1655 connectionRate, 1656 dmAllShared->itNexusTimeout, 1657 0, 1658 SAS_DEVICE_TYPE, 1659 oneDeviceData, 1660 oneExpander, 1661 pDiscoverResp->phyIdentifier 1662 ); 1663 } 1664 else 1665 { 1666 /* incremental discovery */ 1667 AttachedDevice = dmFindRegNValid( 1668 dmRoot, 1669 onePortContext, 1670 &dmSASSubID 1671 ); 1672 /* not registered and not valid; add this*/ 1673 if (AttachedDevice == agNULL) 1674 { 1675 AttachedDevice = dmPortSASDeviceAdd( 1676 dmRoot, 1677 onePortContext, 1678 sasIdentify, 1679 agFALSE, 1680 connectionRate, 1681 dmAllShared->itNexusTimeout, 1682 0, 1683 SAS_DEVICE_TYPE, 1684 oneDeviceData, 1685 oneExpander, 1686 pDiscoverResp->phyIdentifier 1687 ); 1688 } 1689 } 1690 } /* else 22 */ 1691 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 1692 /* If the device is added successfully */ 1693 if ( AttachedDevice != agNULL) 1694 { 1695 if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 1696 || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 1697 || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 1698 || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 1699 { 1700 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n")); 1701 1702 } 1703 else 1704 { 1705 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 1706 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 1707 { 1708 1709 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n")); 1710 } 1711 else 1712 { 1713 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Other type of device.\n")); 1714 } 1715 } 1716 1717 /* LP2006-05-26 added upstream device to the newly found device */ 1718 AttachedDevice->dmExpander = oneExpander; 1719 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 1720 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 1721 1722 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 1723 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 1724 1725 /* If the phy has table routing attribute */ 1726 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1727 { 1728 /* If the attached device is a fan out expander */ 1729 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1730 { 1731 /* TODO: discovery error, callback */ 1732 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 1733 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1734 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1735 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1736 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1737 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1738 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1739 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1740 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1741 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1742 /* discovery done */ 1743 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1744 } 1745 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1746 { 1747 /* Allocate an expander data structure */ 1748 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 1749 1750 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 1751 /* If allocate successfully */ 1752 if ( AttachedExpander != agNULL) 1753 { 1754 /* set up downstream information on configurable expander */ 1755 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1756 /* Setup upstream information */ 1757 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1758 AttachedExpander->hasUpStreamDevice = agTRUE; 1759 AttachedExpander->upStreamSASAddressHi 1760 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1761 AttachedExpander->upStreamSASAddressLo 1762 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1763 AttachedExpander->dmUpStreamExpander = oneExpander; 1764 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 1765 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1766 } 1767 /* If failed to allocate */ 1768 else 1769 { 1770 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to allocate expander data structure!!!\n")); 1771 /* discovery done */ 1772 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1773 } 1774 } 1775 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1776 /* If status is still DISCOVERY_DOWN_STREAM */ 1777 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1778 { 1779 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before\n")); 1780 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1781 UpStreamExpander = oneExpander->dmUpStreamExpander; 1782 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1783 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1784 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1785 if (ConfigurableExpander) 1786 { 1787 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1788 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1789 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1790 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1791 ) 1792 { /* directly attached between oneExpander and ConfigurableExpander */ 1793 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 1\n")); 1794 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1795 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1796 } 1797 else 1798 { 1799 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st before loc 2\n")); 1800 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1801 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1802 } 1803 } /* if !ConfigurableExpander */ 1804 1805 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 1806 ConfigurableExpander, 1807 configSASAddressHi, 1808 configSASAddressLo 1809 ); 1810 1811 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 1812 { 1813 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 1st q123\n")); 1814 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 1815 ConfigurableExpander->currentDownStreamPhyIndex = 1816 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 1817 ConfigurableExpander->dmReturnginExpander = oneExpander; 1818 dmRoutingEntryAdd(dmRoot, 1819 ConfigurableExpander, 1820 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 1821 configSASAddressHi, 1822 configSASAddressLo 1823 ); 1824 } 1825 } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 1826 } /* AttachedDevice != agNULL */ 1827 /* If fail to add the device */ 1828 else 1829 { 1830 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: Failed to add a device!!!\n")); 1831 /* discovery done */ 1832 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1833 } 1834 } /* else 11 */ 1835 } /* AttachedDevice == agNULL */ 1836 /* If the device has been discovered before */ 1837 else /* haha discovered before 33 */ 1838 { 1839 /* If the phy has subtractive routing attribute */ 1840 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 1841 { 1842 /* If the expander doesn't have up stream device */ 1843 if ( oneExpander->hasUpStreamDevice == agFALSE) 1844 { 1845 /* TODO: discovery error, callback */ 1846 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 1847 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1848 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1849 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1850 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1851 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1852 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1853 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1854 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1855 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1856 /* discovery done */ 1857 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1858 } 1859 /* If the expander has up stream device */ 1860 else /* 44 */ 1861 { 1862 /* If sas address doesn't match */ 1863 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 1864 || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 1865 { 1866 /* TODO: discovery error, callback */ 1867 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two subtractive phys!!!\n")); 1868 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1869 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1870 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1871 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1872 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1873 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1874 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1875 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1876 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1877 /* discovery done */ 1878 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1879 } 1880 } /* else 44 */ 1881 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE */ 1882 /* If the phy has table routing attribute */ 1883 else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 1884 { 1885 /* If the attached device is a fan out expander */ 1886 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 1887 { 1888 /* (2.3.3.2.1.1) TODO: discovery error, callback */ 1889 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 1890 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1891 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1892 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1893 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1894 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1895 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1896 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1897 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1898 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1899 /* discovery done */ 1900 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1901 } 1902 /* If the attached device is an edge expander */ 1903 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 1904 { 1905 /* Setup up stream inform */ 1906 AttachedExpander = AttachedDevice->dmExpander; 1907 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 1908 /* If the attached expander has up stream device */ 1909 if ( AttachedExpander->hasUpStreamDevice == agTRUE) 1910 { 1911 /* compare the sas address */ 1912 if ( (AttachedExpander->upStreamSASAddressHi 1913 != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 1914 || (AttachedExpander->upStreamSASAddressLo 1915 != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 1916 { 1917 /* TODO: discovery error, callback */ 1918 SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander, oneExpander, oneExpander); 1919 if (SAS2SAS11Check == agTRUE) 1920 { 1921 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 1922 } 1923 else 1924 { 1925 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 1926 } 1927 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1928 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1929 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1930 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1931 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1932 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1933 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1934 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1935 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1936 /* discovery done */ 1937 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1938 } 1939 else 1940 { 1941 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 1942 /* set up downstream information on configurable expander */ 1943 1944 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 1945 /* haha */ 1946 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 1947 /* Add the pAttachedExpander to discovering list */ 1948 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 1949 } 1950 } /* AttachedExpander->hasUpStreamDevice == agTRUE */ 1951 /* If the attached expander doesn't have up stream device */ 1952 else 1953 { 1954 /* TODO: discovery error, callback */ 1955 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 1956 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 1957 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 1958 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 1959 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 1960 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 1961 DM_DBG1(("dmDownStreamDiscoverExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 1962 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 1963 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 1964 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 1965 /* discovery done */ 1966 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1967 } 1968 } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE */ 1969 } /* DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE */ 1970 /* do this regradless of sub or table */ 1971 /* If status is still DISCOVERY_DOWN_STREAM */ 1972 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1973 { 1974 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before\n")); 1975 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 1976 1977 UpStreamExpander = oneExpander->dmUpStreamExpander; 1978 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1979 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1980 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1981 if (ConfigurableExpander) 1982 { 1983 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 1984 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 1985 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 1986 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 1987 ) 1988 { /* directly attached between oneExpander and ConfigurableExpander */ 1989 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 1\n")); 1990 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 1991 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 1992 } 1993 else 1994 { 1995 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd before loc 2\n")); 1996 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 1997 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 1998 } 1999 } /* if !ConfigurableExpander */ 2000 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2001 ConfigurableExpander, 2002 configSASAddressHi, 2003 configSASAddressLo 2004 ); 2005 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2006 { 2007 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 2nd q123 \n")); 2008 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2009 ConfigurableExpander->currentDownStreamPhyIndex = 2010 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2011 ConfigurableExpander->dmReturnginExpander = oneExpander; 2012 dmRoutingEntryAdd(dmRoot, 2013 ConfigurableExpander, 2014 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2015 configSASAddressHi, 2016 configSASAddressLo 2017 ); 2018 } 2019 } /* onePortContext->discovery.status == DISCOVERY_DOWN_STREAM */ 2020 /* incremental discovery */ 2021 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2022 { 2023 connectionRate = MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)); 2024 2025 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2026 { 2027 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SATA_STP\n")); 2028 2029 dmPortSASDeviceAdd( 2030 dmRoot, 2031 onePortContext, 2032 sasIdentify, 2033 agFALSE, 2034 connectionRate, 2035 dmAllShared->itNexusTimeout, 2036 0, 2037 STP_DEVICE_TYPE, 2038 oneDeviceData, 2039 oneExpander, 2040 pDiscoverResp->phyIdentifier 2041 ); 2042 } 2043 else 2044 { 2045 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: incremental SAS\n")); 2046 2047 2048 dmPortSASDeviceAdd( 2049 dmRoot, 2050 onePortContext, 2051 sasIdentify, 2052 agFALSE, 2053 connectionRate, 2054 dmAllShared->itNexusTimeout, 2055 0, 2056 SAS_DEVICE_TYPE, 2057 oneDeviceData, 2058 oneExpander, 2059 pDiscoverResp->phyIdentifier 2060 ); 2061 2062 } 2063 } /* onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START */ 2064 } /* else 33 */ 2065 } /* (attachedSasLo != onePortContext->sasLocalAddressLo) */ 2066 2067 else /* else 44 */ 2068 { 2069 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: Found Self\n")); 2070 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd before\n")); 2071 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2072 2073 UpStreamExpander = oneExpander->dmUpStreamExpander; 2074 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2075 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2076 ConfigurableExpander, 2077 onePortContext->sasLocalAddressHi, 2078 onePortContext->sasLocalAddressLo 2079 ); 2080 2081 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2082 { 2083 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: 3rd q123 Setup routing table\n")); 2084 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2085 ConfigurableExpander->currentDownStreamPhyIndex = 2086 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2087 ConfigurableExpander->dmReturnginExpander = oneExpander; 2088 dmRoutingEntryAdd(dmRoot, 2089 ConfigurableExpander, 2090 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2091 onePortContext->sasLocalAddressHi, 2092 onePortContext->sasLocalAddressLo 2093 ); 2094 } 2095 } /* else 44 */ 2096 } /* DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE */ 2097 /* If no device is attached */ 2098 else 2099 { 2100 2101 DM_DBG2(("!!!!!!!!!!!!!!!!!!!!! SPIN SATA !!!!!!!!!!!!!!!!!!!!!!!!!!!\n")); 2102 negotiatedPhyLinkRate = DISCRSP_GET_LINKRATE(pDiscoverResp); // added by thenil 2103 2104 if (negotiatedPhyLinkRate == 0x03) 2105 { 2106 2107 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: SPIN SATA sent reset\n")); 2108 dmPhyControlSend(dmRoot, 2109 oneDeviceData, 2110 SMP_PHY_CONTROL_HARD_RESET, 2111 pDiscoverResp->phyIdentifier 2112 ); 2113 } 2114 2115 /* do nothing */ 2116 } 2117 2118 2119 /* Increment the discovering phy id */ 2120 oneExpander->discoveringPhyId ++; 2121 2122 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 2123 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 2124 { 2125 /* If not the last phy */ 2126 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 2127 { 2128 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: More Phys to discover\n")); 2129 /* continue discovery for the next phy */ 2130 dmDiscoverSend(dmRoot, oneDeviceData); 2131 } 2132 /* If the last phy */ 2133 else 2134 { 2135 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: No More Phys\n")); 2136 2137 /* for MCN */ 2138 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 2139 /* remove the expander from the discovering list */ 2140 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 2141 /* continue downstream discovering */ 2142 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 2143 } 2144 } 2145 else 2146 { 2147 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 2148 } 2149 DM_DBG3(("dmDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 2150 2151 return; 2152 } 2153 2154 2155 /* works at SAS2 expander (called in dmDownStreamDiscover2ExpanderPhy()) 2156 if currentExpander is SAS2, called in dmDownStreamDiscover2ExpanderPhy() 2157 if currentExpander is SAS1.1, called in dmDownStreamDiscoverExpanderPhy() 2158 */ 2159 osGLOBAL bit32 2160 dmSAS2SAS11ErrorCheck( 2161 dmRoot_t *dmRoot, 2162 dmIntPortContext_t *onePortContext, 2163 dmExpander_t *topExpander, 2164 dmExpander_t *bottomExpander, 2165 dmExpander_t *currentExpander 2166 ) 2167 { 2168 bit32 result = agFALSE, i = 0; 2169 bit8 downStreamPhyID, upStreamPhyID; 2170 2171 DM_DBG2(("dmSAS2SAS11ErrorCheck: start\n")); 2172 2173 if (topExpander == agNULL) 2174 { 2175 DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander is NULL\n")); 2176 return result; 2177 } 2178 if (bottomExpander == agNULL) 2179 { 2180 DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander is NULL\n")); 2181 return result; 2182 } 2183 2184 if (currentExpander == agNULL) 2185 { 2186 DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander is NULL\n")); 2187 return result; 2188 } 2189 2190 DM_DBG2(("dmSAS2SAS11ErrorCheck: topExpander addrHi 0x%08x addrLo 0x%08x\n", 2191 topExpander->dmDevice->SASAddressID.sasAddressHi, topExpander->dmDevice->SASAddressID.sasAddressLo)); 2192 DM_DBG2(("dmSAS2SAS11ErrorCheck: bottomExpander addrHi 0x%08x addrLo 0x%08x\n", 2193 bottomExpander->dmDevice->SASAddressID.sasAddressHi, bottomExpander->dmDevice->SASAddressID.sasAddressLo)); 2194 DM_DBG2(("dmSAS2SAS11ErrorCheck: currentExpander addrHi 0x%08x addrLo 0x%08x\n", 2195 currentExpander->dmDevice->SASAddressID.sasAddressHi, currentExpander->dmDevice->SASAddressID.sasAddressLo)); 2196 2197 for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2198 { 2199 downStreamPhyID = topExpander->downStreamPhys[i]; 2200 upStreamPhyID = bottomExpander->upStreamPhys[i]; 2201 if (currentExpander->SAS2 == 1) 2202 { 2203 if ( downStreamPhyID == upStreamPhyID && 2204 topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_TABLE && 2205 bottomExpander->routingAttribute[i] == SAS_ROUTING_SUBTRACTIVE && 2206 topExpander->SAS2 == 0 && 2207 bottomExpander->SAS2 == 1 2208 ) 2209 { 2210 result = agTRUE; 2211 break; 2212 } 2213 } 2214 else if (currentExpander->SAS2 == 0) 2215 { 2216 if ( downStreamPhyID == upStreamPhyID && 2217 topExpander->routingAttribute[downStreamPhyID] == SAS_ROUTING_SUBTRACTIVE && 2218 bottomExpander->routingAttribute[i] == SAS_ROUTING_TABLE && 2219 topExpander->SAS2 == 1 && 2220 bottomExpander->SAS2 == 0 2221 ) 2222 { 2223 result = agTRUE; 2224 break; 2225 } 2226 } 2227 } 2228 return result; 2229 } 2230 2231 osGLOBAL void 2232 dmDownStreamDiscover2ExpanderPhy( 2233 dmRoot_t *dmRoot, 2234 dmIntPortContext_t *onePortContext, 2235 dmExpander_t *oneExpander, 2236 smpRespDiscover2_t *pDiscoverResp 2237 ) 2238 { 2239 dmDeviceData_t *oneDeviceData; 2240 dmExpander_t *UpStreamExpander; 2241 dmDeviceData_t *AttachedDevice = agNULL; 2242 dmExpander_t *AttachedExpander; 2243 agsaSASIdentify_t sasIdentify; 2244 bit8 connectionRate; 2245 bit32 attachedSasHi, attachedSasLo; 2246 dmSASSubID_t dmSASSubID; 2247 dmExpander_t *ConfigurableExpander = agNULL; 2248 bit32 dupConfigSASAddr = agFALSE; 2249 bit32 configSASAddressHi; 2250 bit32 configSASAddressLo; 2251 bit32 SAS2SAS11Check = agFALSE; 2252 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 2253 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 2254 2255 2256 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: start\n")); 2257 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 2258 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 2259 2260 DM_ASSERT(dmRoot, "(dmDownStreamDiscover2ExpanderPhy) dmRoot NULL"); 2261 DM_ASSERT(onePortContext, "(dmDownStreamDiscover2ExpanderPhy) pPort NULL"); 2262 DM_ASSERT(oneExpander, "(dmDownStreamDiscover2ExpanderPhy) pExpander NULL"); 2263 DM_ASSERT(pDiscoverResp, "(dmDownStreamDiscover2ExpanderPhy) pDiscoverResp NULL"); 2264 2265 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->dmDevice)); 2266 2267 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 2268 { 2269 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: invalid port or aborted discovery!!!\n")); 2270 return; 2271 } 2272 2273 if (oneExpander != oneExpander->dmDevice->dmExpander) 2274 { 2275 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: wrong!!!\n")); 2276 } 2277 2278 2279 /* (1) Find the device structure of the expander */ 2280 oneDeviceData = oneExpander->dmDevice; 2281 2282 DM_ASSERT(oneDeviceData, "(dmDownStreamDiscover2ExpanderPhy) pDevice NULL"); 2283 2284 /* for debugging */ 2285 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Phy #%d of SAS %08x-%08x\n", 2286 oneExpander->discoveringPhyId, 2287 oneDeviceData->SASAddressID.sasAddressHi, 2288 oneDeviceData->SASAddressID.sasAddressLo)); 2289 2290 DM_DBG2((" Attached device: %s\n", 2291 ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 2292 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 2293 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 2294 2295 2296 /* for debugging */ 2297 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 2298 { 2299 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: !!! Incorrect SMP response !!!\n")); 2300 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 2301 dmhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover2_t)); 2302 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2303 return; 2304 } 2305 2306 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2307 { 2308 DM_DBG2((" SAS address : %08x-%08x\n", 2309 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 2310 SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 2311 DM_DBG2((" SSP Target : %d\n", SAS2_DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 2312 DM_DBG2((" STP Target : %d\n", SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 2313 DM_DBG2((" SMP Target : %d\n", SAS2_DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 2314 DM_DBG2((" SATA DEVICE : %d\n", SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 2315 DM_DBG2((" SSP Initiator : %d\n", SAS2_DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 2316 DM_DBG2((" STP Initiator : %d\n", SAS2_DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 2317 DM_DBG2((" SMP Initiator : %d\n", SAS2_DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 2318 DM_DBG2((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 2319 DM_DBG2((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 2320 2321 } 2322 2323 /* saving routing attribute for non self-configuring expanders */ 2324 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 2325 2326 2327 oneExpander->discoverSMPAllowed = agTRUE; 2328 2329 /* If a device is attached */ 2330 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 2331 { 2332 /* Setup sasIdentify for the attached device */ 2333 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 2334 sasIdentify.deviceType_addressFrameType = pDiscoverResp->attachedDeviceTypeReason & 0x70; 2335 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 2336 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 2337 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 2338 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 2339 2340 /* incremental discovery */ 2341 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 2342 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 2343 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 2344 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 2345 2346 attachedSasHi = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 2347 attachedSasLo = SAS2_DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 2348 2349 /* If it's a direct routing */ 2350 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 2351 { 2352 /* If the attached device is an expander */ 2353 if ( (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2354 || (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 2355 2356 { 2357 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error direct routing can't connect to expander!!!\n")); 2358 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2359 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2360 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2361 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2362 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2363 2364 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2365 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2366 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2367 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2368 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2369 2370 return; 2371 } 2372 } 2373 2374 /* If the expander's attached device is not myself */ 2375 if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 2376 || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 2377 { 2378 /* Find the attached device from discovered list */ 2379 AttachedDevice = dmPortSASDeviceFind(dmRoot, onePortContext, attachedSasLo, attachedSasHi, oneDeviceData); 2380 /* If the device has not been discovered before */ 2381 if ( AttachedDevice == agNULL) //11 2382 { 2383 //qqqqqq 2384 if (0) 2385 { 2386 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address!!!\n")); 2387 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2388 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2389 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2390 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2391 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2392 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2393 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2394 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2395 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2396 /* discovery done */ 2397 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2398 } 2399 else 2400 { 2401 /* Add the device */ 2402 /* read minimum rate from the configuration 2403 onePortContext->LinkRate is SPC's local link rate 2404 */ 2405 connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2406 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 2407 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: negotiatedPhyLinkRate 0x%x\n", SAS2_DISCRSP_GET_LINKRATE(pDiscoverResp))); 2408 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: connectionRate 0x%x\n", connectionRate)); 2409 2410 if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2411 { 2412 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2413 { 2414 AttachedDevice = dmPortSASDeviceAdd( 2415 dmRoot, 2416 onePortContext, 2417 sasIdentify, 2418 agFALSE, 2419 connectionRate, 2420 dmAllShared->itNexusTimeout, 2421 0, 2422 STP_DEVICE_TYPE, 2423 oneDeviceData, 2424 oneExpander, 2425 pDiscoverResp->phyIdentifier 2426 ); 2427 } 2428 else 2429 { 2430 /* incremental discovery */ 2431 AttachedDevice = dmFindRegNValid( 2432 dmRoot, 2433 onePortContext, 2434 &dmSASSubID 2435 ); 2436 /* not registered and not valid; add this*/ 2437 if (AttachedDevice == agNULL) 2438 { 2439 AttachedDevice = dmPortSASDeviceAdd( 2440 dmRoot, 2441 onePortContext, 2442 sasIdentify, 2443 agFALSE, 2444 connectionRate, 2445 dmAllShared->itNexusTimeout, 2446 0, 2447 STP_DEVICE_TYPE, 2448 oneDeviceData, 2449 oneExpander, 2450 pDiscoverResp->phyIdentifier 2451 ); 2452 } 2453 } 2454 } 2455 else 2456 { 2457 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 2458 { 2459 AttachedDevice = dmPortSASDeviceAdd( 2460 dmRoot, 2461 onePortContext, 2462 sasIdentify, 2463 agFALSE, 2464 connectionRate, 2465 dmAllShared->itNexusTimeout, 2466 0, 2467 SAS_DEVICE_TYPE, 2468 oneDeviceData, 2469 oneExpander, 2470 pDiscoverResp->phyIdentifier 2471 ); 2472 } 2473 else 2474 { 2475 /* incremental discovery */ 2476 AttachedDevice = dmFindRegNValid( 2477 dmRoot, 2478 onePortContext, 2479 &dmSASSubID 2480 ); 2481 /* not registered and not valid; add this*/ 2482 if (AttachedDevice == agNULL) 2483 { 2484 AttachedDevice = dmPortSASDeviceAdd( 2485 dmRoot, 2486 onePortContext, 2487 sasIdentify, 2488 agFALSE, 2489 connectionRate, 2490 dmAllShared->itNexusTimeout, 2491 0, 2492 SAS_DEVICE_TYPE, 2493 oneDeviceData, 2494 oneExpander, 2495 pDiscoverResp->phyIdentifier 2496 ); 2497 } 2498 } 2499 } 2500 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 2501 /* If the device is added successfully */ 2502 if ( AttachedDevice != agNULL) 2503 { 2504 if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 2505 || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 2506 || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 2507 || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 2508 { 2509 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Report a new SAS device !!\n")); 2510 2511 } 2512 else 2513 { 2514 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 2515 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 2516 { 2517 2518 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found an STP or SATA device.\n")); 2519 } 2520 else 2521 { 2522 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Other type of device.\n")); 2523 } 2524 } 2525 2526 /* LP2006-05-26 added upstream device to the newly found device */ 2527 AttachedDevice->dmExpander = oneExpander; 2528 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: AttachedDevice %p did %d\n", AttachedDevice, AttachedDevice->id)); 2529 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: Attached oneExpander %p did %d\n", AttachedDevice->dmExpander, AttachedDevice->dmExpander->id)); 2530 2531 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 2532 DM_DBG3(("dmDownStreamDiscover2ExpanderPhy: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 2533 2534 /* If the phy has table routing attribute */ 2535 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2536 { 2537 /* If the attached device is a fan out expander */ 2538 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2539 { 2540 /* TODO: discovery error, callback */ 2541 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys are connected!!!\n")); 2542 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2543 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2544 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2545 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2546 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2547 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2548 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2549 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2550 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2551 /* discovery done */ 2552 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2553 } 2554 else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2555 { 2556 /* Allocate an expander data structure */ 2557 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2558 2559 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 2560 /* If allocate successfully */ 2561 if ( AttachedExpander != agNULL) 2562 { 2563 /* set up downstream information on configurable expander */ 2564 2565 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2566 2567 /* Setup upstream information */ 2568 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2569 //qqqqq 2570 AttachedExpander->hasUpStreamDevice = agTRUE; 2571 AttachedExpander->upStreamSASAddressHi 2572 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2573 AttachedExpander->upStreamSASAddressLo 2574 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2575 AttachedExpander->dmUpStreamExpander = oneExpander; 2576 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2577 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2578 } 2579 /* If failed to allocate */ 2580 else 2581 { 2582 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure!!!\n")); 2583 /* discovery done */ 2584 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2585 } 2586 } 2587 } 2588 //qqqqq 2589 else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 2590 (SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE || 2591 SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2592 ) 2593 { 2594 /* Allocate an expander data structure */ 2595 AttachedExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, AttachedDevice); 2596 2597 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found a EDGE/FANOUT exp device.%p\n", AttachedExpander)); 2598 /* If allocate successfully */ 2599 if ( AttachedExpander != agNULL) 2600 { 2601 /* set up downstream information on configurable expander */ 2602 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2603 2604 /* Setup upstream information */ 2605 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2606 AttachedExpander->hasUpStreamDevice = agTRUE; 2607 AttachedExpander->upStreamSASAddressHi 2608 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2609 AttachedExpander->upStreamSASAddressLo 2610 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2611 AttachedExpander->dmUpStreamExpander = oneExpander; 2612 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 2613 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2614 } 2615 /* If failed to allocate */ 2616 else 2617 { 2618 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to allocate expander data structure (2)!!!\n")); 2619 /* discovery done */ 2620 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2621 } 2622 2623 2624 } 2625 /* If status is still DISCOVERY_DOWN_STREAM */ 2626 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2627 onePortContext->discovery.ConfiguresOthers == agFALSE) 2628 { 2629 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before\n")); 2630 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2631 UpStreamExpander = oneExpander->dmUpStreamExpander; 2632 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2633 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2634 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2635 if (ConfigurableExpander) 2636 { 2637 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2638 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2639 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2640 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2641 ) 2642 { /* directly attached between oneExpander and ConfigurableExpander */ 2643 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 1\n")); 2644 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2645 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2646 } 2647 else 2648 { 2649 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st before loc 2\n")); 2650 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2651 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2652 } 2653 } /* if !ConfigurableExpander */ 2654 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2655 ConfigurableExpander, 2656 configSASAddressHi, 2657 configSASAddressLo 2658 ); 2659 2660 2661 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2662 { 2663 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 1st q123\n")); 2664 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2665 ConfigurableExpander->currentDownStreamPhyIndex = 2666 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2667 ConfigurableExpander->dmReturnginExpander = oneExpander; 2668 dmRoutingEntryAdd(dmRoot, 2669 ConfigurableExpander, 2670 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2671 configSASAddressHi, 2672 configSASAddressLo 2673 ); 2674 } 2675 } 2676 } 2677 /* If fail to add the device */ 2678 else 2679 { 2680 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy, Failed to add a device!!!\n")); 2681 /* discovery done */ 2682 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2683 } 2684 } 2685 } 2686 /* If the device has been discovered before */ 2687 else /* discovered before */ 2688 { 2689 /* If the phy has subtractive routing attribute */ 2690 if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 2691 { 2692 /* If the expander doesn't have up stream device */ 2693 if ( oneExpander->hasUpStreamDevice == agFALSE) 2694 { 2695 /* TODO: discovery error, callback */ 2696 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error loop, or end device connects to two expanders!!!\n")); 2697 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2698 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2699 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2700 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2701 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2702 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2703 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2704 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2705 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2706 /* discovery done */ 2707 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2708 } 2709 /* If the expander has up stream device */ 2710 else 2711 { 2712 2713 //qqqqq 2714 /* If sas address doesn't match */ 2715 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 2716 || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 2717 { 2718 /* TODO: discovery error, callback */ 2719 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** two subtractive phys!!! Allowed in SAS2!!!\n")); 2720 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2721 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2722 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2723 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2724 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2725 onePortContext->discovery.DeferredError = agTRUE; 2726 2727 } 2728 } 2729 } 2730 /* If the phy has table routing attribute */ 2731 else if ( SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 2732 { 2733 /* If the attached device is a fan out expander */ 2734 if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 2735 { 2736 /* (2.3.3.2.1.1) TODO: discovery error, callback */ 2737 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error fan out expander to routing table phy!!!\n")); 2738 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2739 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2740 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2741 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2742 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2743 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2744 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2745 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2746 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2747 /* discovery done */ 2748 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2749 } 2750 /* If the attached device is an edge expander */ 2751 else if ( SAS2_DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 2752 { 2753 /* Setup up stream inform */ 2754 AttachedExpander = AttachedDevice->dmExpander; 2755 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 2756 //hhhhhh 2757 /* If the attached expander has up stream device */ 2758 if ( AttachedExpander->hasUpStreamDevice == agTRUE) 2759 { 2760 /* compare the sas address */ 2761 if ( (AttachedExpander->upStreamSASAddressHi 2762 != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 2763 || (AttachedExpander->upStreamSASAddressLo 2764 != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 2765 { 2766 if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2767 { 2768 /* 2769 needs further error checking 2770 UpstreamExpanderOfAttachedExpander = AttachedExpander->UpStreamExpander 2771 for (i=0;i<DM_MAX_EXPANDER_PHYS;i++) 2772 { 2773 if (UpstreamExpanderOfAttachedExpander->downStreamPhys[i] != 0 && 2774 } 2775 */ 2776 SAS2SAS11Check = dmSAS2SAS11ErrorCheck(dmRoot, onePortContext, AttachedExpander->dmUpStreamExpander, AttachedExpander, oneExpander); 2777 if (SAS2SAS11Check == agTRUE) 2778 { 2779 2780 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error SAS2 and SAS1.1!!!\n")); 2781 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2782 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2783 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2784 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2785 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2786 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2787 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2788 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2789 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2790 /* discovery done */ 2791 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2792 } 2793 else 2794 { 2795 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (1)\n")); 2796 /* move on to the next phys but should be not proceed after oneExpander */ 2797 oneExpander->UndoDueToTTTSupported = agTRUE; 2798 onePortContext->discovery.DeferredError = agFALSE; 2799 } 2800 } 2801 else 2802 { 2803 /* TODO: discovery error, callback */ 2804 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (1)!!!\n")); 2805 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2806 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2807 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2808 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2809 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2810 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2811 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2812 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2813 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2814 /* discovery done */ 2815 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2816 } 2817 } 2818 else 2819 { 2820 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 2821 /* set up downstream information on configurable expander */ 2822 2823 dmExpanderDownStreamPhyAdd(dmRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 2824 /* haha */ 2825 dmExpanderUpStreamPhyAdd(dmRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 2826 /* Add the pAttachedExpander to discovering list */ 2827 dmDiscoveringExpanderAdd(dmRoot, onePortContext, AttachedExpander); 2828 } 2829 } 2830 /* If the attached expander doesn't have up stream device */ 2831 else 2832 { 2833 if (AttachedExpander->TTTSupported && oneExpander->TTTSupported) 2834 { 2835 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: Allowed Table to Table (2)\n")); 2836 /* move on to the next phys but should be not proceed after oneExpander */ 2837 oneExpander->UndoDueToTTTSupported = agTRUE; 2838 onePortContext->discovery.DeferredError = agFALSE; 2839 } 2840 else 2841 { 2842 /* TODO: discovery error, callback */ 2843 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: **** Topology Error two table routing phys connected (2)!!!\n")); 2844 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 2845 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 2846 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 2847 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 2848 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 2849 DM_DBG1(("dmDownStreamDiscover2ExpanderPhy: sasAddressHi 0x%08x sasAddressLo 0x%08x phyid 0x%x\n", 2850 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi, 2851 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo, 2852 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier)); 2853 /* discovery done */ 2854 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2855 } 2856 } 2857 } 2858 } /* for else if (SAS2_DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) */ 2859 2860 /* do this regradless of sub or table */ 2861 /* If status is still DISCOVERY_DOWN_STREAM */ 2862 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM && 2863 onePortContext->discovery.ConfiguresOthers == agFALSE) 2864 { 2865 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before\n")); 2866 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2867 2868 UpStreamExpander = oneExpander->dmUpStreamExpander; 2869 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2870 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2871 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2872 if (ConfigurableExpander) 2873 { 2874 if ( (ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi 2875 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 2876 (ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo 2877 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 2878 ) 2879 { /* directly attached between oneExpander and ConfigurableExpander */ 2880 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 1\n")); 2881 configSASAddressHi = oneExpander->dmDevice->SASAddressID.sasAddressHi; 2882 configSASAddressLo = oneExpander->dmDevice->SASAddressID.sasAddressLo; 2883 } 2884 else 2885 { 2886 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd before loc 2\n")); 2887 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 2888 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 2889 } 2890 } /* if !ConfigurableExpander */ 2891 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2892 ConfigurableExpander, 2893 configSASAddressHi, 2894 configSASAddressLo 2895 ); 2896 2897 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2898 { 2899 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 2nd q123 \n")); 2900 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2901 ConfigurableExpander->currentDownStreamPhyIndex = 2902 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2903 ConfigurableExpander->dmReturnginExpander = oneExpander; 2904 dmRoutingEntryAdd(dmRoot, 2905 ConfigurableExpander, 2906 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2907 configSASAddressHi, 2908 configSASAddressLo 2909 ); 2910 } 2911 } /* if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) */ 2912 /* incremental discovery */ 2913 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 2914 { 2915 connectionRate = MIN(onePortContext->LinkRate, SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pDiscoverResp)); 2916 2917 if (SAS2_DISCRSP_IS_STP_TARGET(pDiscoverResp) || SAS2_DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 2918 { 2919 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SATA_STP\n")); 2920 2921 dmPortSASDeviceAdd( 2922 dmRoot, 2923 onePortContext, 2924 sasIdentify, 2925 agFALSE, 2926 connectionRate, 2927 dmAllShared->itNexusTimeout, 2928 0, 2929 STP_DEVICE_TYPE, 2930 oneDeviceData, 2931 oneExpander, 2932 pDiscoverResp->phyIdentifier 2933 ); 2934 } 2935 else 2936 { 2937 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: incremental SAS\n")); 2938 2939 dmPortSASDeviceAdd( 2940 dmRoot, 2941 onePortContext, 2942 sasIdentify, 2943 agFALSE, 2944 connectionRate, 2945 dmAllShared->itNexusTimeout, 2946 0, 2947 SAS_DEVICE_TYPE, 2948 oneDeviceData, 2949 oneExpander, 2950 pDiscoverResp->phyIdentifier 2951 ); 2952 2953 } 2954 } 2955 2956 2957 }/* else; existing devce */ 2958 } /* not attached to myself */ 2959 /* If the attached device is myself */ 2960 else 2961 { 2962 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Found Self\n")); 2963 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd before\n")); 2964 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 2965 2966 if (onePortContext->discovery.ConfiguresOthers == agFALSE) 2967 { 2968 UpStreamExpander = oneExpander->dmUpStreamExpander; 2969 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 2970 dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 2971 ConfigurableExpander, 2972 onePortContext->sasLocalAddressHi, 2973 onePortContext->sasLocalAddressLo 2974 ); 2975 2976 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 2977 { 2978 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: 3rd q123 Setup routing table\n")); 2979 UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 2980 ConfigurableExpander->currentDownStreamPhyIndex = 2981 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 2982 ConfigurableExpander->dmReturnginExpander = oneExpander; 2983 dmRoutingEntryAdd(dmRoot, 2984 ConfigurableExpander, 2985 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 2986 onePortContext->sasLocalAddressHi, 2987 onePortContext->sasLocalAddressLo 2988 ); 2989 } 2990 } 2991 } 2992 } 2993 /* If no device is attached */ 2994 else 2995 { 2996 } 2997 2998 2999 /* Increment the discovering phy id */ 3000 oneExpander->discoveringPhyId ++; 3001 3002 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3003 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3004 { 3005 /* If not the last phy */ 3006 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3007 { 3008 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: More Phys to discover\n")); 3009 /* continue discovery for the next phy */ 3010 dmDiscoverSend(dmRoot, oneDeviceData); 3011 } 3012 /* If the last phy */ 3013 else 3014 { 3015 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: No More Phys\n")); 3016 3017 /* for MCN */ 3018 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3019 ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 3020 if (oneExpander->UndoDueToTTTSupported == agTRUE && ConfigurableExpander != agNULL) 3021 // if (oneExpander->UndoDueToTTTSupported == agTRUE) 3022 { 3023 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: Not sure!!!\n")); 3024 dmDiscoveringUndoAdd(dmRoot, onePortContext, oneExpander); 3025 oneExpander->UndoDueToTTTSupported = agFALSE; 3026 } 3027 3028 /* remove the expander from the discovering list */ 3029 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3030 /* continue downstream discovering */ 3031 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3032 } 3033 } 3034 else 3035 { 3036 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3037 } 3038 DM_DBG2(("dmDownStreamDiscover2ExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3039 3040 return; 3041 } 3042 3043 3044 osGLOBAL void 3045 dmDiscoveringUndoAdd( 3046 dmRoot_t *dmRoot, 3047 dmIntPortContext_t *onePortContext, 3048 dmExpander_t *oneExpander 3049 ) 3050 { 3051 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3052 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3053 dmList_t *ExpanderList; 3054 dmExpander_t *tempExpander; 3055 dmIntPortContext_t *tmpOnePortContext = onePortContext; 3056 3057 DM_DBG2(("dmDiscoveringUndoAdd: start\n")); 3058 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3059 { 3060 DM_DBG2(("dmDiscoveringUndoAdd: empty discoveringExpanderList\n")); 3061 return; 3062 } 3063 3064 // DM_DBG2(("dmDiscoveringUndoAdd: before\n")); 3065 // dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3066 3067 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3068 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 3069 { 3070 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3071 if ( tempExpander == agNULL) 3072 { 3073 DM_DBG1(("dmDiscoveringUndoAdd: tempExpander is NULL!!!\n")); 3074 return; 3075 } 3076 if (tempExpander->dmUpStreamExpander == oneExpander) 3077 { 3078 DM_DBG2(("dmDiscoveringUndoAdd: match!!! expander id %d\n", tempExpander->id)); 3079 DM_DBG2(("dmDiscoveringUndoAdd: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 3080 DM_DBG2(("dmDiscoveringUndoAdd: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 3081 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 3082 DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 3083 // DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 3084 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 3085 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 3086 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 3087 } 3088 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 3089 { 3090 DM_DBG2(("dmDiscoveringUndoAdd: hitting break\n")); 3091 break; 3092 } 3093 ExpanderList = ExpanderList->flink; 3094 } 3095 3096 // DM_DBG2(("dmDiscoveringUndoAdd: after\n")); 3097 // dmDumpAllExp(dmRoot, onePortContext, oneExpander); 3098 return; 3099 } 3100 3101 osGLOBAL void 3102 dmHandleZoneViolation( 3103 dmRoot_t *dmRoot, 3104 agsaRoot_t *agRoot, 3105 agsaIORequest_t *agIORequest, 3106 dmDeviceData_t *oneDeviceData, 3107 dmSMPFrameHeader_t *frameHeader, 3108 agsaFrameHandle_t frameHandle 3109 ) 3110 { 3111 dmIntPortContext_t *onePortContext = agNULL; 3112 dmExpander_t *oneExpander = agNULL; 3113 3114 DM_DBG1(("dmHandleZoneViolation: start\n")); 3115 DM_DBG1(("dmHandleZoneViolation: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3116 DM_DBG1(("dmHandleZoneViolation: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3117 onePortContext = oneDeviceData->dmPortContext; 3118 oneExpander = oneDeviceData->dmExpander; 3119 if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 3120 { 3121 DM_DBG1(("dmHandleZoneViolation: invalid port or aborted discovery!!!\n")); 3122 return; 3123 } 3124 /* for MCN */ 3125 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3126 /* remove the expander from the discovering list */ 3127 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3128 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3129 { 3130 /* continue upstream discovering */ 3131 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3132 } 3133 else /* DISCOVERY_DOWN_STREAM or DISCOVERY_CONFIG_ROUTING */ 3134 { 3135 /* continue downstream discovering */ 3136 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3137 } 3138 return; 3139 } 3140 3141 3142 osGLOBAL void 3143 dmUpStreamDiscoverExpanderPhySkip( 3144 dmRoot_t *dmRoot, 3145 dmIntPortContext_t *onePortContext, 3146 dmExpander_t *oneExpander 3147 ) 3148 3149 { 3150 dmDeviceData_t *oneDeviceData; 3151 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: start\n")); 3152 3153 oneDeviceData = oneExpander->dmDevice; 3154 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3155 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3156 3157 oneExpander->discoveringPhyId++; 3158 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3159 { 3160 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3161 { 3162 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3163 /* continue discovery for the next phy */ 3164 dmDiscoverSend(dmRoot, oneDeviceData); 3165 } 3166 else 3167 { 3168 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: No More Phys\n")); 3169 3170 /* for MCN */ 3171 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3172 /* remove the expander from the discovering list */ 3173 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3174 /* continue upstream discovering */ 3175 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3176 } 3177 } 3178 else 3179 { 3180 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3181 3182 } 3183 3184 DM_DBG3(("dmUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3185 3186 return; 3187 } 3188 3189 3190 osGLOBAL void 3191 dmUpStreamDiscover2ExpanderPhySkip( 3192 dmRoot_t *dmRoot, 3193 dmIntPortContext_t *onePortContext, 3194 dmExpander_t *oneExpander 3195 ) 3196 { 3197 dmDeviceData_t *oneDeviceData; 3198 3199 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: start\n")); 3200 oneDeviceData = oneExpander->dmDevice; 3201 3202 oneExpander->discoveringPhyId++; 3203 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3204 { 3205 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3206 { 3207 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM find more ...\n")); 3208 /* continue discovery for the next phy */ 3209 dmDiscoverSend(dmRoot, oneDeviceData); 3210 } 3211 else 3212 { 3213 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 3214 3215 /* for MCN */ 3216 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3217 /* remove the expander from the discovering list */ 3218 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3219 /* continue upstream discovering */ 3220 dmUpStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3221 } 3222 } 3223 else 3224 { 3225 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 3226 } 3227 3228 DM_DBG2(("dmUpStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3229 3230 3231 return; 3232 } 3233 3234 osGLOBAL void 3235 dmDownStreamDiscoverExpanderPhySkip( 3236 dmRoot_t *dmRoot, 3237 dmIntPortContext_t *onePortContext, 3238 dmExpander_t *oneExpander 3239 ) 3240 { 3241 dmDeviceData_t *oneDeviceData; 3242 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: start\n")); 3243 3244 oneDeviceData = oneExpander->dmDevice; 3245 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3246 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3247 3248 /* Increment the discovering phy id */ 3249 oneExpander->discoveringPhyId ++; 3250 3251 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3252 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3253 { 3254 /* If not the last phy */ 3255 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3256 { 3257 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 3258 /* continue discovery for the next phy */ 3259 dmDiscoverSend(dmRoot, oneDeviceData); 3260 } 3261 /* If the last phy */ 3262 else 3263 { 3264 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: No More Phys\n")); 3265 3266 /* for MCN */ 3267 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3268 /* remove the expander from the discovering list */ 3269 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3270 /* continue downstream discovering */ 3271 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3272 } 3273 } 3274 else 3275 { 3276 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3277 } 3278 DM_DBG3(("dmDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3279 3280 3281 return; 3282 } 3283 3284 osGLOBAL void 3285 dmDownStreamDiscover2ExpanderPhySkip( 3286 dmRoot_t *dmRoot, 3287 dmIntPortContext_t *onePortContext, 3288 dmExpander_t *oneExpander 3289 ) 3290 { 3291 dmDeviceData_t *oneDeviceData; 3292 3293 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: start\n")); 3294 3295 oneDeviceData = oneExpander->dmDevice; 3296 /* Increment the discovering phy id */ 3297 oneExpander->discoveringPhyId ++; 3298 3299 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 3300 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 3301 { 3302 /* If not the last phy */ 3303 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 3304 { 3305 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: More Phys to discover\n")); 3306 /* continue discovery for the next phy */ 3307 dmDiscoverSend(dmRoot, oneDeviceData); 3308 } 3309 /* If the last phy */ 3310 else 3311 { 3312 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: No More Phys\n")); 3313 3314 /* for MCN */ 3315 dmUpdateAllAdjacent(dmRoot, onePortContext, oneDeviceData); 3316 /* remove the expander from the discovering list */ 3317 dmDiscoveringExpanderRemove(dmRoot, onePortContext, oneExpander); 3318 /* continue downstream discovering */ 3319 dmDownStreamDiscovering(dmRoot, onePortContext, oneDeviceData); 3320 } 3321 } 3322 else 3323 { 3324 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 3325 } 3326 DM_DBG2(("dmDownStreamDiscover2ExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 3327 return; 3328 } 3329 3330 osGLOBAL void 3331 dmExpanderUpStreamPhyAdd( 3332 dmRoot_t *dmRoot, 3333 dmExpander_t *oneExpander, 3334 bit8 phyId 3335 ) 3336 { 3337 bit32 i; 3338 bit32 hasSet = agFALSE; 3339 3340 DM_DBG3(("dmExpanderUpStreamPhyAdd: start, phyid %d\n", phyId)); 3341 DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3342 DM_DBG3(("dmExpanderUpStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3343 DM_DBG3(("dmExpanderUpStreamPhyAdd: phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3344 3345 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3346 { 3347 if ( oneExpander->upStreamPhys[i] == phyId ) 3348 { 3349 hasSet = agTRUE; 3350 break; 3351 } 3352 } 3353 3354 if ( hasSet == agFALSE ) 3355 { 3356 oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId; 3357 } 3358 3359 DM_DBG3(("dmExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 3360 3361 /* for debugging */ 3362 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 3363 { 3364 DM_DBG3(("dmExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i])); 3365 } 3366 return; 3367 } 3368 3369 osGLOBAL void 3370 dmExpanderDownStreamPhyAdd( 3371 dmRoot_t *dmRoot, 3372 dmExpander_t *oneExpander, 3373 bit8 phyId 3374 ) 3375 { 3376 bit32 i; 3377 bit32 hasSet = agFALSE; 3378 3379 DM_DBG3(("dmExpanderDownStreamPhyAdd: start, phyid %d\n", phyId)); 3380 DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 3381 DM_DBG3(("dmExpanderDownStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 3382 DM_DBG3(("dmExpanderDownStreamPhyAdd: phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3383 3384 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3385 { 3386 if ( oneExpander->downStreamPhys[i] == phyId ) 3387 { 3388 hasSet = agTRUE; 3389 break; 3390 } 3391 } 3392 3393 if ( hasSet == agFALSE ) 3394 { 3395 oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId; 3396 } 3397 3398 DM_DBG3(("dmExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 3399 3400 /* for debugging */ 3401 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 3402 { 3403 DM_DBG3(("dmExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i])); 3404 } 3405 return; 3406 } 3407 3408 osGLOBAL void 3409 dmDiscoveryReportMCN( 3410 dmRoot_t *dmRoot, 3411 dmIntPortContext_t *onePortContext 3412 ) 3413 { 3414 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3415 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3416 dmDeviceData_t *oneDeviceData = agNULL; 3417 dmList_t *DeviceListList; 3418 bit16 extension = 0; 3419 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3420 3421 DM_DBG2(("dmDiscoveryReportMCN: start\n")); 3422 3423 /* 3424 if full disocvery, report all devices using MCN 3425 if incremental discovery, 3426 1. compare MCN and PrevMCN 3427 2. report the changed ones; report MCN 3428 3. set PrevMCN to MCN 3429 PrevMCN = MCN 3430 */ 3431 3432 DeviceListList = dmAllShared->MainDeviceList.flink; 3433 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3434 { 3435 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3436 if ( oneDeviceData == agNULL) 3437 { 3438 DM_DBG1(("dmDiscoveryReportMCN: oneDeviceData is NULL!!!\n")); 3439 return; 3440 } 3441 DM_DBG3(("dmDiscoveryReportMCN: loop did %d\n", oneDeviceData->id)); 3442 if (oneDeviceData->dmPortContext == onePortContext) 3443 { 3444 DM_DBG2(("dmDiscoveryReportMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3445 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3446 DM_DBG2(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3447 3448 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3449 { 3450 DM_DBG2(("dmDiscoveryReportMCN: FULL_START\n")); 3451 } 3452 else 3453 { 3454 DM_DBG2(("dmDiscoveryReportMCN: INCREMENTAL_START\n")); 3455 } 3456 /* 3457 if MCN is 0, the device is removed 3458 */ 3459 if (oneDeviceData->MCN != oneDeviceData->PrevMCN && oneDeviceData->MCN != 0) 3460 { 3461 DM_DBG2(("dmDiscoveryReportMCN: reporting \n")); 3462 extension = oneDeviceData->dmDeviceInfo.ext; 3463 /* zero out MCN in extension */ 3464 extension = extension & 0x7FF; 3465 /* sets MCN in extension */ 3466 extension = extension | (oneDeviceData->MCN << 11); 3467 DEVINFO_PUT_EXT(&(oneDeviceData->dmDeviceInfo), extension); 3468 DM_DBG5(("dmDiscoveryReportMCN: MCN 0x%08x PrevMCN 0x%08x\n", DEVINFO_GET_EXT_MCN(&(oneDeviceData->dmDeviceInfo)), oneDeviceData->PrevMCN)); 3469 if (oneDeviceData->ExpDevice != agNULL) 3470 { 3471 DM_DBG2(("dmDiscoveryReportMCN: attached expander case\n")); 3472 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3473 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceMCNChange); 3474 } 3475 else 3476 { 3477 DM_DBG2(("dmDiscoveryReportMCN: No attached expander case\n")); 3478 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceMCNChange); 3479 } 3480 oneDeviceData->PrevMCN = oneDeviceData->MCN; 3481 } 3482 else 3483 { 3484 DM_DBG2(("dmDiscoveryReportMCN: No change; no reporting \n")); 3485 if (oneDeviceData->MCN == 0) 3486 { 3487 oneDeviceData->PrevMCN = oneDeviceData->MCN; 3488 } 3489 } 3490 3491 } 3492 DeviceListList = DeviceListList->flink; 3493 } 3494 3495 return; 3496 } 3497 3498 osGLOBAL void 3499 dmDiscoveryDumpMCN( 3500 dmRoot_t *dmRoot, 3501 dmIntPortContext_t *onePortContext 3502 ) 3503 { 3504 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3505 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3506 dmDeviceData_t *oneDeviceData = agNULL; 3507 dmList_t *DeviceListList; 3508 3509 DM_DBG3(("dmDiscoveryDumpMCN: start\n")); 3510 3511 DeviceListList = dmAllShared->MainDeviceList.flink; 3512 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3513 { 3514 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3515 if (oneDeviceData == agNULL) 3516 { 3517 DM_DBG1(("dmDiscoveryDumpMCN: oneDeviceData is NULL!!!\n")); 3518 return; 3519 } 3520 DM_DBG3(("dmDiscoveryDumpMCN: loop did %d\n", oneDeviceData->id)); 3521 if (oneDeviceData->dmPortContext == onePortContext) 3522 { 3523 DM_DBG3(("dmDiscoveryDumpMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3524 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3525 DM_DBG3(("dmDiscoveryDumpMCN: MCN 0x%08x PrevMCN 0x%08x\n", oneDeviceData->MCN, oneDeviceData->PrevMCN)); 3526 } 3527 DeviceListList = DeviceListList->flink; 3528 } 3529 3530 return; 3531 } 3532 3533 osGLOBAL void 3534 dmDiscoveryResetMCN( 3535 dmRoot_t *dmRoot, 3536 dmIntPortContext_t *onePortContext 3537 ) 3538 { 3539 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3540 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3541 dmDeviceData_t *oneDeviceData = agNULL; 3542 dmList_t *DeviceListList; 3543 3544 DM_DBG2(("dmDiscoveryResetMCN: start\n")); 3545 3546 /* reinitialize the device data belonging to this portcontext */ 3547 DeviceListList = dmAllShared->MainDeviceList.flink; 3548 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3549 { 3550 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3551 if (oneDeviceData == agNULL) 3552 { 3553 DM_DBG1(("dmDiscoveryResetMCN: oneDeviceData is NULL!!!\n")); 3554 return; 3555 } 3556 DM_DBG3(("dmDiscoveryResetMCN: loop did %d\n", oneDeviceData->id)); 3557 if (oneDeviceData->dmPortContext == onePortContext) 3558 { 3559 if (oneDeviceData->ExpDevice != agNULL) 3560 { 3561 DM_DBG2(("dmDiscoveryResetMCN: resetting oneDeviceData->ExpDevice\n")); 3562 oneDeviceData->ExpDevice = agNULL; 3563 } 3564 DM_DBG3(("dmDiscoveryResetMCN: resetting MCN and MCNdone\n")); 3565 oneDeviceData->MCN = 0; 3566 3567 oneDeviceData->MCNDone = agFALSE; 3568 DM_DBG2(("dmDiscoveryResetMCN: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3569 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3570 } 3571 DeviceListList = DeviceListList->flink; 3572 } 3573 3574 return; 3575 } 3576 3577 3578 /* 3579 do min(oneDeviceData, found-one) in all upstream and downstream 3580 find ajcanent expanders and mark it done; sees only ajcacent targets 3581 */ 3582 osGLOBAL void 3583 dmUpdateAllAdjacent( 3584 dmRoot_t *dmRoot, 3585 dmIntPortContext_t *onePortContext, 3586 dmDeviceData_t *oneDeviceData /* current one */ 3587 ) 3588 { 3589 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3590 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3591 dmDeviceData_t *tmponeDeviceData = agNULL; 3592 dmList_t *DeviceListList; 3593 3594 DM_DBG2(("dmUpdateAllAdjacent: start\n")); 3595 if (oneDeviceData == agNULL) 3596 { 3597 DM_DBG1(("dmUpdateAllAdjacent: oneDeviceData is NULL!!!\n")); 3598 return; 3599 } 3600 3601 oneDeviceData->MCNDone = agTRUE; 3602 3603 DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3604 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3605 3606 3607 DeviceListList = dmAllShared->MainDeviceList.flink; 3608 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3609 { 3610 tmponeDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3611 if ( tmponeDeviceData == agNULL) 3612 { 3613 DM_DBG1(("dmUpdateAllAdjacent: tmponeDeviceData is NULL!!!\n")); 3614 return; 3615 } 3616 DM_DBG3(("dmUpdateAllAdjacent: loop did %d\n", tmponeDeviceData->id)); 3617 if (tmponeDeviceData->dmPortContext == onePortContext && tmponeDeviceData->ExpDevice == oneDeviceData) 3618 { 3619 DM_DBG2(("dmUpdateAllAdjacent: setting MCN DONE\n")); 3620 DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3621 tmponeDeviceData->SASAddressID.sasAddressHi, tmponeDeviceData->SASAddressID.sasAddressLo)); 3622 tmponeDeviceData->MCNDone = agTRUE; 3623 if (oneDeviceData->directlyAttached == agFALSE) 3624 { 3625 DM_DBG2(("dmUpdateAllAdjacent: tmponeDeviceData MCN 0x%x\n", tmponeDeviceData->MCN)); 3626 DM_DBG2(("dmUpdateAllAdjacent: oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3627 tmponeDeviceData->MCN = MIN(oneDeviceData->MCN, tmponeDeviceData->MCN); 3628 } 3629 3630 } 3631 DeviceListList = DeviceListList->flink; 3632 } 3633 3634 return; 3635 3636 } 3637 3638 osGLOBAL void 3639 dmUpdateMCN( 3640 dmRoot_t *dmRoot, 3641 dmIntPortContext_t *onePortContext, 3642 dmDeviceData_t *AdjacentDeviceData, /* adjacent expander */ 3643 dmDeviceData_t *oneDeviceData /* current one */ 3644 ) 3645 { 3646 3647 DM_DBG2(("dmUpdateMCN: start\n")); 3648 3649 if (AdjacentDeviceData == agNULL) 3650 { 3651 DM_DBG1(("dmUpdateMCN: AdjacentDeviceData is NULL!!!\n")); 3652 return; 3653 } 3654 3655 if (oneDeviceData == agNULL) 3656 { 3657 DM_DBG1(("dmUpdateMCN: oneDeviceData is NULL!!!\n")); 3658 return; 3659 } 3660 3661 DM_DBG2(("dmUpdateMCN: Current sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3662 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3663 3664 DM_DBG2(("dmUpdateMCN: AdjacentDeviceData one sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3665 AdjacentDeviceData->SASAddressID.sasAddressHi, AdjacentDeviceData->SASAddressID.sasAddressLo)); 3666 3667 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3668 { 3669 DM_DBG2(("dmUpdateMCN: DISCOVERY_UP_STREAM\n")); 3670 } 3671 3672 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3673 { 3674 DM_DBG2(("dmUpdateMCN: DISCOVERY_DOWN_STREAM\n")); 3675 } 3676 3677 3678 /* MCN */ 3679 3680 /* directly attached one does not have MCN 3681 update only adjacent device data 3682 */ 3683 3684 if (oneDeviceData->directlyAttached == agTRUE && AdjacentDeviceData->MCNDone == agFALSE) 3685 { 3686 AdjacentDeviceData->MCN++; 3687 DM_DBG2(("dmUpdateMCN: case 1 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3688 DM_DBG2(("dmUpdateMCN: case 1 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3689 } 3690 else if (AdjacentDeviceData->MCNDone == agFALSE) 3691 { 3692 AdjacentDeviceData->MCN++; 3693 AdjacentDeviceData->MCN = MIN(oneDeviceData->MCN, AdjacentDeviceData->MCN); 3694 DM_DBG2(("dmUpdateMCN: case 2 oneDeviceData MCN 0x%x\n", oneDeviceData->MCN)); 3695 DM_DBG2(("dmUpdateMCN: case 2 AdjacentDeviceData MCN 0x%x\n", AdjacentDeviceData->MCN)); 3696 } 3697 3698 3699 return; 3700 } 3701 /* go through expander list and device list array ??? */ 3702 osGLOBAL dmDeviceData_t * 3703 dmPortSASDeviceFind( 3704 dmRoot_t *dmRoot, 3705 dmIntPortContext_t *onePortContext, 3706 bit32 sasAddrLo, 3707 bit32 sasAddrHi, 3708 dmDeviceData_t *CurrentDeviceData /* current expander */ 3709 ) 3710 { 3711 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3712 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3713 dmDeviceData_t *oneDeviceData, *RetDeviceData=agNULL; 3714 dmList_t *DeviceListList; 3715 3716 DM_DBG3(("dmPortSASDeviceFind: start\n")); 3717 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", sasAddrHi, sasAddrLo)); 3718 3719 DM_ASSERT((agNULL != dmRoot), ""); 3720 DM_ASSERT((agNULL != onePortContext), ""); 3721 3722 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 3723 3724 /* find a device's existence */ 3725 DeviceListList = dmAllShared->MainDeviceList.flink; 3726 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3727 { 3728 DM_DBG3(("dmPortSASDeviceFind: Full discovery\n")); 3729 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3730 { 3731 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3732 if (oneDeviceData == agNULL) 3733 { 3734 DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3735 return agNULL; 3736 } 3737 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3738 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3739 (oneDeviceData->valid == agTRUE) && 3740 (oneDeviceData->dmPortContext == onePortContext) 3741 ) 3742 { 3743 DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3744 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3745 DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3746 RetDeviceData = oneDeviceData; 3747 dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3748 break; 3749 } 3750 DeviceListList = DeviceListList->flink; 3751 } 3752 } 3753 else 3754 { 3755 /* incremental discovery */ 3756 DM_DBG3(("dmPortSASDeviceFind: Incremental discovery\n")); 3757 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3758 { 3759 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3760 if (oneDeviceData == agNULL) 3761 { 3762 DM_DBG1(("dmPortSASDeviceFind: oneDeviceData is NULL!!!\n")); 3763 return agNULL; 3764 } 3765 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 3766 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 3767 (oneDeviceData->valid2 == agTRUE) && 3768 (oneDeviceData->dmPortContext == onePortContext) 3769 ) 3770 { 3771 DM_DBG3(("dmPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3772 DM_DBG3(("dmPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3773 DM_DBG3(("dmPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3774 RetDeviceData = oneDeviceData; 3775 dmUpdateMCN(dmRoot, onePortContext, RetDeviceData, CurrentDeviceData); 3776 break; 3777 } 3778 DeviceListList = DeviceListList->flink; 3779 } 3780 } 3781 3782 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 3783 3784 return RetDeviceData; 3785 } 3786 3787 bit32 3788 dmNewEXPorNot( 3789 dmRoot_t *dmRoot, 3790 dmIntPortContext_t *onePortContext, 3791 dmSASSubID_t *dmSASSubID 3792 ) 3793 { 3794 // dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3795 // dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3796 dmExpander_t *oneExpander = agNULL; 3797 dmList_t *ExpanderList; 3798 bit32 ret = agTRUE; 3799 dmDeviceData_t *oneDeviceData = agNULL; 3800 3801 DM_DBG3(("dmNewEXPorNot: start\n")); 3802 3803 /* find a device's existence */ 3804 ExpanderList = onePortContext->discovery.discoveringExpanderList.flink; 3805 while (ExpanderList != &(onePortContext->discovery.discoveringExpanderList)) 3806 { 3807 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 3808 if ( oneExpander == agNULL) 3809 { 3810 DM_DBG1(("dmNewEXPorNot: oneExpander is NULL!!!\n")); 3811 return agFALSE; 3812 } 3813 oneDeviceData = oneExpander->dmDevice; 3814 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3815 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3816 (oneDeviceData->dmPortContext == onePortContext) 3817 ) 3818 { 3819 DM_DBG3(("dmNewEXPorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3820 ret = agFALSE; 3821 break; 3822 } 3823 ExpanderList = ExpanderList->flink; 3824 } 3825 3826 return ret; 3827 } 3828 3829 3830 bit32 3831 dmNewSASorNot( 3832 dmRoot_t *dmRoot, 3833 dmIntPortContext_t *onePortContext, 3834 dmSASSubID_t *dmSASSubID 3835 ) 3836 { 3837 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3838 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3839 dmDeviceData_t *oneDeviceData = agNULL; 3840 dmList_t *DeviceListList; 3841 bit32 ret = agTRUE; 3842 3843 DM_DBG3(("dmNewSASorNot: start\n")); 3844 3845 /* find a device's existence */ 3846 DeviceListList = dmAllShared->MainDeviceList.flink; 3847 while (DeviceListList != &(dmAllShared->MainDeviceList)) 3848 { 3849 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 3850 if (oneDeviceData == agNULL) 3851 { 3852 DM_DBG1(("dmNewSASorNot: oneDeviceData is NULL!!!\n")); 3853 return agFALSE; 3854 } 3855 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 3856 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 3857 (oneDeviceData->dmPortContext == onePortContext) && 3858 (oneDeviceData->registered == agTRUE) 3859 ) 3860 { 3861 DM_DBG3(("dmNewSASorNot: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 3862 ret = agFALSE; 3863 break; 3864 } 3865 DeviceListList = DeviceListList->flink; 3866 } 3867 3868 return ret; 3869 } 3870 /* 3871 call 3872 osGLOBAL bit32 3873 tddmReportDevice( 3874 dmRoot_t *dmRoot, 3875 dmPortContext_t *dmPortContext, 3876 dmDeviceInfo_t *dmDeviceInfo 3877 ) 3878 if not reported, report Device to TDM 3879 */ 3880 osGLOBAL dmDeviceData_t * 3881 dmPortSASDeviceAdd( 3882 dmRoot_t *dmRoot, 3883 dmIntPortContext_t *onePortContext, 3884 agsaSASIdentify_t sasIdentify, 3885 bit32 sasInitiator, 3886 bit8 connectionRate, 3887 bit32 itNexusTimeout, 3888 bit32 firstBurstSize, 3889 bit32 deviceType, 3890 dmDeviceData_t *oneExpDeviceData, 3891 dmExpander_t *dmExpander, 3892 bit8 phyID 3893 ) 3894 { 3895 dmDeviceData_t *oneDeviceData = agNULL; 3896 bit8 dev_s_rate = 0; 3897 bit8 sasorsata = 1; 3898 dmSASSubID_t dmSASSubID; 3899 bit8 ExpanderConnectionRate = connectionRate; 3900 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 3901 bit16 extension = 0; 3902 bit32 current_link_rate = 0; 3903 3904 DM_DBG3(("dmPortSASDeviceAdd: start\n")); 3905 DM_DBG3(("dmPortSASDeviceAdd: connectionRate %d\n", connectionRate)); 3906 3907 dmSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 3908 dmSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 3909 dmSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 3910 dmSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 3911 3912 if (oneExpDeviceData != agNULL) 3913 { 3914 ExpanderConnectionRate = DEVINFO_GET_LINKRATE(&oneExpDeviceData->agDeviceInfo); 3915 DM_DBG3(("dmPortSASDeviceAdd: ExpanderConnectionRate 0x%x\n", ExpanderConnectionRate)); 3916 } 3917 if (oneExpDeviceData != agNULL) 3918 { 3919 if (oneExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 3920 oneExpDeviceData->SASAddressID.sasAddressLo == 0x0) 3921 { 3922 DM_DBG1(("dmPortSASDeviceAdd: 1st Wrong expander!!!\n")); 3923 } 3924 } 3925 /* old device and already reported to TDM */ 3926 if ( agFALSE == dmNewSASorNot( 3927 dmRoot, 3928 onePortContext, 3929 &dmSASSubID 3930 ) 3931 ) /* old device */ 3932 { 3933 DM_DBG3(("dmPortSASDeviceAdd: OLD qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", dmSASSubID.initiator_ssp_stp_smp, dmSASSubID.target_ssp_stp_smp)); 3934 /* allocate a new device and set the valid bit */ 3935 oneDeviceData = dmAddSASToSharedcontext( 3936 dmRoot, 3937 onePortContext, 3938 &dmSASSubID, 3939 oneExpDeviceData, 3940 phyID 3941 ); 3942 if (oneDeviceData == agNULL) 3943 { 3944 DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null!!!\n")); 3945 } 3946 /* If a device is allocated */ 3947 if ( oneDeviceData != agNULL ) 3948 { 3949 3950 3951 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3952 { 3953 DM_DBG3(("dmPortSASDeviceAdd: OLD, UP_STREAM\n")); 3954 } 3955 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3956 { 3957 DM_DBG3(("dmPortSASDeviceAdd: OLD, DOWN_STREAM\n")); 3958 } 3959 3960 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 3961 { 3962 DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 3963 oneDeviceData->MCN++; 3964 } 3965 else 3966 { 3967 /* incremental */ 3968 DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 3969 if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 3970 { 3971 oneDeviceData->MCN++; 3972 } 3973 } 3974 3975 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 3976 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 3977 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 3978 3979 3980 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 3981 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 3982 3983 // oneDeviceData->sasIdentify = sasIdentify; 3984 dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 3985 3986 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 3987 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 3988 3989 /* parse sasIDframe to fill in agDeviceInfo */ 3990 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 3991 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 3992 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 3993 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 3994 3995 oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 3996 3997 /* adjusting connectionRate */ 3998 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 3999 if (oneAttachedExpDeviceData != agNULL) 4000 { 4001 connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4002 DM_DBG3(("dmPortSASDeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4003 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4004 } 4005 else 4006 { 4007 DM_DBG3(("dmPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n")); 4008 } 4009 4010 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4011 sasorsata = (bit8)deviceType; 4012 /* sTSDK spec device typ */ 4013 dev_s_rate = dev_s_rate | (sasorsata << 4); 4014 dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4015 /* detect link rate change */ 4016 current_link_rate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); 4017 if (current_link_rate != (bit32)MIN(connectionRate, ExpanderConnectionRate)) 4018 { 4019 DM_DBG1(("dmPortSASDeviceAdd: link rate changed current 0x%x new 0x%x\n", current_link_rate, MIN(connectionRate, ExpanderConnectionRate))); 4020 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4021 if (oneDeviceData->ExpDevice != agNULL) 4022 { 4023 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4024 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceRateChange); 4025 } 4026 else 4027 { 4028 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4029 } 4030 } 4031 4032 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4033 4034 4035 DEVINFO_PUT_SAS_ADDRESSLO( 4036 &oneDeviceData->agDeviceInfo, 4037 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4038 ); 4039 DEVINFO_PUT_SAS_ADDRESSHI( 4040 &oneDeviceData->agDeviceInfo, 4041 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4042 ); 4043 oneDeviceData->agContext.osData = oneDeviceData; 4044 oneDeviceData->agContext.sdkData = agNULL; 4045 4046 4047 } 4048 return oneDeviceData; 4049 } /* old device */ 4050 4051 4052 /* new device */ 4053 4054 DM_DBG3(("dmPortSASDeviceAdd: NEW qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", dmSASSubID.initiator_ssp_stp_smp, dmSASSubID.target_ssp_stp_smp)); 4055 4056 /* allocate a new device and set the valid bit */ 4057 oneDeviceData = dmAddSASToSharedcontext( 4058 dmRoot, 4059 onePortContext, 4060 &dmSASSubID, 4061 oneExpDeviceData, 4062 phyID 4063 ); 4064 if (oneDeviceData == agNULL) 4065 { 4066 DM_DBG1(("dmPortSASDeviceAdd: no more device, oneDeviceData is null !!!\n")); 4067 } 4068 4069 /* If a device is allocated */ 4070 if ( oneDeviceData != agNULL ) 4071 { 4072 4073 // DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 4074 // DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 4075 4076 // oneDeviceData->sasIdentify = sasIdentify; 4077 dm_memcpy(&(oneDeviceData->sasIdentify), &sasIdentify, sizeof(agsaSASIdentify_t)); 4078 4079 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4080 { 4081 DM_DBG3(("dmPortSASDeviceAdd: NEW, UP_STREAM\n")); 4082 } 4083 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4084 { 4085 DM_DBG3(("dmPortSASDeviceAdd: NEW, DOWN_STREAM\n")); 4086 } 4087 4088 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4089 { 4090 DM_DBG3(("dmPortSASDeviceAdd: FULL_START\n")); 4091 oneDeviceData->MCN++; 4092 } 4093 else 4094 { 4095 /* incremental */ 4096 DM_DBG3(("dmPortSASDeviceAdd: INCREMENTAL_START\n")); 4097 if (oneDeviceData->MCN == 0 && oneDeviceData->directlyAttached == agFALSE) 4098 { 4099 oneDeviceData->MCN++; 4100 } 4101 } 4102 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData MCN 0x%08x\n", oneDeviceData->MCN)); 4103 DM_DBG3(("dmPortSASDeviceAdd: oneDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 4104 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 4105 4106 DM_DBG3(("dmPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 4107 DM_DBG3(("dmPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 4108 4109 /* parse sasIDframe to fill in agDeviceInfo */ 4110 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 4111 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 4112 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 4113 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 4114 4115 oneDeviceData->SASSpecDeviceType = SA_IDFRM_GET_DEVICETTYPE(&sasIdentify); 4116 4117 /* adjusting connectionRate */ 4118 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4119 if (oneAttachedExpDeviceData != agNULL) 4120 { 4121 connectionRate = MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo)); 4122 DM_DBG3(("dmPortSASDeviceAdd: 2nd connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 4123 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 4124 } 4125 else 4126 { 4127 DM_DBG3(("dmPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n")); 4128 } 4129 4130 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 4131 sasorsata = (bit8)deviceType; 4132 dev_s_rate = dev_s_rate | (sasorsata << 4); 4133 dev_s_rate = dev_s_rate | MIN(connectionRate, ExpanderConnectionRate); 4134 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 4135 4136 4137 DEVINFO_PUT_SAS_ADDRESSLO( 4138 &oneDeviceData->agDeviceInfo, 4139 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4140 ); 4141 DEVINFO_PUT_SAS_ADDRESSHI( 4142 &oneDeviceData->agDeviceInfo, 4143 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4144 ); 4145 oneDeviceData->agContext.osData = oneDeviceData; 4146 oneDeviceData->agContext.sdkData = agNULL; 4147 4148 DM_DBG3(("dmPortSASDeviceAdd: did %d\n", oneDeviceData->id)); 4149 4150 4151 /* reporting to TDM; setting dmDeviceInfo */ 4152 DEVINFO_PUT_SMPTO(&oneDeviceData->dmDeviceInfo, DEFAULT_SMP_TIMEOUT); 4153 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->dmDeviceInfo, (bit16)itNexusTimeout); 4154 DEVINFO_PUT_FBS(&oneDeviceData->dmDeviceInfo, (bit16)firstBurstSize); 4155 DEVINFO_PUT_FLAG(&oneDeviceData->dmDeviceInfo, 1); 4156 DEVINFO_PUT_INITIATOR_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.initiator_ssp_stp_smp); 4157 DEVINFO_PUT_TARGET_SSP_STP_SMP(&oneDeviceData->dmDeviceInfo, dmSASSubID.target_ssp_stp_smp); 4158 extension = phyID; 4159 4160 /* setting 6th bit of dev_s_rate */ 4161 if (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE || 4162 oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 4163 { 4164 extension = (bit16)(extension | (1 << 8)); 4165 } 4166 DEVINFO_PUT_EXT(&oneDeviceData->dmDeviceInfo, extension); 4167 4168 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->dmDeviceInfo, dev_s_rate); 4169 4170 DEVINFO_PUT_SAS_ADDRESSLO( 4171 &oneDeviceData->dmDeviceInfo, 4172 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 4173 ); 4174 DEVINFO_PUT_SAS_ADDRESSHI( 4175 &oneDeviceData->dmDeviceInfo, 4176 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 4177 ); 4178 4179 if (oneDeviceData->ExpDevice != agNULL) 4180 { 4181 DM_DBG3(("dmPortSASDeviceAdd: attached expander case\n")); 4182 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 4183 /* 4184 Puts attached expander's SAS address into dmDeviceInfo 4185 */ 4186 DEVINFO_PUT_SAS_ADDRESSLO( 4187 &oneAttachedExpDeviceData->dmDeviceInfo, 4188 oneAttachedExpDeviceData->SASAddressID.sasAddressLo 4189 ); 4190 DEVINFO_PUT_SAS_ADDRESSHI( 4191 &oneAttachedExpDeviceData->dmDeviceInfo, 4192 oneAttachedExpDeviceData->SASAddressID.sasAddressHi 4193 ); 4194 DM_DBG3(("dmPortSASDeviceAdd: oneAttachedExpDeviceData addrHi 0x%08x addrLo 0x%08x PhyID 0x%x ext 0x%x\n", 4195 DM_GET_SAS_ADDRESSHI(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressHi), 4196 DM_GET_SAS_ADDRESSLO(oneAttachedExpDeviceData->dmDeviceInfo.sasAddressLo), 4197 phyID, extension)); 4198 4199 if (oneAttachedExpDeviceData->SASAddressID.sasAddressHi == 0x0 && 4200 oneAttachedExpDeviceData->SASAddressID.sasAddressLo == 0x0) 4201 { 4202 DM_DBG1(("dmPortSASDeviceAdd: 2nd Wrong expander!!!\n")); 4203 } 4204 if (oneDeviceData->reported == agFALSE) 4205 { 4206 oneDeviceData->registered = agTRUE; 4207 oneDeviceData->reported = agTRUE; 4208 if (deviceType == STP_DEVICE_TYPE) 4209 { 4210 /*STP device, DM need send SMP Report Phy SATA to get the SATA device type */ 4211 oneAttachedExpDeviceData->dmExpander->dmDeviceToProcess = oneDeviceData; 4212 dmReportPhySataSend(dmRoot, oneAttachedExpDeviceData, phyID); 4213 } 4214 else 4215 { 4216 /* SAS or SMP device */ 4217 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, dmDeviceArrival); 4218 } 4219 } 4220 } 4221 else 4222 { 4223 DM_DBG3(("dmPortSASDeviceAdd: NO attached expander case\n")); 4224 if (oneDeviceData->reported == agFALSE) 4225 { 4226 oneDeviceData->registered = agTRUE; 4227 oneDeviceData->reported = agTRUE; 4228 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, dmDeviceArrival); 4229 } 4230 } 4231 } 4232 4233 return oneDeviceData; 4234 } 4235 4236 osGLOBAL dmDeviceData_t * 4237 dmFindRegNValid( 4238 dmRoot_t *dmRoot, 4239 dmIntPortContext_t *onePortContext, 4240 dmSASSubID_t *dmSASSubID 4241 ) 4242 { 4243 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4244 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4245 dmDeviceData_t *oneDeviceData = agNULL; 4246 dmList_t *DeviceListList; 4247 bit32 found = agFALSE; 4248 DM_DBG3(("dmFindRegNValid: start\n")); 4249 4250 /* find a device's existence */ 4251 DeviceListList = dmAllShared->MainDeviceList.flink; 4252 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 4253 { 4254 DM_DBG3(("dmFindRegNValid: Full discovery\n")); 4255 while (DeviceListList != &(dmAllShared->MainDeviceList)) 4256 { 4257 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4258 if (oneDeviceData == agNULL) 4259 { 4260 DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4261 return agFALSE; 4262 } 4263 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4264 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4265 (oneDeviceData->valid == agTRUE) && 4266 (oneDeviceData->dmPortContext == onePortContext) 4267 ) 4268 { 4269 DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4270 DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4271 DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4272 found = agTRUE; 4273 break; 4274 } 4275 DeviceListList = DeviceListList->flink; 4276 } 4277 } 4278 else 4279 { 4280 /* incremental discovery */ 4281 DM_DBG3(("dmFindRegNValid: Incremental discovery\n")); 4282 while (DeviceListList != &(dmAllShared->MainDeviceList)) 4283 { 4284 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 4285 if (oneDeviceData == agNULL) 4286 { 4287 DM_DBG1(("dmFindRegNValid: oneDeviceData is NULL!!!\n")); 4288 return agFALSE; 4289 } 4290 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 4291 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 4292 (oneDeviceData->valid2 == agTRUE) && 4293 (oneDeviceData->dmPortContext == onePortContext) 4294 ) 4295 { 4296 DM_DBG3(("dmFindRegNValid: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 4297 DM_DBG3(("dmFindRegNValid: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4298 DM_DBG3(("dmFindRegNValid: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4299 found = agTRUE; 4300 break; 4301 } 4302 DeviceListList = DeviceListList->flink; 4303 } 4304 } 4305 4306 4307 4308 if (found == agFALSE) 4309 { 4310 DM_DBG3(("dmFindRegNValid: end returning NULL\n")); 4311 return agNULL; 4312 } 4313 else 4314 { 4315 DM_DBG3(("dmFindRegNValid: end returning NOT NULL\n")); 4316 return oneDeviceData; 4317 } 4318 } 4319 4320 osGLOBAL void 4321 dmNotifyBC( 4322 dmRoot_t *dmRoot, 4323 dmPortContext_t *dmPortContext, 4324 bit32 type) 4325 { 4326 dmIntPortContext_t *onePortContext = agNULL; 4327 4328 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4329 4330 DM_DBG3(("dmNotifyBC: start\n")); 4331 4332 if (onePortContext == agNULL) 4333 { 4334 DM_DBG1(("dmNotifyBC: onePortContext is NULL, wrong!!!\n")); 4335 return; 4336 } 4337 4338 if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4339 { 4340 if (onePortContext->DiscoveryAbortInProgress == agFALSE) 4341 { 4342 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4343 { 4344 DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE\n")); 4345 onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4346 onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4347 /* processed broadcast change */ 4348 onePortContext->discovery.SeenBC = agFALSE; 4349 } 4350 else 4351 { 4352 DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4353 onePortContext->discovery.SeenBC = agTRUE; 4354 } 4355 } 4356 } 4357 else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4358 { 4359 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4360 } 4361 else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4362 { 4363 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4364 } 4365 else 4366 { 4367 DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4368 } 4369 return; 4370 } 4371 4372 4373 #ifdef WORKED 4374 /* triggers incremental discovery */ 4375 osGLOBAL void 4376 dmNotifyBC( 4377 dmRoot_t *dmRoot, 4378 dmPortContext_t *dmPortContext, 4379 bit32 type) 4380 { 4381 dmIntPortContext_t *onePortContext = agNULL; 4382 4383 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4384 4385 DM_DBG3(("dmNotifyBC: start\n")); 4386 4387 4388 if (type == OSSA_HW_EVENT_BROADCAST_CHANGE) 4389 { 4390 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4391 { 4392 DM_DBG3(("dmNotifyBC: BROADCAST_CHANGE; does incremental discovery\n")); 4393 onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 4394 onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_INCREMENTAL_START; 4395 /* processed broadcast change */ 4396 onePortContext->discovery.SeenBC = agFALSE; 4397 if (onePortContext->discovery.ResetTriggerred == agTRUE) 4398 { 4399 DM_DBG3(("dmNotifyBC: tdsaBCTimer\n")); 4400 dmBCTimer(dmRoot, onePortContext); 4401 } 4402 else 4403 { 4404 dmDiscover( 4405 dmRoot, 4406 dmPortContext, 4407 DM_DISCOVERY_OPTION_INCREMENTAL_START 4408 ); 4409 } 4410 } 4411 else 4412 { 4413 DM_DBG3(("dmNotifyBC: pid %d BROADCAST_CHANGE; updating SeenBC. Do nothing.\n", onePortContext->id)); 4414 onePortContext->discovery.SeenBC = agTRUE; 4415 } 4416 } 4417 else if (type == OSSA_HW_EVENT_BROADCAST_SES) 4418 { 4419 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_SES\n")); 4420 } 4421 else if (type == OSSA_HW_EVENT_BROADCAST_EXP) 4422 { 4423 DM_DBG3(("dmNotifyBC: OSSA_HW_EVENT_BROADCAST_EXP\n")); 4424 } 4425 else 4426 { 4427 DM_DBG3(("dmNotifyBC: unspecified broadcast type 0x%x\n", type)); 4428 } 4429 return; 4430 } 4431 #endif 4432 4433 osGLOBAL bit32 4434 dmResetFailedDiscovery( 4435 dmRoot_t *dmRoot, 4436 dmPortContext_t *dmPortContext) 4437 { 4438 dmIntPortContext_t *onePortContext = agNULL; 4439 4440 DM_DBG1(("dmResetFailedDiscovery: start\n")); 4441 4442 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4443 4444 if (onePortContext == agNULL) 4445 { 4446 DM_DBG1(("dmResetFailedDiscovery: onePortContext is NULL, wrong!!!\n")); 4447 return DM_RC_FAILURE; 4448 } 4449 4450 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4451 { 4452 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 4453 } 4454 else 4455 { 4456 DM_DBG1(("dmResetFailedDiscovery: discovery is NOT DM_DSTATE_COMPLETED_WITH_FAILURE. It is 0x%x\n", onePortContext->DiscoveryState)); 4457 return DM_RC_FAILURE; 4458 } 4459 4460 return DM_RC_SUCCESS; 4461 } 4462 4463 osGLOBAL bit32 4464 dmQueryDiscovery( 4465 dmRoot_t *dmRoot, 4466 dmPortContext_t *dmPortContext) 4467 { 4468 dmIntPortContext_t *onePortContext = agNULL; 4469 4470 DM_DBG3(("dmQueryDiscovery: start\n")); 4471 4472 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4473 4474 if (onePortContext == agNULL) 4475 { 4476 DM_DBG1(("dmQueryDiscovery: onePortContext is NULL, wrong!!!\n")); 4477 return DM_RC_FAILURE; 4478 } 4479 4480 /* call tddmQueryDiscoveryCB() */ 4481 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED) 4482 { 4483 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscCompleted); 4484 } 4485 else if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED_WITH_FAILURE) 4486 { 4487 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscFailed); 4488 } 4489 else 4490 { 4491 tddmQueryDiscoveryCB(dmRoot, dmPortContext, onePortContext->discoveryOptions, dmDiscInProgress); 4492 } 4493 4494 return DM_RC_SUCCESS; 4495 } 4496 4497 4498 /* 4499 should only for an expander 4500 */ 4501 osGLOBAL bit32 4502 dmRegisterDevice( 4503 dmRoot_t *dmRoot, 4504 dmPortContext_t *dmPortContext, 4505 dmDeviceInfo_t *dmDeviceInfo, 4506 agsaDevHandle_t *agDevHandle 4507 ) 4508 { 4509 4510 dmIntPortContext_t *onePortContext = agNULL; 4511 dmExpander_t *oneExpander = agNULL; 4512 bit32 sasAddressHi, sasAddressLo; 4513 dmDeviceData_t *oneDeviceData = agNULL; 4514 dmSASSubID_t dmSASSubID; 4515 4516 DM_DBG3(("dmRegisterDevice: start\n")); 4517 4518 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 4519 if (onePortContext == agNULL) 4520 { 4521 DM_DBG1(("dmRegisterDevice: onePortContext is NULL!!!\n")); 4522 return DM_RC_FAILURE; 4523 } 4524 4525 if (onePortContext->valid == agFALSE) 4526 { 4527 DM_DBG1(("dmRegisterDevice: invalid port!!!\n")); 4528 return DM_RC_FAILURE; 4529 } 4530 4531 onePortContext->RegFailed = agFALSE; 4532 4533 /* tdssAddSASToSharedcontext() from ossaHwCB() 4534 osGLOBAL void 4535 tdssAddSASToSharedcontext( 4536 tdsaPortContext_t *tdsaPortContext_Instance, 4537 agsaRoot_t *agRoot, 4538 agsaDevHandle_t *agDevHandle, 4539 tdsaSASSubID_t *agSASSubID, 4540 bit32 registered, 4541 bit8 phyID, 4542 bit32 flag 4543 ); 4544 from discovery 4545 osGLOBAL tdsaDeviceData_t * 4546 tdssNewAddSASToSharedcontext( 4547 agsaRoot_t *agRoot, 4548 tdsaPortContext_t *onePortContext, 4549 tdsaSASSubID_t *agSASSubID, 4550 tdsaDeviceData_t *oneExpDeviceData, 4551 bit8 phyID 4552 ); 4553 4554 */ 4555 /* start here */ 4556 dmSASSubID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4557 dmSASSubID.sasAddressLo = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressLo); 4558 dmSASSubID.initiator_ssp_stp_smp = dmDeviceInfo->initiator_ssp_stp_smp; 4559 dmSASSubID.target_ssp_stp_smp = dmDeviceInfo->target_ssp_stp_smp; 4560 4561 oneDeviceData = dmAddSASToSharedcontext(dmRoot, onePortContext, &dmSASSubID, agNULL, 0xFF); 4562 if (oneDeviceData == agNULL) 4563 { 4564 DM_DBG1(("dmRegisterDevice: oneDeviceData is NULL!!!\n")); 4565 return DM_RC_FAILURE; 4566 } 4567 oneDeviceData->agDeviceInfo.devType_S_Rate = dmDeviceInfo->devType_S_Rate; 4568 dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressHi, dmDeviceInfo->sasAddressHi, 4); 4569 dm_memcpy(oneDeviceData->agDeviceInfo.sasAddressLo, dmDeviceInfo->sasAddressLo, 4); 4570 /* finds the type of expanders */ 4571 if (DEVINFO_GET_EXT_SMP(dmDeviceInfo)) 4572 { 4573 if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_EDGE_EXPANDER_DEVICE) 4574 { 4575 oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4576 } 4577 else if (DEVINFO_GET_EXT_EXPANDER_TYPE(dmDeviceInfo) == SAS_FANOUT_EXPANDER_DEVICE) 4578 { 4579 oneDeviceData->SASSpecDeviceType = SAS_FANOUT_EXPANDER_DEVICE; 4580 } 4581 else 4582 { 4583 /* default */ 4584 DM_DBG4(("dmRegisterDevice: no expander type. default to edge expander\n")); 4585 oneDeviceData->SASSpecDeviceType = SAS_EDGE_EXPANDER_DEVICE; 4586 } 4587 } 4588 4589 if (DEVINFO_GET_EXT_MCN(dmDeviceInfo) == 0xF) 4590 { 4591 DM_DBG1(("dmRegisterDevice: directly attached expander\n")); 4592 oneDeviceData->directlyAttached = agTRUE; 4593 oneDeviceData->dmDeviceInfo.ext = (bit16)(oneDeviceData->dmDeviceInfo.ext | (0xF << 11)); 4594 } 4595 else 4596 { 4597 DM_DBG1(("dmRegisterDevice: NOT directly attached expander\n")); 4598 oneDeviceData->directlyAttached = agFALSE; 4599 } 4600 4601 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 4602 { 4603 DM_DBG3(("dmRegisterDevice: DM_DSTATE_NOT_STARTED\n")); 4604 /* before the discovery is started */ 4605 oneExpander = dmDiscoveringExpanderAlloc(dmRoot, onePortContext, oneDeviceData); 4606 if ( oneExpander != agNULL) 4607 { 4608 oneExpander->agDevHandle = agDevHandle; 4609 /* update SAS address field */ 4610 oneExpander->dmDevice->SASAddressID.sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4611 oneExpander->dmDevice->SASAddressID.sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4612 DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi, oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4613 dmDiscoveringExpanderAdd(dmRoot, onePortContext, oneExpander); 4614 } 4615 else 4616 { 4617 DM_DBG1(("dmRegisterDevice: failed to allocate expander !!!\n")); 4618 /* remember that the registration failed so that a discovery can't be started */ 4619 onePortContext->RegFailed = agTRUE; 4620 return DM_RC_FAILURE; 4621 } 4622 } 4623 else 4624 { 4625 /* 4626 the discovery has started. Alloc and add have been done. 4627 find an expander using dmDeviceInfo, and update the expander's agDevHandle 4628 call dmExpFind() 4629 */ 4630 DM_DBG3(("dmRegisterDevice: NOT DM_DSTATE_NOT_STARTED\n")); 4631 sasAddressHi = DM_GET_SAS_ADDRESSHI(dmDeviceInfo->sasAddressHi); 4632 sasAddressLo = DM_GET_SAS_ADDRESSLO(dmDeviceInfo->sasAddressLo); 4633 DM_DBG3(("dmRegisterDevice: AddrHi 0x%08x AddrLo 0x%08x\n", sasAddressHi, sasAddressLo)); 4634 oneExpander = dmExpFind(dmRoot, onePortContext, sasAddressHi, sasAddressLo); 4635 if ( oneExpander != agNULL) 4636 { 4637 oneExpander->agDevHandle = agDevHandle; 4638 } 4639 else 4640 { 4641 DM_DBG1(("dmRegisterDevice: not allowed case, wrong !!!\n")); 4642 return DM_RC_FAILURE; 4643 } 4644 } 4645 4646 return DM_RC_SUCCESS; 4647 } 4648 4649 osGLOBAL dmExpander_t * 4650 dmDiscoveringExpanderAlloc( 4651 dmRoot_t *dmRoot, 4652 dmIntPortContext_t *onePortContext, 4653 dmDeviceData_t *oneDeviceData 4654 ) 4655 { 4656 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4657 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4658 dmExpander_t *oneExpander = agNULL; 4659 dmList_t *ExpanderList; 4660 4661 DM_DBG3(("dmDiscoveringExpanderAlloc: start\n")); 4662 DM_DBG3(("dmDiscoveringExpanderAlloc: did %d\n", oneDeviceData->id)); 4663 DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4664 DM_DBG3(("dmDiscoveringExpanderAlloc: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4665 4666 if (onePortContext->valid == agFALSE) 4667 { 4668 DM_DBG1(("dmDiscoveringExpanderAlloc: invalid port!!!\n")); 4669 return agNULL; 4670 } 4671 4672 4673 /* check exitence in dmAllShared->mainExpanderList */ 4674 oneExpander = dmExpMainListFind(dmRoot, 4675 onePortContext, 4676 oneDeviceData->SASAddressID.sasAddressHi, 4677 oneDeviceData->SASAddressID.sasAddressLo); 4678 4679 if (oneExpander == agNULL) 4680 { 4681 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4682 if (DMLIST_EMPTY(&(dmAllShared->freeExpanderList))) 4683 { 4684 DM_DBG1(("dmDiscoveringExpanderAlloc: no free expanders pid %d!!!\n", onePortContext->id)); 4685 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4686 return agNULL; 4687 } 4688 else 4689 { 4690 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4691 } 4692 4693 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4694 DMLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(dmAllShared->freeExpanderList)); 4695 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4696 4697 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4698 } 4699 4700 if (oneExpander != agNULL) 4701 { 4702 DM_DBG1(("dmDiscoveringExpanderAlloc: pid %d exp id %d \n", onePortContext->id, oneExpander->id)); 4703 4704 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4705 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 4706 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4707 4708 oneExpander->dmDevice = oneDeviceData; 4709 oneExpander->dmUpStreamExpander = agNULL; 4710 oneExpander->dmCurrentDownStreamExpander = agNULL; 4711 oneExpander->dmReturnginExpander = agNULL; 4712 oneExpander->hasUpStreamDevice = agFALSE; 4713 oneExpander->numOfUpStreamPhys = 0; 4714 oneExpander->currentUpStreamPhyIndex = 0; 4715 oneExpander->discoveringPhyId = 0; 4716 oneExpander->underDiscovering = agFALSE; 4717 dm_memset( &(oneExpander->currentIndex), 0, sizeof(oneExpander->currentIndex)); 4718 4719 oneDeviceData->dmExpander = oneExpander; 4720 DM_DBG3(("dmDiscoveringExpanderAlloc: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 4721 DM_DBG3(("dmDiscoveringExpanderAlloc: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 4722 4723 } 4724 4725 return oneExpander; 4726 } 4727 4728 osGLOBAL void 4729 dmDiscoveringExpanderAdd( 4730 dmRoot_t *dmRoot, 4731 dmIntPortContext_t *onePortContext, 4732 dmExpander_t *oneExpander 4733 ) 4734 { 4735 DM_DBG3(("dmDiscoveringExpanderAdd: start\n")); 4736 DM_DBG3(("dmDiscoveringExpanderAdd: expander id %d\n", oneExpander->id)); 4737 DM_DBG3(("dmDiscoveringExpanderAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4738 DM_DBG3(("dmDiscoveringExpanderAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4739 4740 if (onePortContext->valid == agFALSE) 4741 { 4742 DM_DBG1(("dmDiscoveringExpanderAdd: invalid port!!!\n")); 4743 return; 4744 } 4745 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4746 { 4747 DM_DBG3(("dmDiscoveringExpanderAdd: UPSTREAM\n")); 4748 } 4749 else if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4750 { 4751 DM_DBG3(("dmDiscoveringExpanderAdd: DOWNSTREAM\n")); 4752 } 4753 else 4754 { 4755 DM_DBG3(("dmDiscoveringExpanderAdd: status %d\n", onePortContext->discovery.status)); 4756 } 4757 4758 if ( oneExpander->underDiscovering == agFALSE) 4759 { 4760 DM_DBG3(("dmDiscoveringExpanderAdd: ADDED \n")); 4761 4762 oneExpander->underDiscovering = agTRUE; 4763 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4764 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 4765 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4766 } 4767 4768 return; 4769 } 4770 4771 osGLOBAL dmExpander_t * 4772 dmFindConfigurableExp( 4773 dmRoot_t *dmRoot, 4774 dmIntPortContext_t *onePortContext, 4775 dmExpander_t *oneExpander 4776 ) 4777 { 4778 dmExpander_t *tempExpander; 4779 dmIntPortContext_t *tmpOnePortContext = onePortContext; 4780 dmExpander_t *ret = agNULL; 4781 DM_DBG3(("dmFindConfigurableExp: start\n")); 4782 4783 if (oneExpander == agNULL) 4784 { 4785 DM_DBG3(("dmFindConfigurableExp: NULL expander\n")); 4786 return agNULL; 4787 } 4788 4789 DM_DBG3(("dmFindConfigurableExp: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4790 DM_DBG3(("dmFindConfigurableExp: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4791 4792 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 4793 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4794 { 4795 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4796 DM_DBG3(("dmFindConfigurableExp: empty UpdiscoveringExpanderList\n")); 4797 return agNULL; 4798 } 4799 else 4800 { 4801 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 4802 } 4803 tempExpander = oneExpander->dmUpStreamExpander; 4804 while (tempExpander) 4805 { 4806 DM_DBG3(("dmFindConfigurableExp: loop exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4807 DM_DBG3(("dmFindConfigurableExp: loop exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4808 if (tempExpander->configRouteTable) 4809 { 4810 DM_DBG3(("dmFindConfigurableExp: found configurable expander\n")); 4811 ret = tempExpander; 4812 break; 4813 } 4814 tempExpander = tempExpander->dmUpStreamExpander; 4815 } 4816 4817 return ret; 4818 } 4819 4820 osGLOBAL bit32 4821 dmDuplicateConfigSASAddr( 4822 dmRoot_t *dmRoot, 4823 dmExpander_t *oneExpander, 4824 bit32 configSASAddressHi, 4825 bit32 configSASAddressLo 4826 ) 4827 { 4828 bit32 i; 4829 bit32 ret = agFALSE; 4830 DM_DBG3(("dmDuplicateConfigSASAddr: start\n")); 4831 4832 if (oneExpander == agNULL) 4833 { 4834 DM_DBG3(("dmDuplicateConfigSASAddr: NULL expander\n")); 4835 return agTRUE; 4836 } 4837 4838 if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi && 4839 oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo 4840 ) 4841 { 4842 DM_DBG3(("dmDuplicateConfigSASAddr: unnecessary\n")); 4843 return agTRUE; 4844 } 4845 4846 DM_DBG3(("dmDuplicateConfigSASAddr: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4847 DM_DBG3(("dmDuplicateConfigSASAddr: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4848 DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressHi 0x%08x\n", configSASAddressHi)); 4849 DM_DBG3(("dmDuplicateConfigSASAddr: configsasAddressLo 0x%08x\n", configSASAddressLo)); 4850 DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4851 for(i=0;i<oneExpander->configSASAddrTableIndex;i++) 4852 { 4853 if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi && 4854 oneExpander->configSASAddressLoTable[i] == configSASAddressLo 4855 ) 4856 { 4857 DM_DBG3(("dmDuplicateConfigSASAddr: FOUND\n")); 4858 ret = agTRUE; 4859 break; 4860 } 4861 } 4862 /* new one; let's add it */ 4863 if (ret == agFALSE) 4864 { 4865 DM_DBG3(("dmDuplicateConfigSASAddr: adding configSAS Addr\n")); 4866 DM_DBG3(("dmDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4867 oneExpander->configSASAddressHiTable[oneExpander->configSASAddrTableIndex] = configSASAddressHi; 4868 oneExpander->configSASAddressLoTable[oneExpander->configSASAddrTableIndex] = configSASAddressLo; 4869 oneExpander->configSASAddrTableIndex++; 4870 } 4871 4872 return ret; 4873 } 4874 4875 osGLOBAL bit16 4876 dmFindCurrentDownStreamPhyIndex( 4877 dmRoot_t *dmRoot, 4878 dmExpander_t *oneExpander 4879 ) 4880 { 4881 dmExpander_t *DownStreamExpander; 4882 bit16 index = 0; 4883 bit16 i; 4884 bit8 phyId = 0; 4885 4886 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: start\n")); 4887 4888 if (oneExpander == agNULL) 4889 { 4890 DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, oneExpander is NULL!!!\n")); 4891 return 0; 4892 } 4893 4894 DownStreamExpander = oneExpander->dmCurrentDownStreamExpander; 4895 4896 if (DownStreamExpander == agNULL) 4897 { 4898 DM_DBG1(("dmFindCurrentDownStreamPhyIndex: wrong, DownStreamExpander is NULL!!!\n")); 4899 return 0; 4900 } 4901 4902 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4903 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4904 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 4905 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: downstream exp addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 4906 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: numOfDownStreamPhys %d\n", oneExpander->numOfDownStreamPhys)); 4907 4908 phyId = DownStreamExpander->upStreamPhys[0]; 4909 4910 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: phyId %d\n", phyId)); 4911 4912 for (i=0; i<oneExpander->numOfDownStreamPhys;i++) 4913 { 4914 if (oneExpander->downStreamPhys[i] == phyId) 4915 { 4916 index = i; 4917 break; 4918 } 4919 } 4920 DM_DBG3(("dmFindCurrentDownStreamPhyIndex: index %d\n", index)); 4921 return index; 4922 } 4923 4924 osGLOBAL bit32 4925 dmFindDiscoveringExpander( 4926 dmRoot_t *dmRoot, 4927 dmIntPortContext_t *onePortContext, 4928 dmExpander_t *oneExpander 4929 ) 4930 { 4931 dmList_t *ExpanderList; 4932 dmExpander_t *tempExpander; 4933 dmIntPortContext_t *tmpOnePortContext = onePortContext; 4934 bit32 ret = agFALSE; 4935 4936 4937 DM_DBG3(("dmFindDiscoveringExpander: start\n")); 4938 4939 DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4940 DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4941 4942 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4943 { 4944 DM_DBG3(("dmFindDiscoveringExpander: empty discoveringExpanderList\n")); 4945 return ret; 4946 } 4947 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 4948 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 4949 { 4950 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 4951 if (tempExpander == oneExpander) 4952 { 4953 if (tempExpander != agNULL) 4954 { 4955 DM_DBG3(("dmFindDiscoveringExpander: match, expander id %d\n", tempExpander->id)); 4956 DM_DBG3(("dmFindDiscoveringExpander: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 4957 DM_DBG3(("dmFindDiscoveringExpander: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 4958 } 4959 ret = agTRUE; 4960 break; 4961 } 4962 4963 ExpanderList = ExpanderList->flink; 4964 } 4965 4966 4967 return ret; 4968 } 4969 4970 4971 osGLOBAL void 4972 dmDiscoveringExpanderRemove( 4973 dmRoot_t *dmRoot, 4974 dmIntPortContext_t *onePortContext, 4975 dmExpander_t *oneExpander 4976 ) 4977 { 4978 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 4979 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 4980 4981 DM_DBG3(("dmDiscoveringExpanderRemove: start\n")); 4982 DM_DBG3(("dmDiscoveringExpanderRemove: expander id %d\n", oneExpander->id)); 4983 DM_DBG3(("dmDiscoveringExpanderRemove: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 4984 DM_DBG3(("dmDiscoveringExpanderRemove: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 4985 4986 DM_DBG3(("dmDiscoveringExpanderRemove: BEFORE\n")); 4987 dmDumpAllExp(dmRoot, onePortContext, oneExpander); 4988 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 4989 dmDumpAllFreeExp(dmRoot); 4990 4991 // if is temporary till smp problem is fixed 4992 if (dmFindDiscoveringExpander(dmRoot, onePortContext, oneExpander) == agTRUE) 4993 { 4994 DM_DBG3(("dmDiscoveringExpanderRemove: oneDeviceData %p did %d\n", oneExpander->dmDevice, oneExpander->dmDevice->id)); 4995 DM_DBG3(("dmDiscoveringExpanderRemove: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 4996 4997 if (oneExpander != oneExpander->dmDevice->dmExpander) 4998 { 4999 DM_DBG3(("dmDiscoveringExpanderRemove: before !!! wrong !!!\n")); 5000 } 5001 oneExpander->underDiscovering = agFALSE; 5002 oneExpander->discoveringPhyId = 0; 5003 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5004 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 5005 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5006 5007 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 5008 { 5009 DM_DBG3(("dmDiscoveringExpanderRemove: DISCOVERY_UP_STREAM\n")); 5010 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5011 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->upNode), &(onePortContext->discovery.UpdiscoveringExpanderList)); 5012 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5013 onePortContext->discovery.NumOfUpExp++; 5014 } 5015 else 5016 { 5017 DM_DBG3(("dmDiscoveringExpanderRemove: Status %d\n", onePortContext->discovery.status)); 5018 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5019 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->mainExpanderList)); 5020 // DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 5021 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5022 } 5023 // error checking 5024 if (oneExpander != oneExpander->dmDevice->dmExpander) 5025 { 5026 DM_DBG3(("dmDiscoveringExpanderRemove: after !!! wrong !!!\n")); 5027 } 5028 5029 } //end temp if 5030 else 5031 { 5032 DM_DBG1(("dmDiscoveringExpanderRemove: !!! problem !!!\n")); 5033 } 5034 5035 DM_DBG3(("dmDiscoveringExpanderRemove: AFTER\n")); 5036 5037 dmDumpAllExp(dmRoot, onePortContext, oneExpander); 5038 dmDumpAllUpExp(dmRoot, onePortContext, oneExpander); 5039 dmDumpAllFreeExp(dmRoot); 5040 5041 return; 5042 } 5043 5044 /* 5045 returns an expander with sasAddrLo, sasAddrHi from dmAllShared->mainExpanderList 5046 */ 5047 osGLOBAL dmExpander_t * 5048 dmExpMainListFind( 5049 dmRoot_t *dmRoot, 5050 dmIntPortContext_t *onePortContext, 5051 bit32 sasAddrHi, 5052 bit32 sasAddrLo 5053 ) 5054 { 5055 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5056 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5057 dmList_t *ExpanderList; 5058 dmExpander_t *tempExpander; 5059 5060 DM_DBG3(("dmExpMainListFind: start\n")); 5061 5062 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5063 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 5064 { 5065 DM_DBG1(("dmExpMainListFind: empty mainExpanderList\n")); 5066 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5067 return agNULL; 5068 } 5069 else 5070 { 5071 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5072 } 5073 ExpanderList = dmAllShared->mainExpanderList.flink; 5074 while (ExpanderList != &(dmAllShared->mainExpanderList)) 5075 { 5076 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5077 if (tempExpander == agNULL) 5078 { 5079 DM_DBG1(("dmExpMainListFind: tempExpander is NULL!!!\n")); 5080 return agNULL; 5081 } 5082 DM_DBG3(("dmExpMainListFind: expander id %d\n", tempExpander->id)); 5083 DM_DBG3(("dmExpMainListFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5084 DM_DBG3(("dmExpMainListFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5085 if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5086 (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5087 (tempExpander->dmDevice->dmPortContext == onePortContext) 5088 ) 5089 { 5090 DM_DBG3(("dmExpMainListFind: found expander id %d\n", tempExpander->id)); 5091 DM_DBG3(("dmExpMainListFind: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5092 DM_DBG3(("dmExpMainListFind: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5093 return tempExpander; 5094 } 5095 ExpanderList = ExpanderList->flink; 5096 } 5097 return agNULL; 5098 5099 } 5100 5101 /* 5102 returns an expander with sasAddrLo, sasAddrHi from discoveringExpanderList 5103 */ 5104 osGLOBAL dmExpander_t * 5105 dmExpFind( 5106 dmRoot_t *dmRoot, 5107 dmIntPortContext_t *onePortContext, 5108 bit32 sasAddrHi, 5109 bit32 sasAddrLo 5110 ) 5111 { 5112 dmList_t *ExpanderList; 5113 dmExpander_t *tempExpander; 5114 dmIntPortContext_t *tmpOnePortContext = onePortContext; 5115 DM_DBG3(("dmExpFind: start\n")); 5116 5117 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5118 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5119 { 5120 DM_DBG3(("dmExpFind tdsaDumpAllExp: empty discoveringExpanderList\n")); 5121 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5122 return agNULL; 5123 } 5124 else 5125 { 5126 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5127 } 5128 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5129 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5130 { 5131 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5132 if (tempExpander == agNULL) 5133 { 5134 DM_DBG1(("dmExpFind: tempExpander is NULL!!!\n")); 5135 return agNULL; 5136 } 5137 DM_DBG3(("dmExpFind: expander id %d\n", tempExpander->id)); 5138 DM_DBG3(("dmExpFind: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5139 DM_DBG3(("dmExpFind: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5140 if ((tempExpander->dmDevice->SASAddressID.sasAddressHi == sasAddrHi) && 5141 (tempExpander->dmDevice->SASAddressID.sasAddressLo == sasAddrLo) && 5142 (tempExpander->dmDevice->dmPortContext == onePortContext) 5143 ) 5144 { 5145 DM_DBG3(("dmExpFind: found\n")); 5146 return tempExpander; 5147 } 5148 ExpanderList = ExpanderList->flink; 5149 } 5150 return agNULL; 5151 } 5152 5153 osGLOBAL bit32 5154 dmDiscoverCheck( 5155 dmRoot_t *dmRoot, 5156 dmIntPortContext_t *onePortContext 5157 ) 5158 { 5159 DM_DBG3(("dmDiscoverCheck: start\n")); 5160 5161 if (onePortContext == agNULL) 5162 { 5163 DM_DBG1(("dmDiscoverCheck: onePortContext is NULL!!!\n")); 5164 return agTRUE; 5165 } 5166 if (onePortContext->valid == agFALSE) 5167 { 5168 DM_DBG1(("dmDiscoverCheck: invalid port!!!\n")); 5169 return agTRUE; 5170 } 5171 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5172 onePortContext->discovery.status == DISCOVERY_SAS_DONE 5173 ) 5174 { 5175 DM_DBG1(("dmDiscoverCheck: aborted discovery!!!\n")); 5176 tddmDiscoverCB( 5177 dmRoot, 5178 onePortContext->dmPortContext, 5179 dmDiscAborted 5180 ); 5181 return agTRUE; 5182 } 5183 5184 return agFALSE; 5185 } 5186 5187 /* ??? needs to handle pending SMPs 5188 move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList 5189 */ 5190 osGLOBAL void 5191 dmDiscoverAbort( 5192 dmRoot_t *dmRoot, 5193 dmIntPortContext_t *onePortContext 5194 ) 5195 { 5196 DM_DBG1(("dmDiscoverAbort: start\n")); 5197 5198 if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 5199 onePortContext->discovery.status == DISCOVERY_SAS_DONE) 5200 { 5201 DM_DBG1(("dmDiscoverAbort: not allowed case!!! onePortContext->DiscoveryState 0x%x onePortContext->discovery.status 0x%x\n", 5202 onePortContext->DiscoveryState, onePortContext->discovery.status)); 5203 return; 5204 } 5205 5206 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5207 onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5208 5209 /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5210 dmCleanAllExp(dmRoot, onePortContext); 5211 5212 5213 return; 5214 5215 5216 } 5217 5218 /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList */ 5219 osGLOBAL void 5220 dmCleanAllExp( 5221 dmRoot_t *dmRoot, 5222 dmIntPortContext_t *onePortContext 5223 ) 5224 { 5225 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5226 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5227 dmList_t *ExpanderList; 5228 dmExpander_t *tempExpander; 5229 dmExpander_t *oneExpander = agNULL; 5230 dmIntPortContext_t *tmpOnePortContext = onePortContext; 5231 5232 DM_DBG3(("dmCleanAllExp: start\n")); 5233 DM_DBG3(("dmCleanAllExp: pid %d\n", onePortContext->id)); 5234 5235 DM_DBG3(("dmCleanAllExp: before all clean up\n")); 5236 dmDumpAllFreeExp(dmRoot); 5237 5238 /* clean up UpdiscoveringExpanderList*/ 5239 DM_DBG3(("dmCleanAllExp: clean discoveringExpanderList\n")); 5240 if (!DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5241 { 5242 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5243 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 5244 { 5245 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 5246 if (tempExpander == agNULL) 5247 { 5248 DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5249 return; 5250 } 5251 DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5252 DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5253 DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5254 5255 oneExpander = dmExpMainListFind(dmRoot, 5256 tmpOnePortContext, 5257 tempExpander->dmDevice->SASAddressID.sasAddressHi, 5258 tempExpander->dmDevice->SASAddressID.sasAddressLo); 5259 if (oneExpander == agNULL) 5260 { 5261 DM_DBG3(("dmCleanAllExp: moving\n")); 5262 DM_DBG3(("dmCleanAllExp: moving, exp id %d\n", tempExpander->id)); 5263 /* putting back to the free pool */ 5264 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5265 DMLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 5266 // DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->freeExpanderList)); 5267 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5268 5269 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 5270 { 5271 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5272 break; 5273 } 5274 else 5275 { 5276 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5277 } 5278 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 5279 } 5280 else 5281 { 5282 DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5283 ExpanderList = ExpanderList->flink; 5284 } 5285 } 5286 } 5287 else 5288 { 5289 DM_DBG3(("dmCleanAllExp: empty discoveringExpanderList\n")); 5290 } 5291 5292 /* reset discoveringExpanderList */ 5293 DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.discoveringExpanderList)); 5294 5295 /* clean up UpdiscoveringExpanderList*/ 5296 DM_DBG3(("dmCleanAllExp: clean UpdiscoveringExpanderList\n")); 5297 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5298 { 5299 DM_DBG3(("dmCleanAllExp: empty UpdiscoveringExpanderList\n")); 5300 return; 5301 } 5302 ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5303 while (ExpanderList != &(tmpOnePortContext->discovery.UpdiscoveringExpanderList)) 5304 { 5305 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, upNode, ExpanderList); 5306 if (tempExpander == agNULL) 5307 { 5308 DM_DBG1(("dmCleanAllExp: tempExpander is NULL!!!\n")); 5309 return; 5310 } 5311 DM_DBG3(("dmCleanAllExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 5312 DM_DBG3(("dmCleanAllExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 5313 DM_DBG3(("dmCleanAllExp: exp id %d\n", tempExpander->id)); 5314 oneExpander = dmExpMainListFind(dmRoot, 5315 tmpOnePortContext, 5316 tempExpander->dmDevice->SASAddressID.sasAddressHi, 5317 tempExpander->dmDevice->SASAddressID.sasAddressLo); 5318 if (oneExpander == agNULL) 5319 { 5320 DM_DBG3(("dmCleanAllExp: moving\n")); 5321 DM_DBG3(("dmCleanAllExp: moving exp id %d\n", tempExpander->id)); 5322 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 5323 DMLIST_DEQUEUE_THIS(&(tempExpander->upNode)); 5324 DMLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(dmAllShared->mainExpanderList)); 5325 5326 if (DMLIST_EMPTY(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList))) 5327 { 5328 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5329 break; 5330 } 5331 else 5332 { 5333 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 5334 } 5335 ExpanderList = tmpOnePortContext->discovery.UpdiscoveringExpanderList.flink; 5336 } 5337 else 5338 { 5339 DM_DBG3(("dmCleanAllExp: in mainExpanderList; skippig\n")); 5340 ExpanderList = ExpanderList->flink; 5341 } 5342 } 5343 5344 /* reset UpdiscoveringExpanderList */ 5345 DMLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList)); 5346 5347 DM_DBG3(("dmCleanAllExp: after all clean up\n")); 5348 dmDumpAllFreeExp(dmRoot); 5349 5350 return; 5351 } 5352 5353 osGLOBAL void 5354 dmInternalRemovals( 5355 dmRoot_t *dmRoot, 5356 dmIntPortContext_t *onePortContext 5357 ) 5358 { 5359 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5360 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5361 dmDeviceData_t *oneDeviceData = agNULL; 5362 dmList_t *DeviceListList; 5363 5364 5365 DM_DBG3(("dmInternalRemovals: start\n")); 5366 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5367 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5368 { 5369 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5370 DM_DBG3(("dmInternalRemovals: empty device list\n")); 5371 return; 5372 } 5373 else 5374 { 5375 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5376 } 5377 5378 DeviceListList = dmAllShared->MainDeviceList.flink; 5379 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5380 { 5381 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5382 if (oneDeviceData == agNULL) 5383 { 5384 DM_DBG1(("dmInternalRemovals: oneDeviceData is NULL!!!\n")); 5385 return; 5386 } 5387 DM_DBG3(("dmInternalRemovals: loop did %d\n", oneDeviceData->id)); 5388 DM_DBG3(("dmInternalRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5389 DM_DBG3(("dmInternalRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5390 DM_DBG3(("dmInternalRemovals: valid %d\n", oneDeviceData->valid)); 5391 DM_DBG3(("dmInternalRemovals: valid2 %d\n", oneDeviceData->valid2)); 5392 DM_DBG3(("dmInternalRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5393 if ( oneDeviceData->dmPortContext == onePortContext) 5394 { 5395 DM_DBG3(("dmInternalRemovals: right portcontext pid %d\n", onePortContext->id)); 5396 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 5397 { 5398 DM_DBG3(("dmInternalRemovals: incremental discovery\n")); 5399 oneDeviceData->valid2 = agFALSE; 5400 } 5401 else 5402 { 5403 DM_DBG3(("dmInternalRemovals: full discovery\n")); 5404 oneDeviceData->valid = agFALSE; 5405 } 5406 DeviceListList = DeviceListList->flink; 5407 } 5408 else 5409 { 5410 if (oneDeviceData->dmPortContext != agNULL) 5411 { 5412 DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5413 } 5414 else 5415 { 5416 DM_DBG3(("dmInternalRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5417 } 5418 DeviceListList = DeviceListList->flink; 5419 } 5420 } 5421 5422 5423 return; 5424 } 5425 5426 osGLOBAL void 5427 dmDiscoveryResetProcessed( 5428 dmRoot_t *dmRoot, 5429 dmIntPortContext_t *onePortContext 5430 ) 5431 { 5432 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5433 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5434 dmDeviceData_t *oneDeviceData = agNULL; 5435 dmList_t *DeviceListList; 5436 5437 DM_DBG3(("dmDiscoveryResetProcessed: start\n")); 5438 5439 /* reinitialize the device data belonging to this portcontext */ 5440 DeviceListList = dmAllShared->MainDeviceList.flink; 5441 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5442 { 5443 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5444 if (oneDeviceData == agNULL) 5445 { 5446 DM_DBG1(("dmDiscoveryResetProcessed: oneDeviceData is NULL!!!\n")); 5447 return; 5448 } 5449 DM_DBG3(("dmDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id)); 5450 if (oneDeviceData->dmPortContext == onePortContext) 5451 { 5452 DM_DBG3(("dmDiscoveryResetProcessed: resetting procssed flag\n")); 5453 oneDeviceData->processed = agFALSE; 5454 } 5455 DeviceListList = DeviceListList->flink; 5456 } 5457 5458 return; 5459 } 5460 5461 /* 5462 calls 5463 osGLOBAL void 5464 tddmDiscoverCB( 5465 dmRoot_t *dmRoot, 5466 dmPortContext_t *dmPortContext, 5467 bit32 eventStatus 5468 ) 5469 5470 */ 5471 osGLOBAL void 5472 dmDiscoverDone( 5473 dmRoot_t *dmRoot, 5474 dmIntPortContext_t *onePortContext, 5475 bit32 flag 5476 ) 5477 { 5478 5479 DM_DBG3(("dmDiscoverDone: start\n")); 5480 DM_DBG3(("dmDiscoverDone: pid %d\n", onePortContext->id)); 5481 5482 /* Set discovery status */ 5483 onePortContext->discovery.status = DISCOVERY_SAS_DONE; 5484 5485 5486 /* clean up expanders data strucures; move to free exp when device is cleaned */ 5487 dmCleanAllExp(dmRoot, onePortContext); 5488 5489 dmDumpAllMainExp(dmRoot, onePortContext); 5490 5491 dmDiscoveryResetProcessed(dmRoot, onePortContext); 5492 5493 dmDiscoveryDumpMCN(dmRoot, onePortContext); 5494 5495 if (onePortContext->discovery.SeenBC == agTRUE) 5496 { 5497 DM_DBG3(("dmDiscoverDone: broadcast change; discover again\n")); 5498 dmDiscoveryResetMCN(dmRoot, onePortContext); 5499 5500 dmInternalRemovals(dmRoot, onePortContext); 5501 5502 /* processed broadcast change */ 5503 onePortContext->discovery.SeenBC = agFALSE; 5504 if (onePortContext->discovery.ResetTriggerred == agTRUE) 5505 { 5506 DM_DBG3(("dmDiscoverDone: dmBCTimer\n")); 5507 dmBCTimer(dmRoot, onePortContext); 5508 } 5509 else 5510 { 5511 5512 dmIncrementalDiscover(dmRoot, onePortContext, agTRUE); 5513 } 5514 } 5515 else 5516 { 5517 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 5518 5519 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_FULL_START) 5520 { 5521 if (flag == DM_RC_SUCCESS) 5522 { 5523 5524 dmResetReported(dmRoot, 5525 onePortContext 5526 ); 5527 5528 dmDiscoveryReportMCN(dmRoot, 5529 onePortContext 5530 ); 5531 5532 5533 /* call tddmDiscoverCB() */ 5534 tddmDiscoverCB( 5535 dmRoot, 5536 onePortContext->dmPortContext, 5537 dmDiscCompleted 5538 ); 5539 } 5540 else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5541 { 5542 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5543 DM_DBG1(("dmDiscoverDone: Error; clean up!!!\n")); 5544 5545 dmDiscoveryInvalidateDevices(dmRoot, 5546 onePortContext 5547 ); 5548 5549 tddmDiscoverCB( 5550 dmRoot, 5551 onePortContext->dmPortContext, 5552 dmDiscFailed 5553 ); 5554 } 5555 } 5556 else 5557 { 5558 if (flag == DM_RC_SUCCESS) 5559 { 5560 dmReportChanges(dmRoot, 5561 onePortContext 5562 ); 5563 dmDiscoveryReportMCN(dmRoot, 5564 onePortContext 5565 ); 5566 tddmDiscoverCB( 5567 dmRoot, 5568 onePortContext->dmPortContext, 5569 dmDiscCompleted 5570 ); 5571 } 5572 else if (flag != DM_RC_SUCCESS || onePortContext->discovery.DeferredError == agTRUE) 5573 { 5574 onePortContext->DiscoveryState = DM_DSTATE_COMPLETED_WITH_FAILURE; 5575 dmDiscoveryInvalidateDevices(dmRoot, 5576 onePortContext 5577 ); 5578 5579 tddmDiscoverCB( 5580 dmRoot, 5581 onePortContext->dmPortContext, 5582 dmDiscFailed 5583 ); 5584 } 5585 } 5586 } 5587 return; 5588 } 5589 5590 /* called by dmDiscoveryErrorRemovals() or dmReportRemovals() on discovery failure */ 5591 osGLOBAL void 5592 dmSubReportRemovals( 5593 dmRoot_t *dmRoot, 5594 dmIntPortContext_t *onePortContext, 5595 dmDeviceData_t *oneDeviceData, 5596 bit32 flag 5597 ) 5598 { 5599 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5600 DM_DBG3(("dmSubReportRemovals: start\n")); 5601 5602 DM_DBG3(("dmSubReportRemovals: flag 0x%x\n", flag)); 5603 if (flag == dmDeviceRemoval) 5604 { 5605 oneDeviceData->registered = agFALSE; 5606 } 5607 5608 if (oneDeviceData->ExpDevice != agNULL) 5609 { 5610 DM_DBG3(("dmSubReportRemovals: attached expander case\n")); 5611 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5612 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5613 } 5614 else 5615 { 5616 DM_DBG3(("dmSubReportRemovals: NO attached expander case\n")); 5617 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5618 } 5619 5620 5621 /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5622 oneDeviceData->reported = agFALSE; 5623 return; 5624 } 5625 5626 5627 /* called by dmReportChanges() on discovery success */ 5628 osGLOBAL void 5629 dmSubReportChanges( 5630 dmRoot_t *dmRoot, 5631 dmIntPortContext_t *onePortContext, 5632 dmDeviceData_t *oneDeviceData, 5633 bit32 flag 5634 ) 5635 { 5636 dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5637 DM_DBG3(("dmSubReportChanges: start\n")); 5638 5639 DM_DBG3(("dmSubReportChanges: flag 0x%x\n", flag)); 5640 if (flag == dmDeviceRemoval) 5641 { 5642 oneDeviceData->registered = agFALSE; 5643 } 5644 if (oneDeviceData->reported == agFALSE) 5645 { 5646 if (oneDeviceData->ExpDevice != agNULL) 5647 { 5648 DM_DBG3(("dmSubReportChanges: attached expander case\n")); 5649 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 5650 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, &oneAttachedExpDeviceData->dmDeviceInfo, flag); 5651 } 5652 else 5653 { 5654 DM_DBG3(("dmSubReportChanges: NO attached expander case\n")); 5655 tddmReportDevice(dmRoot, onePortContext->dmPortContext, &oneDeviceData->dmDeviceInfo, agNULL, flag); 5656 } 5657 } 5658 else 5659 { 5660 DM_DBG3(("dmSubReportChanges: skip; been reported\n")); 5661 } 5662 5663 5664 /* this function is called at the end of discovery; reinitalizes oneDeviceData->reported */ 5665 oneDeviceData->reported = agFALSE; 5666 return; 5667 } 5668 5669 /* 5670 should add or remove be reported per device??? 5671 */ 5672 osGLOBAL void 5673 dmReportChanges( 5674 dmRoot_t *dmRoot, 5675 dmIntPortContext_t *onePortContext 5676 ) 5677 { 5678 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5679 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5680 dmDeviceData_t *oneDeviceData = agNULL; 5681 dmList_t *DeviceListList; 5682 bit32 added = agFALSE, removed = agFALSE; 5683 // dmDeviceData_t *oneAttachedExpDeviceData = agNULL; 5684 5685 DM_DBG3(("dmReportChanges: start\n")); 5686 5687 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5688 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5689 { 5690 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5691 DM_DBG3(("dmReportChanges: empty device list\n")); 5692 return; 5693 } 5694 else 5695 { 5696 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5697 } 5698 5699 DeviceListList = dmAllShared->MainDeviceList.flink; 5700 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5701 { 5702 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5703 if (oneDeviceData == agNULL) 5704 { 5705 DM_DBG1(("dmReportChanges: oneDeviceData is NULL!!!\n")); 5706 return; 5707 } 5708 DM_DBG3(("dmReportChanges: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5709 DM_DBG3(("dmReportChanges: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5710 if ( oneDeviceData->dmPortContext == onePortContext) 5711 { 5712 DM_DBG3(("dmReportChanges: right portcontext\n")); 5713 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5714 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5715 ) 5716 { 5717 DM_DBG1(("dmReportChanges: keep, not reporting did 0x%x\n", oneDeviceData->id)); 5718 oneDeviceData->valid = agTRUE; 5719 oneDeviceData->valid2 = agFALSE; 5720 } 5721 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) ) 5722 { 5723 DM_DBG3(("dmReportChanges: same\n")); 5724 /* reset valid bit */ 5725 oneDeviceData->valid = oneDeviceData->valid2; 5726 oneDeviceData->valid2 = agFALSE; 5727 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceNoChange); 5728 } 5729 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) ) 5730 { 5731 DM_DBG3(("dmReportChanges: removed\n")); 5732 removed = agTRUE; 5733 /* reset valid bit */ 5734 oneDeviceData->valid = oneDeviceData->valid2; 5735 oneDeviceData->valid2 = agFALSE; 5736 5737 onePortContext->RegisteredDevNums--; 5738 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5739 } 5740 else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) ) 5741 { 5742 DM_DBG3(("dmReportChanges: added\n")); 5743 added = agTRUE; 5744 /* reset valid bit */ 5745 oneDeviceData->valid = oneDeviceData->valid2; 5746 oneDeviceData->valid2 = agFALSE; 5747 dmSubReportChanges(dmRoot, onePortContext, oneDeviceData, dmDeviceArrival); 5748 } 5749 else 5750 { 5751 DM_DBG3(("dmReportChanges: else\n")); 5752 } 5753 } 5754 else 5755 { 5756 DM_DBG3(("dmReportChanges: different portcontext\n")); 5757 } 5758 DeviceListList = DeviceListList->flink; 5759 } 5760 /* 5761 osGLOBAL void 5762 tddmReportDevice( 5763 dmRoot_t *dmRoot, 5764 dmPortContext_t *dmPortContext, 5765 dmDeviceInfo_t *dmDeviceInfo, 5766 dmDeviceInfo_t *dmExpDeviceInfo, 5767 bit32 flag 5768 5769 ) 5770 5771 */ 5772 5773 /* arrival or removal at once */ 5774 if (added == agTRUE) 5775 { 5776 DM_DBG3(("dmReportChanges: added at the end\n")); 5777 #if 0 /* TBD */ 5778 ostiInitiatorEvent( 5779 tiRoot, 5780 onePortContext->tiPortalContext, 5781 agNULL, 5782 tiIntrEventTypeDeviceChange, 5783 tiDeviceArrival, 5784 agNULL 5785 ); 5786 #endif 5787 5788 } 5789 if (removed == agTRUE) 5790 { 5791 DM_DBG3(("dmReportChanges: removed at the end\n")); 5792 #if 0 /* TBD */ 5793 ostiInitiatorEvent( 5794 tiRoot, 5795 onePortContext->tiPortalContext, 5796 agNULL, 5797 tiIntrEventTypeDeviceChange, 5798 tiDeviceRemoval, 5799 agNULL 5800 ); 5801 #endif 5802 } 5803 5804 if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE) 5805 { 5806 DM_DBG3(("dmReportChanges: missed chance to report. forced to report OK\n")); 5807 onePortContext->discovery.forcedOK = agFALSE; 5808 #if 0 /* TBD */ 5809 ostiInitiatorEvent( 5810 tiRoot, 5811 onePortContext->tiPortalContext, 5812 agNULL, 5813 tiIntrEventTypeDiscovery, 5814 tiDiscOK, 5815 agNULL 5816 ); 5817 #endif 5818 } 5819 5820 if (added == agFALSE && removed == agFALSE) 5821 { 5822 DM_DBG3(("dmReportChanges: the same\n")); 5823 } 5824 5825 return; 5826 } 5827 5828 osGLOBAL void 5829 dmReportRemovals( 5830 dmRoot_t *dmRoot, 5831 dmIntPortContext_t *onePortContext, 5832 bit32 flag 5833 ) 5834 { 5835 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5836 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5837 dmDeviceData_t *oneDeviceData = agNULL; 5838 dmList_t *DeviceListList; 5839 bit32 removed = agFALSE; 5840 5841 DM_DBG1(("dmReportRemovals: start\n")); 5842 5843 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5844 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5845 { 5846 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5847 DM_DBG3(("dmReportRemovals: empty device list\n")); 5848 return; 5849 } 5850 else 5851 { 5852 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5853 } 5854 5855 DeviceListList = dmAllShared->MainDeviceList.flink; 5856 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5857 { 5858 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5859 if (oneDeviceData == agNULL) 5860 { 5861 DM_DBG1(("dmReportRemovals: oneDeviceData is NULL!!!\n")); 5862 return; 5863 } 5864 DM_DBG3(("dmReportRemovals: loop did %d\n", oneDeviceData->id)); 5865 DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5866 DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5867 DM_DBG3(("dmReportRemovals: valid %d\n", oneDeviceData->valid)); 5868 DM_DBG3(("dmReportRemovals: valid2 %d\n", oneDeviceData->valid2)); 5869 DM_DBG3(("dmReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5870 if ( oneDeviceData->dmPortContext == onePortContext) 5871 { 5872 DM_DBG3(("dmReportRemovals: right portcontext pid %d\n", onePortContext->id)); 5873 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 5874 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 5875 ) 5876 { 5877 DM_DBG1(("dmReportRemovals: keeping\n")); 5878 oneDeviceData->valid = agTRUE; 5879 oneDeviceData->valid2 = agFALSE; 5880 } 5881 else if (oneDeviceData->valid == agTRUE) 5882 { 5883 DM_DBG3(("dmReportRemovals: removing\n")); 5884 5885 /* notify only reported devices to OS layer*/ 5886 if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || 5887 DEVICE_IS_STP_TARGET(oneDeviceData) || 5888 DEVICE_IS_SATA_DEVICE(oneDeviceData) 5889 ) 5890 { 5891 removed = agTRUE; 5892 } 5893 5894 /* all targets except expanders */ 5895 DM_DBG3(("dmReportRemovals: did %d\n", oneDeviceData->id)); 5896 DM_DBG3(("dmReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5897 DM_DBG3(("dmReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5898 onePortContext->RegisteredDevNums--; 5899 dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 5900 5901 5902 /* reset valid bit */ 5903 oneDeviceData->valid = agFALSE; 5904 oneDeviceData->valid2 = agFALSE; 5905 5906 5907 } 5908 /* called by port invalid case */ 5909 if (flag == agTRUE) 5910 { 5911 oneDeviceData->dmPortContext = agNULL; 5912 } 5913 DeviceListList = DeviceListList->flink; 5914 } 5915 else 5916 { 5917 if (oneDeviceData->dmPortContext != agNULL) 5918 { 5919 DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5920 } 5921 else 5922 { 5923 DM_DBG3(("dmReportRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 5924 } 5925 DeviceListList = DeviceListList->flink; 5926 } 5927 } 5928 5929 if (removed == agTRUE) 5930 { 5931 DM_DBG3(("dmReportRemovals: removed at the end\n")); 5932 #if 0 /* TBD */ 5933 ostiInitiatorEvent( 5934 tiRoot, 5935 onePortContext->tiPortalContext, 5936 agNULL, 5937 tiIntrEventTypeDeviceChange, 5938 tiDeviceRemoval, 5939 agNULL 5940 ); 5941 #endif 5942 } 5943 5944 return; 5945 } 5946 5947 osGLOBAL void 5948 dmResetReported( 5949 dmRoot_t *dmRoot, 5950 dmIntPortContext_t *onePortContext 5951 ) 5952 { 5953 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 5954 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 5955 dmDeviceData_t *oneDeviceData = agNULL; 5956 dmList_t *DeviceListList; 5957 5958 DM_DBG3(("dmResetReported: start\n")); 5959 5960 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 5961 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 5962 { 5963 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5964 DM_DBG3(("dmResetReported: empty device list\n")); 5965 return; 5966 } 5967 else 5968 { 5969 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 5970 } 5971 5972 DeviceListList = dmAllShared->MainDeviceList.flink; 5973 while (DeviceListList != &(dmAllShared->MainDeviceList)) 5974 { 5975 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 5976 if (oneDeviceData == agNULL) 5977 { 5978 DM_DBG1(("dmResetReported: oneDeviceData is NULL!!!\n")); 5979 return; 5980 } 5981 DM_DBG3(("dmResetReported: loop did %d\n", oneDeviceData->id)); 5982 DM_DBG3(("dmResetReported: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 5983 DM_DBG3(("dmResetReported: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 5984 DM_DBG3(("dmResetReported: valid %d\n", oneDeviceData->valid)); 5985 DM_DBG3(("dmResetReported: valid2 %d\n", oneDeviceData->valid2)); 5986 DM_DBG3(("dmResetReported: directlyAttached %d\n", oneDeviceData->directlyAttached)); 5987 if ( oneDeviceData->dmPortContext == onePortContext) 5988 { 5989 DM_DBG3(("dmResetReported: right portcontext pid %d\n", onePortContext->id)); 5990 oneDeviceData->reported = agFALSE; 5991 DeviceListList = DeviceListList->flink; 5992 } 5993 else 5994 { 5995 if (oneDeviceData->dmPortContext != agNULL) 5996 { 5997 DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 5998 } 5999 else 6000 { 6001 DM_DBG3(("dmResetReported: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6002 } 6003 DeviceListList = DeviceListList->flink; 6004 } 6005 } 6006 6007 return; 6008 } 6009 6010 /* called on discover failure */ 6011 osGLOBAL void 6012 dmDiscoveryInvalidateDevices( 6013 dmRoot_t *dmRoot, 6014 dmIntPortContext_t *onePortContext 6015 ) 6016 { 6017 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6018 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6019 dmDeviceData_t *oneDeviceData = agNULL; 6020 dmList_t *DeviceListList; 6021 6022 DM_DBG1(("dmDiscoveryInvalidateDevices: start\n")); 6023 6024 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6025 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6026 { 6027 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6028 DM_DBG3(("dmDiscoveryInvalidateDevices: empty device list\n")); 6029 return; 6030 } 6031 else 6032 { 6033 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6034 } 6035 DeviceListList = dmAllShared->MainDeviceList.flink; 6036 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6037 { 6038 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6039 if (oneDeviceData == agNULL) 6040 { 6041 DM_DBG1(("dmDiscoveryInvalidateDevices: oneDeviceData is NULL!!!\n")); 6042 return; 6043 } 6044 DM_DBG3(("dmDiscoveryInvalidateDevices: loop did %d\n", oneDeviceData->id)); 6045 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6046 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6047 DM_DBG3(("dmDiscoveryInvalidateDevices: valid %d\n", oneDeviceData->valid)); 6048 DM_DBG3(("dmDiscoveryInvalidateDevices: valid2 %d\n", oneDeviceData->valid2)); 6049 DM_DBG3(("dmDiscoveryInvalidateDevices: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6050 if ( oneDeviceData->dmPortContext == onePortContext) 6051 { 6052 DM_DBG3(("dmDiscoveryInvalidateDevices: right portcontext pid %d\n", onePortContext->id)); 6053 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6054 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6055 ) 6056 { 6057 DM_DBG1(("dmDiscoveryInvalidateDevices: keeping\n")); 6058 oneDeviceData->valid = agTRUE; 6059 oneDeviceData->valid2 = agFALSE; 6060 } 6061 else 6062 { 6063 oneDeviceData->valid = agFALSE; 6064 oneDeviceData->valid2 = agFALSE; 6065 oneDeviceData->registered = agFALSE; 6066 oneDeviceData->reported = agFALSE; 6067 /* all targets other than expanders */ 6068 DM_DBG3(("dmDiscoveryInvalidateDevices: did %d\n", oneDeviceData->id)); 6069 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6070 DM_DBG3(("dmDiscoveryInvalidateDevices: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6071 onePortContext->RegisteredDevNums--; 6072 } 6073 DeviceListList = DeviceListList->flink; 6074 } 6075 else 6076 { 6077 if (oneDeviceData->dmPortContext != agNULL) 6078 { 6079 DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6080 } 6081 else 6082 { 6083 DM_DBG3(("dmDiscoveryInvalidateDevices: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6084 } 6085 DeviceListList = DeviceListList->flink; 6086 } 6087 } 6088 6089 return; 6090 } 6091 6092 6093 /* 6094 should DM report the device removal to TDM on an error case? 6095 or 6096 DM simply removes the devices 6097 For now, the second option. 6098 */ 6099 osGLOBAL void 6100 dmDiscoveryErrorRemovals( 6101 dmRoot_t *dmRoot, 6102 dmIntPortContext_t *onePortContext 6103 ) 6104 { 6105 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6106 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6107 dmDeviceData_t *oneDeviceData = agNULL; 6108 dmList_t *DeviceListList; 6109 6110 DM_DBG1(("dmDiscoveryErrorRemovals: start\n")); 6111 6112 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6113 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6114 { 6115 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6116 DM_DBG3(("dmDiscoveryErrorRemovals: empty device list\n")); 6117 return; 6118 } 6119 else 6120 { 6121 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6122 } 6123 DeviceListList = dmAllShared->MainDeviceList.flink; 6124 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6125 { 6126 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6127 if (oneDeviceData == agNULL) 6128 { 6129 DM_DBG1(("dmDiscoveryErrorRemovals: oneDeviceData is NULL!!!\n")); 6130 return; 6131 } 6132 DM_DBG3(("dmDiscoveryErrorRemovals: loop did %d\n", oneDeviceData->id)); 6133 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6134 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6135 DM_DBG3(("dmDiscoveryErrorRemovals: valid %d\n", oneDeviceData->valid)); 6136 DM_DBG3(("dmDiscoveryErrorRemovals: valid2 %d\n", oneDeviceData->valid2)); 6137 DM_DBG3(("dmDiscoveryErrorRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 6138 if ( oneDeviceData->dmPortContext == onePortContext) 6139 { 6140 DM_DBG3(("dmDiscoveryErrorRemovals: right portcontext pid %d\n", onePortContext->id)); 6141 if (oneDeviceData->SASAddressID.sasAddressHi == onePortContext->sasRemoteAddressHi && 6142 oneDeviceData->SASAddressID.sasAddressLo == onePortContext->sasRemoteAddressLo 6143 ) 6144 { 6145 DM_DBG1(("dmDiscoveryErrorRemovals: keeping\n")); 6146 oneDeviceData->valid = agTRUE; 6147 oneDeviceData->valid2 = agFALSE; 6148 } 6149 else 6150 { 6151 oneDeviceData->valid = agFALSE; 6152 oneDeviceData->valid2 = agFALSE; 6153 6154 /* all targets other than expanders */ 6155 DM_DBG3(("dmDiscoveryErrorRemovals: did %d\n", oneDeviceData->id)); 6156 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6157 DM_DBG3(("dmDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6158 onePortContext->RegisteredDevNums--; 6159 dmSubReportRemovals(dmRoot, onePortContext, oneDeviceData, dmDeviceRemoval); 6160 6161 } 6162 DeviceListList = DeviceListList->flink; 6163 } 6164 else 6165 { 6166 if (oneDeviceData->dmPortContext != agNULL) 6167 { 6168 DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid %d oneportcontext pid %d\n", oneDeviceData->dmPortContext->id, onePortContext->id)); 6169 } 6170 else 6171 { 6172 DM_DBG3(("dmDiscoveryErrorRemovals: different portcontext; oneDeviceData->dmPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 6173 } 6174 DeviceListList = DeviceListList->flink; 6175 } 6176 } 6177 6178 return; 6179 } 6180 6181 /* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */ 6182 osGLOBAL void 6183 dmDiscoveryExpanderCleanUp( 6184 dmRoot_t *dmRoot, 6185 dmIntPortContext_t *onePortContext 6186 ) 6187 { 6188 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6189 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6190 dmExpander_t *oneExpander = agNULL; 6191 dmList_t *ExpanderList = agNULL; 6192 dmDeviceData_t *oneDeviceData = agNULL; 6193 6194 DM_DBG3(("dmDiscoveryExpanderCleanUp: start\n")); 6195 /* 6196 be sure to call 6197 osGLOBAL void 6198 dmExpanderDeviceDataReInit( 6199 dmRoot_t *dmRoot, 6200 dmExpander_t *oneExpander 6201 ); 6202 6203 */ 6204 6205 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6206 if (!DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6207 { 6208 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6209 ExpanderList = dmAllShared->mainExpanderList.flink; 6210 while (ExpanderList != &(dmAllShared->mainExpanderList)) 6211 { 6212 oneExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6213 if (oneExpander == agNULL) 6214 { 6215 DM_DBG1(("dmDiscoveryExpanderCleanUp: oneExpander is NULL!!!\n")); 6216 return; 6217 } 6218 oneDeviceData = oneExpander->dmDevice; 6219 DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6220 DM_DBG3(("dmDiscoveryExpanderCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6221 if ( oneDeviceData->dmPortContext == onePortContext) 6222 { 6223 dmExpanderDeviceDataReInit(dmRoot, oneExpander); 6224 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6225 DMLIST_DEQUEUE_THIS(&(oneExpander->linkNode)); 6226 DMLIST_ENQUEUE_AT_TAIL(&(oneExpander->linkNode), &(dmAllShared->freeExpanderList)); 6227 6228 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6229 { 6230 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6231 break; 6232 } 6233 else 6234 { 6235 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6236 } 6237 ExpanderList = dmAllShared->mainExpanderList.flink; 6238 } 6239 else 6240 { 6241 ExpanderList = ExpanderList->flink; 6242 } 6243 } 6244 } 6245 else 6246 { 6247 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6248 DM_DBG3(("dmDiscoveryExpanderCleanUp: empty mainExpanderList\n")); 6249 } 6250 return; 6251 6252 } 6253 6254 6255 /* moves all devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */ 6256 osGLOBAL void 6257 dmDiscoveryDeviceCleanUp( 6258 dmRoot_t *dmRoot, 6259 dmIntPortContext_t *onePortContext 6260 ) 6261 { 6262 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6263 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6264 dmDeviceData_t *oneDeviceData = agNULL; 6265 dmList_t *DeviceListList; 6266 6267 DM_DBG3(("dmDiscoveryDeviceCleanUp: start\n")); 6268 6269 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6270 if (!DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6271 { 6272 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6273 DeviceListList = dmAllShared->MainDeviceList.flink; 6274 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6275 { 6276 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6277 if (oneDeviceData == agNULL) 6278 { 6279 DM_DBG1(("dmDiscoveryDeviceCleanUp: oneDeviceData is NULL!!!\n")); 6280 return; 6281 } 6282 DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6283 DM_DBG3(("dmDiscoveryDeviceCleanUp: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6284 if ( oneDeviceData->dmPortContext == onePortContext) 6285 { 6286 dmDeviceDataReInit(dmRoot, oneDeviceData); 6287 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6288 DMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 6289 DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(dmAllShared->FreeDeviceList)); 6290 6291 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6292 { 6293 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6294 break; 6295 } 6296 else 6297 { 6298 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6299 } 6300 onePortContext->RegisteredDevNums--; 6301 DeviceListList = dmAllShared->MainDeviceList.flink; 6302 } 6303 else 6304 { 6305 DeviceListList = DeviceListList->flink; 6306 } 6307 } 6308 } 6309 else 6310 { 6311 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6312 DM_DBG3(("dmDiscoveryDeviceCleanUp: empty MainDeviceList\n")); 6313 } 6314 return; 6315 } 6316 6317 6318 6319 osGLOBAL void 6320 dmDumpAllExp( 6321 dmRoot_t *dmRoot, 6322 dmIntPortContext_t *onePortContext, 6323 dmExpander_t *oneExpander 6324 ) 6325 { 6326 DM_DBG3(("dmDumpAllExp: start\n")); 6327 return; 6328 } 6329 6330 6331 osGLOBAL void 6332 dmDumpAllUpExp( 6333 dmRoot_t *dmRoot, 6334 dmIntPortContext_t *onePortContext, 6335 dmExpander_t *oneExpander 6336 ) 6337 { 6338 DM_DBG3(("dmDumpAllUpExp: start\n")); 6339 return; 6340 } 6341 6342 osGLOBAL void 6343 dmDumpAllFreeExp( 6344 dmRoot_t *dmRoot 6345 ) 6346 { 6347 DM_DBG3(("dmDumpAllFreeExp: start\n")); 6348 return; 6349 } 6350 6351 osGLOBAL void 6352 dmDumpAllMainExp( 6353 dmRoot_t *dmRoot, 6354 dmIntPortContext_t *onePortContext 6355 ) 6356 { 6357 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6358 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6359 dmList_t *ExpanderList; 6360 dmExpander_t *tempExpander; 6361 6362 DM_DBG3(("dmDumpAllMainExp: start\n")); 6363 6364 tddmSingleThreadedEnter(dmRoot, DM_EXPANDER_LOCK); 6365 if (DMLIST_EMPTY(&(dmAllShared->mainExpanderList))) 6366 { 6367 DM_DBG3(("dmDumpAllMainExp: empty discoveringExpanderList\n")); 6368 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6369 return; 6370 } 6371 else 6372 { 6373 tddmSingleThreadedLeave(dmRoot, DM_EXPANDER_LOCK); 6374 } 6375 6376 ExpanderList = dmAllShared->mainExpanderList.flink; 6377 while (ExpanderList != &(dmAllShared->mainExpanderList)) 6378 { 6379 tempExpander = DMLIST_OBJECT_BASE(dmExpander_t, linkNode, ExpanderList); 6380 if (tempExpander == agNULL) 6381 { 6382 DM_DBG1(("dmDumpAllMainExp: tempExpander is NULL!!!\n")); 6383 return; 6384 } 6385 DM_DBG3(("dmDumpAllMainExp: expander id %d\n", tempExpander->id)); 6386 DM_DBG3(("dmDumpAllMainExp: exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6387 DM_DBG3(("dmDumpAllMainExp: exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6388 if ((tempExpander->dmDevice->dmPortContext == onePortContext) 6389 ) 6390 { 6391 DM_DBG3(("dmDumpAllMainExp: found expander id %d\n", tempExpander->id)); 6392 DM_DBG3(("dmDumpAllMainExp: found exp addrHi 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressHi)); 6393 DM_DBG3(("dmDumpAllMainExp: found exp addrLo 0x%08x\n", tempExpander->dmDevice->SASAddressID.sasAddressLo)); 6394 } 6395 ExpanderList = ExpanderList->flink; 6396 } 6397 return; 6398 } 6399 6400 6401 osGLOBAL void 6402 dmDumpAllMainDevice( 6403 dmRoot_t *dmRoot, 6404 dmIntPortContext_t *onePortContext 6405 ) 6406 { 6407 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6408 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6409 dmDeviceData_t *oneDeviceData = agNULL; 6410 dmList_t *DeviceListList; 6411 bit32 total = 0, port_total = 0; 6412 6413 DM_DBG3(("dmDumpAllMainDevice: start\n")); 6414 6415 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6416 if (DMLIST_EMPTY(&(dmAllShared->MainDeviceList))) 6417 { 6418 DM_DBG3(("dmDumpAllMainDevice: empty discoveringExpanderList\n")); 6419 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6420 return; 6421 } 6422 else 6423 { 6424 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6425 } 6426 6427 DeviceListList = dmAllShared->MainDeviceList.flink; 6428 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6429 { 6430 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6431 if (oneDeviceData == agNULL) 6432 { 6433 DM_DBG3(("dmDumpAllMainDevice: oneDeviceData is NULL!!!\n")); 6434 return; 6435 } 6436 DM_DBG3(("dmDumpAllMainDevice: oneDeviceData id %d\n", oneDeviceData->id)); 6437 DM_DBG3(("dmDumpAllMainDevice: addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6438 DM_DBG3(("dmDumpAllMainDevice: addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6439 total++; 6440 if ((oneDeviceData->dmPortContext == onePortContext) 6441 ) 6442 { 6443 DM_DBG3(("dmDumpAllMainDevice: found oneDeviceData id %d\n", oneDeviceData->id)); 6444 DM_DBG3(("dmDumpAllMainDevice: found addrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6445 DM_DBG3(("dmDumpAllMainDevice: found addrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6446 port_total++; 6447 } 6448 DeviceListList = DeviceListList->flink; 6449 } 6450 DM_DBG3(("dmDumpAllMainDevice: total %d port_totaol %d\n", total, port_total)); 6451 6452 return; 6453 } 6454 6455 6456 6457 osGLOBAL dmDeviceData_t * 6458 dmAddSASToSharedcontext( 6459 dmRoot_t *dmRoot, 6460 dmIntPortContext_t *onePortContext, 6461 dmSASSubID_t *dmSASSubID, 6462 dmDeviceData_t *oneExpDeviceData, 6463 bit8 phyID 6464 ) 6465 { 6466 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6467 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6468 dmDeviceData_t *oneDeviceData = agNULL; 6469 dmList_t *DeviceListList; 6470 bit32 new_device = agTRUE; 6471 6472 6473 DM_DBG3(("dmAddSASToSharedcontext: start\n")); 6474 DM_DBG3(("dmAddSASToSharedcontext: oneportContext ID %d\n", onePortContext->id)); 6475 6476 if (oneExpDeviceData != agNULL) 6477 { 6478 DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6479 oneExpDeviceData->SASAddressID.sasAddressHi, oneExpDeviceData->SASAddressID.sasAddressLo)); 6480 } 6481 else 6482 { 6483 DM_DBG3(("dmAddSASToSharedcontext: oneExpDeviceData is NULL\n")); 6484 } 6485 /* find a device's existence */ 6486 DeviceListList = dmAllShared->MainDeviceList.flink; 6487 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6488 { 6489 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6490 if (oneDeviceData == agNULL) 6491 { 6492 DM_DBG1(("dmAddSASToSharedcontext: oneDeviceData is NULL!!!\n")); 6493 return agNULL; 6494 } 6495 if ((oneDeviceData->SASAddressID.sasAddressHi == dmSASSubID->sasAddressHi) && 6496 (oneDeviceData->SASAddressID.sasAddressLo == dmSASSubID->sasAddressLo) && 6497 (oneDeviceData->dmPortContext == onePortContext) 6498 ) 6499 { 6500 DM_DBG3(("dmAddSASToSharedcontext: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6501 new_device = agFALSE; 6502 break; 6503 } 6504 DeviceListList = DeviceListList->flink; 6505 } 6506 6507 /* new device */ 6508 if (new_device == agTRUE) 6509 { 6510 DM_DBG3(("dmAddSASToSharedcontext: new device\n")); 6511 DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6512 dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6513 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6514 if (!DMLIST_NOT_EMPTY(&(dmAllShared->FreeDeviceList))) 6515 { 6516 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6517 DM_DBG1(("dmAddSASToSharedcontext: empty DeviceData FreeLink\n")); 6518 dmDumpAllMainDevice(dmRoot, onePortContext); 6519 return agNULL; 6520 } 6521 6522 DMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(dmAllShared->FreeDeviceList)); 6523 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6524 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, FreeLink, DeviceListList); 6525 6526 if (oneDeviceData != agNULL) 6527 { 6528 DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p pid %d did %d\n", oneDeviceData, onePortContext->id, oneDeviceData->id)); 6529 6530 onePortContext->Count++; 6531 oneDeviceData->dmRoot = dmRoot; 6532 /* saving sas address */ 6533 oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6534 oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6535 oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6536 oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6537 oneDeviceData->dmPortContext = onePortContext; 6538 /* handles both SAS target and STP-target, SATA-device */ 6539 if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6540 { 6541 oneDeviceData->DeviceType = DM_SAS_DEVICE; 6542 } 6543 else 6544 { 6545 oneDeviceData->DeviceType = DM_SATA_DEVICE; 6546 } 6547 6548 if (oneExpDeviceData != agNULL) 6549 { 6550 oneDeviceData->ExpDevice = oneExpDeviceData; 6551 } 6552 6553 /* set phyID only when it has initial value of 0xFF */ 6554 if (oneDeviceData->phyID == 0xFF) 6555 { 6556 oneDeviceData->phyID = phyID; 6557 } 6558 /* incremental discovery */ 6559 /* add device to incremental-related link. Report using this link 6560 when incremental discovery is done */ 6561 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6562 { 6563 DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6564 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6565 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6566 oneDeviceData->valid = agTRUE; 6567 } 6568 else 6569 { 6570 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6571 { 6572 DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6573 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6574 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6575 oneDeviceData->valid2 = agTRUE; 6576 } 6577 else 6578 { 6579 DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6580 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6581 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6582 oneDeviceData->valid = agTRUE; 6583 } 6584 } 6585 /* add the devicedata to the portcontext */ 6586 tddmSingleThreadedEnter(dmRoot, DM_DEVICE_LOCK); 6587 DMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(dmAllShared->MainDeviceList)); 6588 tddmSingleThreadedLeave(dmRoot, DM_DEVICE_LOCK); 6589 DM_DBG3(("dmAddSASToSharedcontext: one case pid %d did %d \n", onePortContext->id, oneDeviceData->id)); 6590 DM_DBG3(("dmAddSASToSharedcontext: new case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6591 } 6592 } 6593 else /* old device */ 6594 { 6595 DM_DBG3(("dmAddSASToSharedcontext: old device\n")); 6596 DM_DBG3(("dmAddSASToSharedcontext: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 6597 DM_DBG3(("dmAddSASToSharedcontext: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", 6598 dmSASSubID->sasAddressHi, dmSASSubID->sasAddressLo)); 6599 6600 oneDeviceData->dmRoot = dmRoot; 6601 /* saving sas address */ 6602 oneDeviceData->SASAddressID.sasAddressLo = dmSASSubID->sasAddressLo; 6603 oneDeviceData->SASAddressID.sasAddressHi = dmSASSubID->sasAddressHi; 6604 oneDeviceData->initiator_ssp_stp_smp = dmSASSubID->initiator_ssp_stp_smp; 6605 oneDeviceData->target_ssp_stp_smp = dmSASSubID->target_ssp_stp_smp; 6606 oneDeviceData->dmPortContext = onePortContext; 6607 /* handles both SAS target and STP-target, SATA-device */ 6608 if (!DEVICE_IS_SATA_DEVICE(oneDeviceData) && !DEVICE_IS_STP_TARGET(oneDeviceData)) 6609 { 6610 oneDeviceData->DeviceType = DM_SAS_DEVICE; 6611 } 6612 else 6613 { 6614 oneDeviceData->DeviceType = DM_SATA_DEVICE; 6615 } 6616 6617 if (oneExpDeviceData != agNULL) 6618 { 6619 oneDeviceData->ExpDevice = oneExpDeviceData; 6620 } 6621 6622 /* set phyID only when it has initial value of 0xFF */ 6623 if (oneDeviceData->phyID == 0xFF) 6624 { 6625 oneDeviceData->phyID = phyID; 6626 } 6627 6628 if (onePortContext->DiscoveryState == DM_DSTATE_NOT_STARTED) 6629 { 6630 DM_DBG3(("dmAddSASToSharedcontext: DM_DSTATE_NOT_STARTED\n")); 6631 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6632 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6633 oneDeviceData->valid = agTRUE; 6634 } 6635 else 6636 { 6637 if (onePortContext->discovery.type == DM_DISCOVERY_OPTION_INCREMENTAL_START) 6638 { 6639 DM_DBG3(("dmAddSASToSharedcontext: incremental discovery\n")); 6640 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6641 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6642 oneDeviceData->valid2 = agTRUE; 6643 } 6644 else 6645 { 6646 DM_DBG3(("dmAddSASToSharedcontext: full discovery\n")); 6647 DM_DBG3(("dmAddSASToSharedcontext: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 6648 DM_DBG3(("dmAddSASToSharedcontext: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 6649 oneDeviceData->valid = agTRUE; 6650 } 6651 } 6652 DM_DBG3(("dmAddSASToSharedcontext: old case pid %d did %d phyID %d\n", onePortContext->id, oneDeviceData->id, oneDeviceData->phyID)); 6653 6654 } 6655 return oneDeviceData; 6656 } 6657 6658 /* no checking of valid and valid2 */ 6659 osGLOBAL dmDeviceData_t * 6660 dmDeviceFind( 6661 dmRoot_t *dmRoot, 6662 dmIntPortContext_t *onePortContext, 6663 bit32 sasAddrHi, 6664 bit32 sasAddrLo 6665 ) 6666 { 6667 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6668 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6669 dmDeviceData_t *oneDeviceData = agNULL; 6670 dmList_t *DeviceListList; 6671 bit32 found = agFALSE; 6672 6673 DM_DBG3(("dmDeviceFind: start\n")); 6674 /* find a device's existence */ 6675 DeviceListList = dmAllShared->MainDeviceList.flink; 6676 6677 while (DeviceListList != &(dmAllShared->MainDeviceList)) 6678 { 6679 oneDeviceData = DMLIST_OBJECT_BASE(dmDeviceData_t, MainLink, DeviceListList); 6680 if (oneDeviceData == agNULL) 6681 { 6682 DM_DBG1(("dmDeviceFind: oneDeviceData is NULL!!!\n")); 6683 return agNULL; 6684 } 6685 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 6686 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 6687 // (oneDeviceData->valid == agTRUE) && 6688 (oneDeviceData->dmPortContext == onePortContext) 6689 ) 6690 { 6691 DM_DBG3(("dmDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6692 DM_DBG3(("dmDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 6693 DM_DBG3(("dmDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 6694 found = agTRUE; 6695 break; 6696 } 6697 DeviceListList = DeviceListList->flink; 6698 } 6699 6700 if (found == agFALSE) 6701 { 6702 DM_DBG3(("dmDeviceFind: end returning NULL\n")); 6703 return agNULL; 6704 } 6705 else 6706 { 6707 DM_DBG3(("dmDeviceFind: end returning NOT NULL\n")); 6708 return oneDeviceData; 6709 } 6710 6711 } 6712 6713 6714 osGLOBAL void 6715 dmBCTimer( 6716 dmRoot_t *dmRoot, 6717 dmIntPortContext_t *onePortContext 6718 ) 6719 { 6720 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6721 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6722 dmDiscovery_t *discovery; 6723 6724 DM_DBG3(("dmBCTimer: start\n")); 6725 6726 discovery = &(onePortContext->discovery); 6727 6728 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6729 if (discovery->BCTimer.timerRunning == agTRUE) 6730 { 6731 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6732 dmKillTimer( 6733 dmRoot, 6734 &discovery->BCTimer 6735 ); 6736 } 6737 else 6738 { 6739 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6740 } 6741 6742 if (onePortContext->valid == agTRUE) 6743 { 6744 dmSetTimerRequest( 6745 dmRoot, 6746 &discovery->BCTimer, 6747 BC_TIMER_VALUE/dmAllShared->usecsPerTick, 6748 dmBCTimerCB, 6749 onePortContext, 6750 agNULL, 6751 agNULL 6752 ); 6753 6754 dmAddTimer( 6755 dmRoot, 6756 &dmAllShared->timerlist, 6757 &discovery->BCTimer 6758 ); 6759 6760 } 6761 6762 6763 return; 6764 } 6765 6766 6767 osGLOBAL void 6768 dmBCTimerCB( 6769 dmRoot_t * dmRoot, 6770 void * timerData1, 6771 void * timerData2, 6772 void * timerData3 6773 ) 6774 { 6775 dmIntPortContext_t *onePortContext; 6776 dmDiscovery_t *discovery; 6777 6778 DM_DBG3(("dmBCTimerCB: start\n")); 6779 6780 onePortContext = (dmIntPortContext_t *)timerData1; 6781 discovery = &(onePortContext->discovery); 6782 6783 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6784 if (discovery->BCTimer.timerRunning == agTRUE) 6785 { 6786 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6787 dmKillTimer( 6788 dmRoot, 6789 &discovery->BCTimer 6790 ); 6791 } 6792 else 6793 { 6794 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6795 } 6796 6797 discovery->ResetTriggerred = agFALSE; 6798 6799 if (onePortContext->valid == agTRUE) 6800 { 6801 dmDiscover(dmRoot, 6802 onePortContext->dmPortContext, 6803 DM_DISCOVERY_OPTION_INCREMENTAL_START 6804 ); 6805 } 6806 return; 6807 } 6808 6809 /* discovery related SMP timers */ 6810 osGLOBAL void 6811 dmDiscoverySMPTimer(dmRoot_t *dmRoot, 6812 dmIntPortContext_t *onePortContext, 6813 bit32 functionCode, 6814 dmSMPRequestBody_t *dmSMPRequestBody 6815 ) 6816 { 6817 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6818 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6819 dmDiscovery_t *discovery; 6820 6821 DM_DBG3(("dmDiscoverySMPTimer: start\n")); 6822 DM_DBG3(("dmDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode)); 6823 6824 /* start the SMP timer which works as SMP application timer */ 6825 discovery = &(onePortContext->discovery); 6826 6827 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6828 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6829 { 6830 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6831 dmKillTimer( 6832 dmRoot, 6833 &discovery->DiscoverySMPTimer 6834 ); 6835 } 6836 else 6837 { 6838 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6839 } 6840 6841 6842 dmSetTimerRequest( 6843 dmRoot, 6844 &discovery->DiscoverySMPTimer, 6845 SMP_TIMER_VALUE/dmAllShared->usecsPerTick, 6846 dmDiscoverySMPTimerCB, 6847 onePortContext, 6848 dmSMPRequestBody, 6849 agNULL 6850 ); 6851 6852 dmAddTimer ( 6853 dmRoot, 6854 &dmAllShared->timerlist, 6855 &discovery->DiscoverySMPTimer 6856 ); 6857 6858 return; 6859 } 6860 6861 6862 osGLOBAL void 6863 dmDiscoverySMPTimerCB( 6864 dmRoot_t * dmRoot, 6865 void * timerData1, 6866 void * timerData2, 6867 void * timerData3 6868 ) 6869 { 6870 agsaRoot_t *agRoot; 6871 dmIntPortContext_t *onePortContext; 6872 bit8 SMPFunction; 6873 #ifndef DIRECT_SMP 6874 dmSMPFrameHeader_t *dmSMPFrameHeader; 6875 bit8 smpHeader[4]; 6876 #endif 6877 dmSMPRequestBody_t *dmSMPRequestBody; 6878 dmDiscovery_t *discovery; 6879 dmDeviceData_t *oneDeviceData; 6880 agsaIORequest_t *agAbortIORequest = agNULL; 6881 agsaIORequest_t *agToBeAbortIORequest = agNULL; 6882 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6883 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 6884 dmExpander_t *oneExpander = agNULL; 6885 dmSMPRequestBody_t *dmAbortSMPRequestBody = agNULL; 6886 dmList_t *SMPList; 6887 6888 DM_DBG1(("dmDiscoverySMPTimerCB: start!!!\n")); 6889 6890 onePortContext = (dmIntPortContext_t *)timerData1; 6891 dmSMPRequestBody = (dmSMPRequestBody_t *)timerData2; 6892 6893 discovery = &(onePortContext->discovery); 6894 oneDeviceData = dmSMPRequestBody->dmDevice; 6895 agToBeAbortIORequest = &(dmSMPRequestBody->agIORequest); 6896 agRoot = dmAllShared->agRoot; 6897 6898 #ifdef DIRECT_SMP 6899 SMPFunction = dmSMPRequestBody->smpPayload[1]; 6900 #else 6901 saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpHeader, 4); 6902 dmSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 6903 SMPFunction = dmSMPFrameHeader->smpFunction; 6904 #endif 6905 6906 DM_DBG3(("dmDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction)); 6907 6908 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 6909 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 6910 { 6911 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6912 dmKillTimer( 6913 dmRoot, 6914 &discovery->DiscoverySMPTimer 6915 ); 6916 } 6917 else 6918 { 6919 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 6920 } 6921 6922 //for debugging 6923 // saGetPendingPICI(agRoot); 6924 6925 switch (SMPFunction) 6926 { 6927 case SMP_REPORT_GENERAL: /* fall through */ 6928 case SMP_DISCOVER: /* fall through */ 6929 case SMP_CONFIGURE_ROUTING_INFORMATION: /* fall through */ 6930 DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function 0x%x !!!\n", SMPFunction)); 6931 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6932 return; /* no more things to do */ 6933 case SMP_REPORT_PHY_SATA: 6934 DM_DBG1(("dmDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA !!!\n")); 6935 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 6936 break; 6937 default: 6938 /* do nothing */ 6939 DM_DBG1(("dmDiscoverySMPTimerCB: Error, not allowed case!!!\n")); 6940 break; 6941 } 6942 6943 if (oneDeviceData->registered == agTRUE && (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) ) 6944 { 6945 /* call to saSMPAbort(one) */ 6946 /* get an smp REQUEST from the free list */ 6947 tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 6948 if (DMLIST_EMPTY(&(dmAllShared->freeSMPList))) 6949 { 6950 DM_DBG1(("dmDiscoverySMPTimerCB: no free SMP, can't abort SMP!!!\n")); 6951 tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6952 return; 6953 } 6954 else 6955 { 6956 DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList)); 6957 tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 6958 dmAbortSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList); 6959 if (dmAbortSMPRequestBody == agNULL) 6960 { 6961 DM_DBG1(("dmDiscoverySMPTimerCB: dmAbortSMPRequestBody is NULL!!!\n")); 6962 return; 6963 } 6964 DM_DBG5(("dmDiscoverySMPTimerCB: SMP id %d\n", dmAbortSMPRequestBody->id)); 6965 } 6966 6967 dmAbortSMPRequestBody->dmRoot = dmRoot; 6968 6969 agAbortIORequest = &(dmAbortSMPRequestBody->agIORequest); 6970 agAbortIORequest->osData = (void *) dmAbortSMPRequestBody; 6971 agAbortIORequest->sdkData = agNULL; /* SALL takes care of this */ 6972 6973 oneExpander = oneDeviceData->dmExpander; 6974 6975 DM_DBG1(("dmDiscoverySMPTimerCB: calling saSMPAbort!!!\n")); 6976 saSMPAbort(agRoot, 6977 agAbortIORequest, 6978 0, 6979 oneExpander->agDevHandle, 6980 0, /* abort one */ 6981 agToBeAbortIORequest, 6982 dmSMPAbortCB 6983 ); 6984 } 6985 return; 6986 } 6987 6988 6989 6990 6991 osGLOBAL void 6992 dmSMPBusyTimer(dmRoot_t *dmRoot, 6993 dmIntPortContext_t *onePortContext, 6994 dmDeviceData_t *oneDeviceData, 6995 dmSMPRequestBody_t *dmSMPRequestBody 6996 ) 6997 { 6998 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 6999 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7000 dmDiscovery_t *discovery; 7001 7002 DM_DBG3(("dmSMPBusyTimer: start\n")); 7003 DM_DBG3(("dmSMPBusyTimer: pid %d\n", onePortContext->id)); 7004 7005 discovery = &(onePortContext->discovery); 7006 7007 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7008 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7009 { 7010 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7011 dmKillTimer( 7012 dmRoot, 7013 &discovery->SMPBusyTimer 7014 ); 7015 } 7016 else 7017 { 7018 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7019 } 7020 7021 dmSetTimerRequest( 7022 dmRoot, 7023 &discovery->SMPBusyTimer, 7024 SMP_BUSY_TIMER_VALUE/dmAllShared->usecsPerTick, 7025 dmSMPBusyTimerCB, 7026 onePortContext, 7027 oneDeviceData, 7028 dmSMPRequestBody 7029 ); 7030 7031 dmAddTimer ( 7032 dmRoot, 7033 &dmAllShared->timerlist, 7034 &discovery->SMPBusyTimer 7035 ); 7036 7037 7038 return; 7039 } 7040 7041 osGLOBAL void 7042 dmSMPBusyTimerCB( 7043 dmRoot_t * dmRoot, 7044 void * timerData1, 7045 void * timerData2, 7046 void * timerData3 7047 ) 7048 { 7049 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7050 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7051 agsaRoot_t *agRoot; 7052 dmIntPortContext_t *onePortContext; 7053 dmDeviceData_t *oneDeviceData; 7054 dmSMPRequestBody_t *dmSMPRequestBody; 7055 agsaSASRequestBody_t *agSASRequestBody; 7056 agsaIORequest_t *agIORequest; 7057 agsaDevHandle_t *agDevHandle; 7058 dmDiscovery_t *discovery; 7059 bit32 status = AGSA_RC_FAILURE; 7060 dmExpander_t *oneExpander = agNULL; 7061 7062 7063 DM_DBG3(("dmSMPBusyTimerCB: start\n")); 7064 7065 onePortContext = (dmIntPortContext_t *)timerData1; 7066 oneDeviceData = (dmDeviceData_t *)timerData2; 7067 dmSMPRequestBody = (dmSMPRequestBody_t *)timerData3; 7068 agRoot = dmAllShared->agRoot; 7069 agIORequest = &(dmSMPRequestBody->agIORequest); 7070 oneExpander = oneDeviceData->dmExpander; 7071 agDevHandle = oneExpander->agDevHandle; 7072 agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 7073 discovery = &(onePortContext->discovery); 7074 7075 discovery->SMPRetries++; 7076 7077 if (discovery->SMPRetries < SMP_BUSY_RETRIES) 7078 { 7079 status = saSMPStart( 7080 agRoot, 7081 agIORequest, 7082 0, 7083 agDevHandle, 7084 AGSA_SMP_INIT_REQ, 7085 agSASRequestBody, 7086 &dmsaSMPCompleted 7087 ); 7088 } 7089 7090 if (status == AGSA_RC_SUCCESS) 7091 { 7092 discovery->SMPRetries = 0; 7093 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7094 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7095 { 7096 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7097 dmKillTimer( 7098 dmRoot, 7099 &discovery->SMPBusyTimer 7100 ); 7101 } 7102 else 7103 { 7104 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7105 } 7106 } 7107 else if (status == AGSA_RC_FAILURE) 7108 { 7109 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7110 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7111 { 7112 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7113 dmKillTimer( 7114 dmRoot, 7115 &discovery->SMPBusyTimer 7116 ); 7117 } 7118 else 7119 { 7120 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7121 } 7122 7123 discovery->SMPRetries = 0; 7124 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7125 } 7126 else /* AGSA_RC_BUSY */ 7127 { 7128 if (discovery->SMPRetries >= SMP_BUSY_RETRIES) 7129 { 7130 /* done with retris; give up */ 7131 DM_DBG3(("dmSMPBusyTimerCB: retries are over\n")); 7132 7133 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7134 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7135 { 7136 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7137 dmKillTimer( 7138 dmRoot, 7139 &discovery->SMPBusyTimer 7140 ); 7141 } 7142 else 7143 { 7144 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7145 } 7146 7147 discovery->SMPRetries = 0; 7148 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7149 7150 } 7151 else 7152 { 7153 /* keep retrying */ 7154 dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 7155 } 7156 } 7157 7158 return; 7159 } 7160 7161 7162 /* expander configuring timer */ 7163 osGLOBAL void 7164 dmDiscoveryConfiguringTimer(dmRoot_t *dmRoot, 7165 dmIntPortContext_t *onePortContext, 7166 dmDeviceData_t *oneDeviceData 7167 ) 7168 { 7169 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7170 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7171 dmDiscovery_t *discovery; 7172 7173 DM_DBG3(("dmDiscoveryConfiguringTimer: start\n")); 7174 DM_DBG3(("dmDiscoveryConfiguringTimer: pid %d\n", onePortContext->id)); 7175 7176 discovery = &(onePortContext->discovery); 7177 7178 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7179 if (discovery->discoveryTimer.timerRunning == agTRUE) 7180 { 7181 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7182 dmKillTimer( 7183 dmRoot, 7184 &discovery->discoveryTimer 7185 ); 7186 } 7187 else 7188 { 7189 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7190 } 7191 7192 DM_DBG3(("dmDiscoveryConfiguringTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7193 DM_DBG3(("dmDiscoveryConfiguringTimer: Timervalue %d\n", DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick)); 7194 7195 dmSetTimerRequest( 7196 dmRoot, 7197 &discovery->discoveryTimer, 7198 DISCOVERY_CONFIGURING_TIMER_VALUE/dmAllShared->usecsPerTick, 7199 dmDiscoveryConfiguringTimerCB, 7200 onePortContext, 7201 oneDeviceData, 7202 agNULL 7203 ); 7204 7205 dmAddTimer ( 7206 dmRoot, 7207 &dmAllShared->timerlist, 7208 &discovery->discoveryTimer 7209 ); 7210 7211 7212 return; 7213 } 7214 7215 7216 osGLOBAL void 7217 dmDiscoveryConfiguringTimerCB( 7218 dmRoot_t * dmRoot, 7219 void * timerData1, 7220 void * timerData2, 7221 void * timerData3 7222 ) 7223 { 7224 dmIntPortContext_t *onePortContext = agNULL; 7225 dmDiscovery_t *discovery = agNULL; 7226 dmDeviceData_t *oneDeviceData = agNULL; 7227 7228 onePortContext = (dmIntPortContext_t *)timerData1; 7229 oneDeviceData = (dmDeviceData_t *)timerData2; 7230 discovery = &(onePortContext->discovery); 7231 7232 DM_DBG3(("dmDiscoveryConfiguringTimerCB: start\n")); 7233 7234 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7235 if (discovery->discoveryTimer.timerRunning == agTRUE) 7236 { 7237 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7238 dmKillTimer( 7239 dmRoot, 7240 &discovery->discoveryTimer 7241 ); 7242 } 7243 else 7244 { 7245 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7246 } 7247 7248 if (oneDeviceData->valid == agTRUE || oneDeviceData->valid2 == agTRUE) 7249 { 7250 dmReportGeneralSend(dmRoot, oneDeviceData); 7251 } 7252 return; 7253 } 7254 7255 osGLOBAL void 7256 dmConfigureRouteTimer(dmRoot_t *dmRoot, 7257 dmIntPortContext_t *onePortContext, 7258 dmExpander_t *oneExpander, 7259 smpRespDiscover_t *pdmSMPDiscoverResp, 7260 smpRespDiscover2_t *pdmSMPDiscover2Resp 7261 ) 7262 { 7263 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7264 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7265 dmDiscovery_t *discovery; 7266 7267 DM_DBG3(("dmConfigureRouteTimer: start\n")); 7268 7269 DM_DBG3(("dmConfigureRouteTimer: pid %d\n", onePortContext->id)); 7270 7271 discovery = &(onePortContext->discovery); 7272 7273 DM_DBG3(("dmConfigureRouteTimer: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7274 7275 DM_DBG3(("dmConfigureRouteTimer: discovery %p \n", discovery)); 7276 7277 DM_DBG3(("dmConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7278 7279 DM_DBG3(("dmConfigureRouteTimer: discovery->status %d\n", discovery->status)); 7280 7281 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7282 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7283 { 7284 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7285 dmKillTimer( 7286 dmRoot, 7287 &discovery->configureRouteTimer 7288 ); 7289 } 7290 else 7291 { 7292 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7293 } 7294 7295 DM_DBG3(("dmConfigureRouteTimer: UsecsPerTick %d\n", dmAllShared->usecsPerTick)); 7296 DM_DBG3(("dmConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick)); 7297 7298 if (oneExpander->SAS2 == 0) 7299 { 7300 /* SAS 1.1 */ 7301 dmSetTimerRequest( 7302 dmRoot, 7303 &discovery->configureRouteTimer, 7304 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7305 dmConfigureRouteTimerCB, 7306 (void *)onePortContext, 7307 (void *)oneExpander, 7308 (void *)pdmSMPDiscoverResp 7309 ); 7310 } 7311 else 7312 { 7313 /* SAS 2 */ 7314 dmSetTimerRequest( 7315 dmRoot, 7316 &discovery->configureRouteTimer, 7317 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7318 dmConfigureRouteTimerCB, 7319 (void *)onePortContext, 7320 (void *)oneExpander, 7321 (void *)pdmSMPDiscover2Resp 7322 ); 7323 } 7324 dmAddTimer ( 7325 dmRoot, 7326 &dmAllShared->timerlist, 7327 &discovery->configureRouteTimer 7328 ); 7329 7330 return; 7331 } 7332 7333 7334 osGLOBAL void 7335 dmConfigureRouteTimerCB( 7336 dmRoot_t * dmRoot, 7337 void * timerData1, 7338 void * timerData2, 7339 void * timerData3 7340 ) 7341 { 7342 dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 7343 dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 7344 dmIntPortContext_t *onePortContext; 7345 dmExpander_t *oneExpander; 7346 smpRespDiscover_t *pdmSMPDiscoverResp = agNULL; 7347 smpRespDiscover2_t *pdmSMPDiscover2Resp = agNULL; 7348 dmDiscovery_t *discovery; 7349 7350 7351 DM_DBG3(("dmConfigureRouteTimerCB: start\n")); 7352 7353 onePortContext = (dmIntPortContext_t *)timerData1; 7354 oneExpander = (dmExpander_t *)timerData2; 7355 if (oneExpander->SAS2 == 0) 7356 { 7357 pdmSMPDiscoverResp = (smpRespDiscover_t *)timerData3; 7358 } 7359 else 7360 { 7361 pdmSMPDiscover2Resp = (smpRespDiscover2_t *)timerData3; 7362 } 7363 discovery = &(onePortContext->discovery); 7364 7365 DM_DBG3(("dmConfigureRouteTimerCB: onePortContext %p oneExpander %p pdmSMPDiscoverResp %p\n", onePortContext, oneExpander, pdmSMPDiscoverResp)); 7366 7367 DM_DBG3(("dmConfigureRouteTimerCB: discovery %p\n", discovery)); 7368 7369 DM_DBG3(("dmConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7370 7371 DM_DBG3(("dmConfigureRouteTimerCB: discovery.status %d\n", discovery->status)); 7372 7373 discovery->configureRouteRetries++; 7374 if (discovery->configureRouteRetries >= dmAllShared->MaxRetryDiscovery) 7375 { 7376 DM_DBG3(("dmConfigureRouteTimerCB: retries are over\n")); 7377 7378 tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 7379 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7380 { 7381 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7382 dmKillTimer( 7383 dmRoot, 7384 &discovery->configureRouteTimer 7385 ); 7386 } 7387 else 7388 { 7389 tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 7390 } 7391 7392 discovery->configureRouteRetries = 0; 7393 /* failed the discovery */ 7394 dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 7395 7396 return; 7397 } 7398 7399 7400 if (oneExpander->SAS2 == 0) 7401 { 7402 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7403 { 7404 DM_DBG3(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscoverExpanderPhy\n")); 7405 dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 7406 discovery->configureRouteRetries = 0; 7407 7408 dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp); 7409 } 7410 else 7411 { 7412 DM_DBG3(("dmConfigureRouteTimerCB: setting timer again\n")); 7413 /* set the timer again */ 7414 dmSetTimerRequest( 7415 dmRoot, 7416 &discovery->configureRouteTimer, 7417 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7418 dmConfigureRouteTimerCB, 7419 (void *)onePortContext, 7420 (void *)oneExpander, 7421 (void *)pdmSMPDiscoverResp 7422 ); 7423 7424 dmAddTimer ( 7425 dmRoot, 7426 &dmAllShared->timerlist, 7427 &discovery->configureRouteTimer 7428 ); 7429 } 7430 } /* SAS 1.1 */ 7431 else 7432 { 7433 /* SAS 2 */ 7434 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7435 { 7436 DM_DBG2(("dmConfigureRouteTimerCB: proceed by calling dmDownStreamDiscover2ExpanderPhy\n")); 7437 dmhexdump("dmConfigureRouteTimerCB", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 7438 7439 dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp); 7440 } 7441 else 7442 { 7443 DM_DBG2(("dmConfigureRouteTimerCB: setting timer again\n")); 7444 /* set the timer again */ 7445 dmSetTimerRequest( 7446 dmRoot, 7447 &discovery->configureRouteTimer, 7448 CONFIGURE_ROUTE_TIMER_VALUE/dmAllShared->usecsPerTick, 7449 dmConfigureRouteTimerCB, 7450 (void *)onePortContext, 7451 (void *)oneExpander, 7452 (void *)pdmSMPDiscover2Resp 7453 ); 7454 7455 dmAddTimer ( 7456 dmRoot, 7457 &dmAllShared->timerlist, 7458 &discovery->configureRouteTimer 7459 ); 7460 } 7461 } 7462 7463 return; 7464 } 7465 #endif /* FDS_ DM */ 7466 7467