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