1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ********************************************************************************/ 22 /*******************************************************************************/ 23 /** \file 24 * 25 * This file contains initiator discover related functions 26 * 27 */ 28 #include <sys/cdefs.h> 29 #include <dev/pms/config.h> 30 31 #include <dev/pms/freebsd/driver/common/osenv.h> 32 #include <dev/pms/freebsd/driver/common/ostypes.h> 33 #include <dev/pms/freebsd/driver/common/osdebug.h> 34 35 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 36 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 37 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 38 39 #include <dev/pms/RefTisa/tisa/api/titypes.h> 40 #include <dev/pms/RefTisa/tisa/api/ostiapi.h> 41 #include <dev/pms/RefTisa/tisa/api/tiapi.h> 42 #include <dev/pms/RefTisa/tisa/api/tiglobal.h> 43 44 #ifdef FDS_SM 45 #include <dev/pms/RefTisa/sat/api/sm.h> 46 #include <dev/pms/RefTisa/sat/api/smapi.h> 47 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 48 #endif 49 50 #ifdef FDS_DM 51 #include <dev/pms/RefTisa/discovery/api/dm.h> 52 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 53 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 54 #endif 55 56 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h> 57 #include <dev/pms/freebsd/driver/common/osstring.h> 58 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h> 59 60 #ifdef INITIATOR_DRIVER 61 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h> 62 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h> 63 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h> 64 #endif 65 66 #ifdef TARGET_DRIVER 67 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h> 68 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h> 69 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h> 70 #endif 71 72 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 73 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h> 74 75 /***************************************************************************** 76 *! \brief tiINIDiscoverTargets 77 * 78 * Purpose: This function is called to send a transport dependent discovery 79 * request. An implicit login will be started following the 80 * completion of discovery. 81 * 82 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 83 * instance. 84 * \param portalContext: Pointer to the portal context instance. 85 * \param option: This is a bit field option on how the session is to be 86 * created 87 * \return: 88 * tiSuccess Discovery initiated. 89 * tiBusy Discovery could not be initiated at this time. 90 * 91 * \note: 92 * 93 *****************************************************************************/ 94 osGLOBAL bit32 95 tiINIDiscoverTargets( 96 tiRoot_t *tiRoot, 97 tiPortalContext_t *portalContext, 98 bit32 option 99 ) 100 { 101 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 102 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 103 tdList_t *PortContextList; 104 tdsaPortContext_t *onePortContext = agNULL; 105 bit32 found = agFALSE; 106 107 #ifdef FDS_DM 108 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot); 109 dmPortContext_t *dmPortContext = agNULL; 110 #endif 111 /* 112 this function is called after LINK_UP by ossaHWCB() 113 Therefore, tdsaportcontext is ready at this point 114 */ 115 116 TI_DBG3(("tiINIDiscoverTargets: start\n")); 117 118 /* find a right tdsaPortContext using tiPortalContext 119 then, check the status of tdsaPortContext 120 then, if status is right, start the discovery 121 */ 122 123 TI_DBG6(("tiINIDiscoverTargets: portalContext %p\n", portalContext)); 124 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 125 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList))) 126 { 127 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 128 TI_DBG1(("tiINIDiscoverTargets: No tdsaPortContext\n")); 129 return tiError; 130 } 131 else 132 { 133 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 134 } 135 136 /* find a right portcontext */ 137 PortContextList = tdsaAllShared->MainPortContextList.flink; 138 if (PortContextList == agNULL) 139 { 140 TI_DBG1(("tiINIDiscoverTargets: PortContextList is NULL\n")); 141 return tiError; 142 } 143 while (PortContextList != &(tdsaAllShared->MainPortContextList)) 144 { 145 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList); 146 if (onePortContext == agNULL) 147 { 148 TI_DBG1(("tiINIDiscoverTargets: onePortContext is NULL, PortContextList = %p\n", PortContextList)); 149 return tiError; 150 } 151 if (onePortContext->tiPortalContext == portalContext && onePortContext->valid == agTRUE) 152 { 153 TI_DBG6(("tiINIDiscoverTargets: found; oneportContext ID %d\n", onePortContext->id)); 154 found = agTRUE; 155 break; 156 } 157 PortContextList = PortContextList->flink; 158 } 159 160 if (found == agFALSE) 161 { 162 TI_DBG1(("tiINIDiscoverTargets: No corresponding tdsaPortContext\n")); 163 return tiError; 164 } 165 166 TI_DBG2(("tiINIDiscoverTargets: pid %d\n", onePortContext->id)); 167 if (onePortContext->DiscoveryState == ITD_DSTATE_NOT_STARTED) 168 { 169 TI_DBG6(("tiINIDiscoverTargets: calling Discovery\n")); 170 /* start SAS discovery */ 171 #ifdef FDS_DM 172 if (onePortContext->UseDM == agTRUE) 173 { 174 TI_DBG1(("tiINIDiscoverTargets: calling dmDiscover, pid %d\n", onePortContext->id)); 175 onePortContext->DiscoveryState = ITD_DSTATE_STARTED; 176 dmPortContext = &(onePortContext->dmPortContext); 177 dmDiscover(dmRoot, dmPortContext, DM_DISCOVERY_OPTION_FULL_START); 178 } 179 else 180 { 181 /* complete discovery */ 182 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED; 183 ostiInitiatorEvent( 184 tiRoot, 185 portalContext, 186 agNULL, 187 tiIntrEventTypeDiscovery, 188 tiDiscOK, 189 agNULL 190 ); 191 192 return tiSuccess; 193 } 194 195 #else 196 197 #ifdef TD_DISCOVER 198 tdsaDiscover( 199 tiRoot, 200 onePortContext, 201 AG_SA_DISCOVERY_TYPE_SAS, 202 TDSA_DISCOVERY_OPTION_FULL_START 203 ); 204 #else 205 saDiscover(onePortContext->agRoot, onePortContext->agPortContext, AG_SA_DISCOVERY_TYPE_SAS, onePortContext->discoveryOptions); 206 207 208 209 #endif 210 #endif /* FDS_DM */ 211 } 212 else 213 { 214 TI_DBG1(("tiINIDiscoverTargets: Discovery has started or incorrect initialization; state %d pid 0x%x\n", 215 onePortContext->DiscoveryState, 216 onePortContext->id)); 217 return tiError; 218 } 219 220 return tiSuccess; 221 } 222 223 /***************************************************************************** 224 *! \brief tiINIGetDeviceHandles 225 * 226 * Purpose: This routine is called to to return the device handles for each 227 * device currently available. 228 * 229 * \param tiRoot: Pointer to driver Instance. 230 * \param tiPortalContext: Pointer to the portal context instance. 231 * \param agDev[]: Array to receive pointers to the device handles. 232 * \param maxDevs: Number of device handles which will fit in array pointed 233 * by agDev. 234 * \return: 235 * Number of device handle slots present (however, only maxDevs 236 * are copied into tiDev[]) which may be greater than the number of 237 * handles actually present. In short, returns the number of devices that 238 * were found. 239 * 240 * \note: 241 * 242 *****************************************************************************/ 243 osGLOBAL bit32 244 tiINIGetDeviceHandles( 245 tiRoot_t * tiRoot, 246 tiPortalContext_t * tiPortalContext, 247 tiDeviceHandle_t * tiDev[], 248 bit32 maxDevs 249 ) 250 { 251 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 252 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 253 tdList_t *PortContextList; 254 tdsaPortContext_t *onePortContext = agNULL; 255 tdsaDeviceData_t *oneDeviceData = agNULL; 256 tdList_t *DeviceListList; 257 bit32 i; 258 bit32 FoundDevices = 0; 259 bit32 DeviceIndex = 0; 260 bit32 found = agFALSE; 261 #ifdef TD_DEBUG_ENABLE 262 satDeviceData_t *pSatDevData; 263 #endif 264 #ifdef FDS_DM 265 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot); 266 #endif 267 268 TI_DBG2(("tiINIGetDeviceHandles: start\n")); 269 TI_DBG2(("tiINIGetDeviceHandles: tiPortalContext %p\n", tiPortalContext)); 270 271 272 if (maxDevs == 0) 273 { 274 TI_DBG1(("tiINIGetDeviceHandles: maxDevs is 0\n")); 275 TI_DBG1(("tiINIGetDeviceHandles: first, returning 0\n")); 276 /* nullify all device handles */ 277 for (i = 0 ; i < maxDevs ; i++) 278 { 279 tiDev[i] = agNULL; 280 } 281 return 0; 282 } 283 284 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 285 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList))) 286 { 287 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 288 TI_DBG1(("tiINIGetDeviceHandles: No available tdsaPortContext\n")); 289 TI_DBG1(("tiINIGetDeviceHandles: second, returning 0\n")); 290 /* nullify all device handles */ 291 for (i = 0 ; i < maxDevs ; i++) 292 { 293 tiDev[i] = agNULL; 294 } 295 return 0; 296 } 297 else 298 { 299 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 300 } 301 /* find a corresponding portcontext */ 302 PortContextList = tdsaAllShared->MainPortContextList.flink; 303 while (PortContextList != &(tdsaAllShared->MainPortContextList)) 304 { 305 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList); 306 if(onePortContext == agNULL) continue; 307 308 TI_DBG3(("tiINIGetDeviceHandles: oneportContext pid %d\n", onePortContext->id)); 309 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE) 310 { 311 TI_DBG3(("tiINIGetDeviceHandles: found; oneportContext pid %d\n", onePortContext->id)); 312 found = agTRUE; 313 break; 314 } 315 PortContextList = PortContextList->flink; 316 } 317 318 if (found == agFALSE) 319 { 320 TI_DBG1(("tiINIGetDeviceHandles: First, No corresponding tdsaPortContext\n")); 321 TI_DBG1(("tiINIGetDeviceHandles: third, returning 0\n")); 322 /* nullify all device handles */ 323 for (i = 0 ; i < maxDevs ; i++) 324 { 325 tiDev[i] = agNULL; 326 } 327 return 0; 328 } 329 330 if (onePortContext == agNULL) 331 { 332 TI_DBG1(("tiINIGetDeviceHandles: Second, No corressponding tdsaPortContext\n")); 333 TI_DBG1(("tiINIGetDeviceHandles: fourth, returning 0\n")); 334 /* nullify all device handles */ 335 for (i = 0 ; i < maxDevs ; i++) 336 { 337 tiDev[i] = agNULL; 338 } 339 return 0; 340 } 341 342 if (onePortContext->valid == agFALSE) 343 { 344 TI_DBG1(("tiINIGetDeviceHandles: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id)); 345 TI_DBG1(("tiINIGetDeviceHandles: fifth, returning 0\n")); 346 /* nullify all device handles */ 347 for (i = 0 ; i < maxDevs ; i++) 348 { 349 tiDev[i] = agNULL; 350 } 351 return 0; 352 } 353 354 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed) 355 { 356 TI_DBG1(("tiINIGetDeviceHandles: forth, discovery failed, pid %d\n", onePortContext->id)); 357 TI_DBG1(("tiINIGetDeviceHandles: sixth, returning 0\n")); 358 /* nullify all device handles */ 359 for (i = 0 ; i < maxDevs ; i++) 360 { 361 tiDev[i] = agNULL; 362 } 363 return 0; 364 } 365 366 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED) 367 { 368 TI_DBG1(("tiINIGetDeviceHandles: discovery not completed\n")); 369 TI_DBG1(("tiINIGetDeviceHandles: sixth, returning DISCOVERY_IN_PROGRESS, pid %d\n", onePortContext->id)); 370 onePortContext->discovery.forcedOK = agTRUE; 371 return DISCOVERY_IN_PROGRESS; 372 } 373 374 TI_DBG2(("tiINIGetDeviceHandles: pid %d\n", onePortContext->id)); 375 376 #ifdef FDS_DM 377 tdsaUpdateMCN(dmRoot, onePortContext); 378 #endif 379 380 /* nullify all device handles */ 381 for (i = 0 ; i < maxDevs ; i++) 382 { 383 tiDev[i] = agNULL; 384 } 385 386 /* 387 From the device list, returns only valid devices 388 */ 389 DeviceListList = tdsaAllShared->MainDeviceList.flink; 390 391 TD_ASSERT(DeviceListList, "DeviceListList NULL"); 392 if (DeviceListList == agNULL ) 393 { 394 TI_DBG1(("tiINIGetDeviceHandles: DeviceListList == agNULL\n")); 395 TI_DBG1(("tiINIGetDeviceHandles: seventh, returning not found, pid %d\n", onePortContext->id)); 396 return 0; 397 } 398 399 while ((DeviceIndex < maxDevs) && 400 DeviceListList != &(tdsaAllShared->MainDeviceList)) 401 { 402 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 403 #ifdef TD_DEBUG_ENABLE 404 pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData); 405 if (pSatDevData != agNULL) 406 { 407 TI_DBG3(("tiINIGetDeviceHandles: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 408 TI_DBG3(("tiINIGetDeviceHandles: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 409 } 410 #endif 411 TI_DBG3(("tiINIGetDeviceHandles: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 412 TI_DBG3(("tiINIGetDeviceHandles: device AddrHi 0x%08x AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 413 414 TI_DBG6(("tiINIGetDeviceHandles: handle %p\n", &(oneDeviceData->tiDeviceHandle))); 415 if (oneDeviceData->tdPortContext != onePortContext) 416 { 417 TI_DBG3(("tiINIGetDeviceHandles: different port\n")); 418 DeviceListList = DeviceListList->flink; 419 } 420 else 421 { 422 #ifdef SATA_ENABLE 423 if ((oneDeviceData->valid == agTRUE) && 424 (oneDeviceData->registered == agTRUE) && 425 (oneDeviceData->tdPortContext == onePortContext) && 426 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) 427 || DEVICE_IS_SATA_DEVICE(oneDeviceData) ) 428 ) 429 #else 430 if ((oneDeviceData->valid == agTRUE) && 431 (oneDeviceData->registered == agTRUE) && 432 (oneDeviceData->tdPortContext == onePortContext) && 433 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) ) 434 ) 435 #endif 436 { 437 if (DEVICE_IS_SSP_TARGET(oneDeviceData)) 438 { 439 TI_DBG2(("tiINIGetDeviceHandles: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle))); 440 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle); 441 FoundDevices++; 442 } 443 else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)) 444 && 445 oneDeviceData->satDevData.IDDeviceValid == agTRUE ) 446 { 447 TI_DBG2(("tiINIGetDeviceHandles: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle))); 448 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle); 449 FoundDevices++; 450 } 451 else 452 { 453 TI_DBG3(("tiINIGetDeviceHandles: skip case !!!\n")); 454 TI_DBG3(("tiINIGetDeviceHandles: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData))); 455 TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->satDevData.IDDeviceValid %d\n", oneDeviceData->satDevData.IDDeviceValid)); 456 TI_DBG3(("tiINIGetDeviceHandles: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext))); 457 TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext)); 458 } 459 TI_DBG3(("tiINIGetDeviceHandles: valid FoundDevices %d\n", FoundDevices)); 460 TI_DBG3(("tiINIGetDeviceHandles: agDevHandle %p\n", oneDeviceData->agDevHandle)); 461 } 462 else 463 { 464 TI_DBG3(("tiINIGetDeviceHandles: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData))); 465 TI_DBG3(("tiINIGetDeviceHandles: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext))); 466 TI_DBG3(("tiINIGetDeviceHandles: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext)); 467 } 468 DeviceIndex++; 469 DeviceListList = DeviceListList->flink; 470 } /* else */ 471 } 472 473 if (DeviceIndex > maxDevs) 474 { 475 TI_DBG1(("tiINIGetDeviceHandles: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs)); 476 FoundDevices = maxDevs; 477 } 478 479 TI_DBG1(("tiINIGetDeviceHandles: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id)); 480 481 return FoundDevices; 482 } 483 484 /***************************************************************************** 485 *! \brief tiINIGetDeviceHandlesForWinIOCTL 486 * 487 * Purpose: This routine is called to to return the device handles for each 488 * device currently available, this routine is only for Win IOCTL to display SAS topology. 489 * 490 * \param tiRoot: Pointer to driver Instance. 491 * \param tiPortalContext: Pointer to the portal context instance. 492 * \param agDev[]: Array to receive pointers to the device handles. 493 * \param maxDevs: Number of device handles which will fit in array pointed 494 * by agDev. 495 * \return: 496 * Number of device handle slots present (however, only maxDevs 497 * are copied into tiDev[]) which may be greater than the number of 498 * handles actually present. In short, returns the number of devices that 499 * were found. 500 * 501 * \note: 502 * 503 *****************************************************************************/ 504 osGLOBAL bit32 505 tiINIGetDeviceHandlesForWinIOCTL( 506 tiRoot_t * tiRoot, 507 tiPortalContext_t * tiPortalContext, 508 tiDeviceHandle_t * tiDev[], 509 bit32 maxDevs 510 ) 511 { 512 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 513 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 514 tdList_t *PortContextList; 515 tdsaPortContext_t *onePortContext = agNULL; 516 tdsaDeviceData_t *oneDeviceData = agNULL; 517 tdList_t *DeviceListList; 518 bit32 i; 519 bit32 FoundDevices = 0; 520 bit32 DeviceIndex = 0; 521 bit32 found = agFALSE; 522 #ifdef TD_DEBUG_ENABLE 523 satDeviceData_t *pSatDevData; 524 #endif 525 #ifdef FDS_DM 526 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot); 527 #endif 528 529 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: start\n")); 530 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: tiPortalContext %p\n", tiPortalContext)); 531 532 533 if (maxDevs == 0) 534 { 535 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: maxDevs is 0\n")); 536 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: first, returning 0\n")); 537 /* nullify all device handles */ 538 for (i = 0 ; i < maxDevs ; i++) 539 { 540 tiDev[i] = agNULL; 541 } 542 return 0; 543 } 544 545 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 546 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList))) 547 { 548 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 549 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: No available tdsaPortContext\n")); 550 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: second, returning 0\n")); 551 /* nullify all device handles */ 552 for (i = 0 ; i < maxDevs ; i++) 553 { 554 tiDev[i] = agNULL; 555 } 556 return 0; 557 } 558 else 559 { 560 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 561 } 562 /* find a corresponding portcontext */ 563 PortContextList = tdsaAllShared->MainPortContextList.flink; 564 while (PortContextList != &(tdsaAllShared->MainPortContextList)) 565 { 566 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList); 567 if(onePortContext == agNULL) continue; 568 569 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneportContext pid %d\n", onePortContext->id)); 570 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE) 571 { 572 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: found; oneportContext pid %d\n", onePortContext->id)); 573 found = agTRUE; 574 break; 575 } 576 PortContextList = PortContextList->flink; 577 } 578 579 if (found == agFALSE) 580 { 581 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: First, No corresponding tdsaPortContext\n")); 582 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: third, returning 0\n")); 583 /* nullify all device handles */ 584 for (i = 0 ; i < maxDevs ; i++) 585 { 586 tiDev[i] = agNULL; 587 } 588 return 0; 589 } 590 591 if (onePortContext == agNULL) 592 { 593 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: Second, No corressponding tdsaPortContext\n")); 594 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: fourth, returning 0\n")); 595 /* nullify all device handles */ 596 for (i = 0 ; i < maxDevs ; i++) 597 { 598 tiDev[i] = agNULL; 599 } 600 return 0; 601 } 602 603 if (onePortContext->valid == agFALSE) 604 { 605 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id)); 606 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: fifth, returning 0\n")); 607 /* nullify all device handles */ 608 for (i = 0 ; i < maxDevs ; i++) 609 { 610 tiDev[i] = agNULL; 611 } 612 return 0; 613 } 614 615 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed) 616 { 617 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: forth, discovery failed, pid %d\n", onePortContext->id)); 618 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: sixth, returning 0\n")); 619 /* nullify all device handles */ 620 for (i = 0 ; i < maxDevs ; i++) 621 { 622 tiDev[i] = agNULL; 623 } 624 return 0; 625 } 626 627 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED) 628 { 629 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: discovery not completed\n")); 630 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: sixth, returning DISCOVERY_IN_PROGRESS, pid %d\n", onePortContext->id)); 631 onePortContext->discovery.forcedOK = agTRUE; 632 return DISCOVERY_IN_PROGRESS; 633 } 634 635 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: pid %d\n", onePortContext->id)); 636 637 #ifdef FDS_DM 638 tdsaUpdateMCN(dmRoot, onePortContext); 639 #endif 640 641 /* nullify all device handles */ 642 for (i = 0 ; i < maxDevs ; i++) 643 { 644 tiDev[i] = agNULL; 645 } 646 647 /* 648 From the device list, returns only valid devices 649 */ 650 DeviceListList = tdsaAllShared->MainDeviceList.flink; 651 652 TD_ASSERT(DeviceListList, "DeviceListList NULL"); 653 if (DeviceListList == agNULL ) 654 { 655 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceListList == agNULL\n")); 656 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: seventh, returning not found, pid %d\n", onePortContext->id)); 657 return 0; 658 } 659 660 while ((DeviceIndex < maxDevs) && 661 DeviceListList != &(tdsaAllShared->MainDeviceList)) 662 { 663 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 664 if(oneDeviceData == agNULL) 665 { 666 TI_DBG3(("tiINIGetDeviceHandles: OneDeviceData is NULL\n")); 667 return 0; 668 } 669 #ifdef TD_DEBUG_ENABLE 670 pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData); 671 if (pSatDevData != agNULL) 672 { 673 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 674 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 675 } 676 #endif 677 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 678 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: device AddrHi 0x%08x AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 679 680 TI_DBG6(("tiINIGetDeviceHandlesForWinIOCTL: handle %p\n", &(oneDeviceData->tiDeviceHandle))); 681 if (oneDeviceData->tdPortContext != onePortContext) 682 { 683 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: different port\n")); 684 DeviceListList = DeviceListList->flink; 685 } 686 else 687 { 688 #ifdef SATA_ENABLE 689 if ((oneDeviceData->valid == agTRUE) && 690 (oneDeviceData->registered == agTRUE) && 691 (oneDeviceData->tdPortContext == onePortContext) && 692 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) 693 || DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData)) 694 ) 695 #else 696 if ((oneDeviceData->valid == agTRUE) && 697 (oneDeviceData->registered == agTRUE) && 698 (oneDeviceData->tdPortContext == onePortContext) && 699 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)) 700 ) 701 #endif 702 { 703 if (DEVICE_IS_SSP_TARGET(oneDeviceData)) 704 { 705 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle))); 706 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle); 707 DeviceIndex++; 708 FoundDevices++; 709 } 710 else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData)) 711 && 712 oneDeviceData->satDevData.IDDeviceValid == agTRUE ) 713 { 714 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle))); 715 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle); 716 DeviceIndex++; 717 FoundDevices++; 718 } 719 else if (DEVICE_IS_SMP_TARGET(oneDeviceData)) 720 { 721 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SMP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle))); 722 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle); 723 DeviceIndex++; 724 FoundDevices++; 725 } 726 else 727 { 728 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: skip case !!!\n")); 729 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData))); 730 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->satDevData.IDDeviceValid %d\n", oneDeviceData->satDevData.IDDeviceValid)); 731 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext))); 732 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext)); 733 } 734 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid FoundDevices %d\n", FoundDevices)); 735 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: agDevHandle %p\n", oneDeviceData->agDevHandle)); 736 } 737 else 738 { 739 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid %d SSP target %d STP target %d SATA device %d\n", oneDeviceData->valid, DEVICE_IS_SSP_TARGET(oneDeviceData), DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData))); 740 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: registered %d right port %d \n", oneDeviceData->registered, (oneDeviceData->tdPortContext == onePortContext))); 741 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneDeviceData->tdPortContext %p onePortContext %p\n", oneDeviceData->tdPortContext, onePortContext)); 742 } 743 //DeviceIndex++; 744 DeviceListList = DeviceListList->flink; 745 } /* else */ 746 } 747 748 if (DeviceIndex > maxDevs) 749 { 750 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs)); 751 FoundDevices = maxDevs; 752 } 753 754 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id)); 755 756 return FoundDevices; 757 } 758 759 760 /***************************************************************************** 761 *! \brief tiINIGetDeviceInfo 762 * 763 * Purpose: This routine is called by the OS Layer find out 764 * the name associated with the device and where 765 * it is mapped (address1 and address2). 766 * 767 * \param tiRoot: Pointer to driver Instance. 768 * \param tiDeviceHandle: device handle associated with the device 769 * \param tiDeviceInfo: pointer to structure where the information 770 * needs to be copied. 771 * \return: 772 * tiSuccess - successful 773 * tiInvalidHandle - device handle passed is not a valid handle. 774 * 775 * \note: 776 * 777 *****************************************************************************/ 778 osGLOBAL bit32 779 tiINIGetDeviceInfo( 780 tiRoot_t *tiRoot, 781 tiDeviceHandle_t *tiDeviceHandle, 782 tiDeviceInfo_t *tiDeviceInfo) 783 { 784 tdsaDeviceData_t *oneDeviceData = agNULL; 785 satDeviceData_t *pSatDevData = agNULL; 786 bit8 id_limit[5]; 787 bit8 SN_id_limit[25]; 788 agsaRoot_t *agRoot = agNULL; 789 790 TI_DBG6(("tiINIGetDeviceInfo: start \n")); 791 792 if (tiDeviceHandle == agNULL) 793 { 794 TI_DBG6(("tiINIGetDeviceInfo: tiDeviceHandle NULL\n")); 795 return tiInvalidHandle; 796 } 797 798 if (tiDeviceHandle->tdData == agNULL) 799 { 800 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NULL\n")); 801 return tiInvalidHandle; 802 } 803 else 804 { 805 806 oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData); 807 agRoot = oneDeviceData->agRoot; 808 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NOT NULL\n")); 809 } 810 if (oneDeviceData == agNULL) 811 { 812 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ oneDeviceData NULL\n")); 813 return tiInvalidHandle; 814 } 815 816 817 /* filling in the link rate */ 818 if (oneDeviceData->registered == agTRUE) 819 { 820 tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate; 821 } 822 else 823 { 824 tiDeviceInfo->info.devType_S_Rate = (bit8)(oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f); 825 } 826 827 /* just returning local and remote SAS address; doesn't have a name for SATA device, returns identify device data */ 828 if (DEVICE_IS_SATA_DEVICE(oneDeviceData) && (oneDeviceData->directlyAttached == agTRUE)) 829 { 830 osti_memset(&id_limit, 0, sizeof(id_limit)); 831 osti_memset(&SN_id_limit, 0, sizeof(SN_id_limit)); 832 833 /* SATA signature 0xABCD */ 834 id_limit[0] = 0xA; 835 id_limit[1] = 0xB; 836 id_limit[2] = 0xC; 837 id_limit[3] = 0xD; 838 839 pSatDevData = &(oneDeviceData->satDevData); 840 if (pSatDevData->satNCQ == agTRUE) 841 { 842 id_limit[4] = (bit8)pSatDevData->satNCQMaxIO; 843 } 844 else 845 { 846 /* no NCQ */ 847 id_limit[4] = 1; 848 } 849 850 osti_memcpy(&SN_id_limit, &(oneDeviceData->satDevData.satIdentifyData.serialNumber), 20); 851 osti_memcpy(&(SN_id_limit[20]), &id_limit, 5); 852 osti_memcpy(oneDeviceData->satDevData.SN_id_limit, SN_id_limit, 25); 853 /* serialNumber, 20 bytes + ABCD + NCQ LENGTH ; modelNumber, 40 bytes */ 854 // tiDeviceInfo->remoteName = (char *)&(oneDeviceData->satDevData.satIdentifyData.serialNumber); 855 tiDeviceInfo->remoteName = (char *)oneDeviceData->satDevData.SN_id_limit; 856 tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber); 857 // TI_DBG1(("tiINIGetDeviceInfo: SATA device remote hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasRemoteAddressHi, oneDeviceData->tdPortContext->sasRemoteAddressLo)); 858 // tdhexdump("tiINIGetDeviceInfo remotename", (bit8 *)&(oneDeviceData->satDevData.satIdentifyData.serialNumber), 20); 859 // tdhexdump("tiINIGetDeviceInfo new name", (bit8 *)&(SN_id_limit), sizeof(SN_id_limit)); 860 // tdhexdump("tiINIGetDeviceInfo remoteaddress", (bit8 *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber),40); 861 tiDeviceInfo->osAddress1 = 25; 862 tiDeviceInfo->osAddress2 = 40; 863 864 } 865 else if (DEVICE_IS_STP_TARGET(oneDeviceData)) 866 { 867 /* serialNumber, 20 bytes; modelNumber, 40 bytes */ 868 tiDeviceInfo->remoteName = (char *)&(oneDeviceData->satDevData.satIdentifyData.serialNumber); 869 tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber); 870 // TI_DBG1(("tiINIGetDeviceInfo: SATA device remote hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasRemoteAddressHi, oneDeviceData->tdPortContext->sasRemoteAddressLo)); 871 // tdhexdump("tiINIGetDeviceInfo remotename", (bit8 *)&(oneDeviceData->satDevData.satIdentifyData.serialNumber), 20); 872 // tdhexdump("tiINIGetDeviceInfo remoteaddress", (bit8 *)&(oneDeviceData->satDevData.satIdentifyData.modelNumber),40); 873 tiDeviceInfo->osAddress1 = 20; 874 tiDeviceInfo->osAddress2 = 40; 875 } 876 else 877 { 878 tiDeviceInfo->remoteName = (char *)&(oneDeviceData->SASAddressID.sasAddressHi); 879 tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->SASAddressID.sasAddressLo); 880 TI_DBG1(("tiINIGetDeviceInfo: SAS device remote hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasRemoteAddressHi, oneDeviceData->tdPortContext->sasRemoteAddressLo)); 881 tiDeviceInfo->osAddress1 = 4; 882 tiDeviceInfo->osAddress2 = 4; 883 } 884 885 tiDeviceInfo->localName = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi); 886 tiDeviceInfo->localAddress = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo); 887 888 TI_DBG6(("tiINIGetDeviceInfo: local hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasLocalAddressHi, oneDeviceData->tdPortContext->sasLocalAddressLo)); 889 890 if (oneDeviceData->agDevHandle == agNULL) 891 { 892 TI_DBG1(("tiINIGetDeviceInfo: Error! oneDeviceData->agDevHandle is NULL")); 893 return tiError; 894 } 895 else 896 { 897 saGetDeviceInfo(agRoot, agNULL, 0, 0,oneDeviceData->agDevHandle); 898 } 899 900 901 return tiSuccess; 902 } 903 904 /***************************************************************************** 905 *! \brief tiINILogin 906 * 907 * Purpose: This function is called to request that the Transport Dependent 908 * Layer initiates login for a specific target. 909 * 910 * \param tiRoot: Pointer to driver Instance. 911 * \param tiDeviceHandle: Pointer to a target device handle discovered 912 * following the discovery. 913 * 914 * \return: 915 * tiSuccess Login initiated. 916 * tiError Login failed. 917 * tiBusy Login can not be initiated at this time. 918 * tiNotSupported This API is currently not supported by this 919 * Transport Layer 920 * 921 * 922 *****************************************************************************/ 923 osGLOBAL bit32 924 tiINILogin( 925 tiRoot_t *tiRoot, 926 tiDeviceHandle_t *tiDeviceHandle 927 ) 928 { 929 TI_DBG6(("tiINILogin: start\n")); 930 return tiNotSupported; 931 } 932 933 /***************************************************************************** 934 *! \brief tiINILogout 935 * 936 * Purpose: This function is called to request that the Transport Dependent 937 * Layer initiates logout for a specific target from the previously 938 * successful login through tiINILogin() call. 939 * 940 * \param tiRoot : Pointer to the OS Specific module allocated tiRoot_t 941 * instance. 942 * \param tiDeviceHandle: Pointer to a target device handle. 943 * 944 * \return: 945 * tiSuccess Logout initiated. 946 * tiError Logout failed. 947 * tiBusy Logout can not be initiated at this time. 948 * tiNotSupported This API is currently not supported by this 949 * Transport Layer 950 * 951 * 952 *****************************************************************************/ 953 osGLOBAL bit32 954 tiINILogout( 955 tiRoot_t *tiRoot, 956 tiDeviceHandle_t *tiDeviceHandle 957 ) 958 { 959 TI_DBG6(("tiINILogout: start\n")); 960 return tiNotSupported; 961 } 962 /***************************************************************************** 963 *! \brief tiINIGetExpander 964 * 965 * 966 * \note: 967 * 968 *****************************************************************************/ 969 osGLOBAL bit32 970 tiINIGetExpander( 971 tiRoot_t * tiRoot, 972 tiPortalContext_t * tiPortalContext, 973 tiDeviceHandle_t * tiDev, 974 tiDeviceHandle_t ** tiExp 975 ) 976 { 977 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 978 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 979 tdList_t *PortContextList; 980 tdsaPortContext_t *onePortContext = agNULL; 981 tdsaDeviceData_t *oneDeviceData = agNULL; 982 tdList_t *DeviceListList; 983 tdsaDeviceData_t *oneTargetDeviceData = agNULL; 984 tdsaDeviceData_t *oneExpanderDeviceData = agNULL; 985 bit32 found = agFALSE; 986 oneTargetDeviceData = (tdsaDeviceData_t *)tiDev->tdData; 987 if (oneTargetDeviceData == agNULL) 988 { 989 TI_DBG1(("tiINIGetExpander: oneTargetDeviceData is NULL\n")); 990 return tiError; 991 } 992 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 993 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList))) 994 { 995 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 996 TI_DBG1(("tiINIGetExpander: No available tdsaPortContext\n")); 997 TI_DBG1(("tiINIGetExpander: second, returning 0\n")); 998 return tiError; 999 } 1000 else 1001 { 1002 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 1003 } 1004 /* find a corresponding portcontext */ 1005 PortContextList = tdsaAllShared->MainPortContextList.flink; 1006 while (PortContextList != &(tdsaAllShared->MainPortContextList)) 1007 { 1008 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList); 1009 TI_DBG3(("tiINIGetExpander: oneportContext pid %d\n", onePortContext->id)); 1010 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE) 1011 { 1012 TI_DBG3(("tiINIGetExpander: found; oneportContext pid %d\n", onePortContext->id)); 1013 found = agTRUE; 1014 break; 1015 } 1016 PortContextList = PortContextList->flink; 1017 } 1018 if (found == agFALSE) 1019 { 1020 TI_DBG1(("tiINIGetExpander: First, No corresponding tdsaPortContext\n")); 1021 TI_DBG1(("tiINIGetExpander: third, returning 0\n")); 1022 return tiError; 1023 } 1024 if (onePortContext == agNULL) 1025 { 1026 TI_DBG1(("tiINIGetExpander: Second, No corressponding tdsaPortContext\n")); 1027 TI_DBG1(("tiINIGetExpander: fourth, returning 0\n")); 1028 return tiError; 1029 } 1030 if (onePortContext->valid == agFALSE) 1031 { 1032 TI_DBG1(("tiINIGetExpander: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id)); 1033 TI_DBG1(("tiINIGetExpander: fifth, returning 0\n")); 1034 return tiError; 1035 } 1036 DeviceListList = tdsaAllShared->MainDeviceList.flink; 1037 while ( DeviceListList != &(tdsaAllShared->MainDeviceList) ) 1038 { 1039 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 1040 if (oneDeviceData->tdPortContext != onePortContext) 1041 { 1042 TI_DBG3(("tiINIGetExpander: different port\n")); 1043 DeviceListList = DeviceListList->flink; 1044 } 1045 else 1046 { 1047 if (oneDeviceData == oneTargetDeviceData) 1048 { 1049 oneExpanderDeviceData = oneDeviceData->ExpDevice; 1050 if (oneExpanderDeviceData == agNULL) 1051 { 1052 TI_DBG1(("tiINIGetExpander: oneExpanderDeviceData is NULL\n")); 1053 return tiError; 1054 } 1055 *tiExp = &(oneExpanderDeviceData->tiDeviceHandle); 1056 return tiSuccess; 1057 } 1058 DeviceListList = DeviceListList->flink; 1059 } 1060 } 1061 return tiError; 1062 } 1063 1064 1065 osGLOBAL void tiIniGetDirectSataSasAddr(tiRoot_t * tiRoot, bit32 phyId, bit8 **sasAddressHi, bit8 **sasAddressLo) 1066 { 1067 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1068 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1069 agsaRoot_t *agRoot = &tdsaAllShared->agRootInt; 1070 tiIOCTLPayload_wwn_t agIoctlPayload; 1071 bit8 nvmDev; 1072 bit32 status; 1073 int i; 1074 agIoctlPayload.Length = 4096; 1075 agIoctlPayload.Reserved = 0; 1076 agIoctlPayload.MinorFunction = IOCTL_MN_NVMD_GET_CONFIG; 1077 agIoctlPayload.MajorFunction = IOCTL_MJ_NVMD_GET; 1078 tiCOMDelayedInterruptHandler(tiRoot, 0,1, tiNonInterruptContext); 1079 if(tiIS_SPC(agRoot)) 1080 { 1081 nvmDev = 4; 1082 status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev); 1083 } 1084 else 1085 { 1086 nvmDev = 1; 1087 status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev); 1088 } 1089 if(status == IOCTL_CALL_FAIL) 1090 { 1091 #if !(defined(__FreeBSD__)) 1092 printk("Error getting Adapter WWN\n"); 1093 #else 1094 printf("Error getting Adapter WWN\n"); 1095 #endif 1096 return; 1097 } 1098 for(i=0; i< TD_MAX_NUM_PHYS; i++) 1099 { 1100 *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressHi) = *(bit32 *)&agIoctlPayload.FunctionSpecificArea[0]; 1101 *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressLo) = *(bit32 *)&agIoctlPayload.FunctionSpecificArea[4]; 1102 TI_DBG3(("SAS AddressHi is 0x%x\n", *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressHi))); 1103 TI_DBG3(("SAS AddressLo is 0x%x\n", *(bit32 *)(tdsaAllShared->Ports[i].SASID.sasAddressLo))); 1104 } 1105 *sasAddressHi = tdsaAllShared->Ports[phyId].SASID.sasAddressHi; 1106 *sasAddressLo = tdsaAllShared->Ports[phyId].SASID.sasAddressLo; 1107 } 1108 osGLOBAL tiDeviceHandle_t * 1109 tiINIGetExpDeviceHandleBySasAddress( 1110 tiRoot_t * tiRoot, 1111 tiPortalContext_t * tiPortalContext, 1112 bit32 sas_addr_hi, 1113 bit32 sas_addr_lo, 1114 bit32 maxDevs 1115 ) 1116 1117 { 1118 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1119 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1120 tdList_t *PortContextList; 1121 tdsaPortContext_t *onePortContext = agNULL; 1122 tdsaDeviceData_t *oneDeviceData = agNULL; 1123 tdList_t *DeviceListList; 1124 //bit32 i; 1125 //bit32 FoundDevices = 0; 1126 bit32 DeviceIndex = 0; 1127 bit32 found = agFALSE; 1128 1129 1130 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: start\n")); 1131 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: tiPortalContext %p\n", tiPortalContext)); 1132 1133 1134 if (maxDevs == 0) 1135 { 1136 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: maxDevs is 0\n")); 1137 1138 return agNULL; 1139 } 1140 1141 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 1142 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList))) 1143 { 1144 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 1145 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: No available tdsaPortContext\n")); 1146 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: second, returning 0\n")); 1147 return agNULL; 1148 } 1149 else 1150 { 1151 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 1152 } 1153 /* find a corresponding portcontext */ 1154 PortContextList = tdsaAllShared->MainPortContextList.flink; 1155 1156 if(PortContextList == agNULL) 1157 { 1158 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: PortContextList is NULL!!\n")); 1159 return agNULL; 1160 } 1161 1162 while (PortContextList != &(tdsaAllShared->MainPortContextList)) 1163 { 1164 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList); 1165 1166 if(onePortContext == agNULL) 1167 { 1168 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: onePortContext is NULL!!\n")); 1169 return agNULL; 1170 } 1171 1172 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneportContext pid %d\n", onePortContext->id)); 1173 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE) 1174 { 1175 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: found; oneportContext pid %d\n", onePortContext->id)); 1176 found = agTRUE; 1177 break; 1178 } 1179 1180 if(PortContextList != agNULL) 1181 { 1182 PortContextList = PortContextList->flink; 1183 } 1184 1185 } 1186 1187 if (found == agFALSE) 1188 { 1189 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: First, No corresponding tdsaPortContext\n")); 1190 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: third, returning 0\n")); 1191 /* nullify all device handles */ 1192 return agNULL; 1193 } 1194 1195 if (onePortContext == agNULL) 1196 { 1197 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Second, No corressponding tdsaPortContext\n")); 1198 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fourth, returning 0\n")); 1199 /* nullify all device handles */ 1200 return agNULL; 1201 } 1202 1203 if (onePortContext->valid == agFALSE) 1204 { 1205 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id)); 1206 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fifth, returning 0\n")); 1207 return agNULL; 1208 } 1209 1210 1211 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: pid %d\n", onePortContext->id)); 1212 1213 1214 /* to do: check maxdev and length of Mainlink */ 1215 /* 1216 From the device list, returns only valid devices 1217 */ 1218 DeviceListList = tdsaAllShared->MainDeviceList.flink; 1219 1220 if(DeviceListList == agNULL) 1221 { 1222 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: DeviceListList == agNULL\n")); 1223 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: seventh, returning not found, pid %d\n", onePortContext->id)); 1224 return agNULL; 1225 } 1226 1227 while ((DeviceIndex < maxDevs) && 1228 DeviceListList != &(tdsaAllShared->MainDeviceList)) 1229 { 1230 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 1231 1232 if(oneDeviceData == agNULL) 1233 { 1234 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneDeviceData is NULL!!\n")); 1235 return agNULL; 1236 } 1237 1238 1239 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: handle %p\n", &(oneDeviceData->tiDeviceHandle))); 1240 if (oneDeviceData->tdPortContext != onePortContext) 1241 { 1242 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: different port\n")); 1243 1244 if(DeviceListList != agNULL) 1245 { 1246 DeviceListList = DeviceListList->flink; 1247 } 1248 1249 } 1250 else 1251 { 1252 1253 if ((oneDeviceData->valid == agTRUE) && 1254 (oneDeviceData->registered == agTRUE) && 1255 (oneDeviceData->tdPortContext == onePortContext) && 1256 ( 1257 (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) || 1258 (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) || 1259 DEVICE_IS_SMP_TARGET(oneDeviceData) 1260 ) 1261 ) 1262 1263 { 1264 1265 if(oneDeviceData->SASAddressID.sasAddressLo == sas_addr_lo && oneDeviceData->SASAddressID.sasAddressHi == sas_addr_hi) 1266 { 1267 //TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: valid FoundDevices %d\n", FoundDevices)); 1268 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: agDevHandle %p\n", oneDeviceData->agDevHandle)); 1269 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: Matched sas address: low %x and high %x\n", oneDeviceData->SASAddressID.sasAddressLo, oneDeviceData->SASAddressID.sasAddressHi)); 1270 return &(oneDeviceData->tiDeviceHandle); 1271 } 1272 } 1273 DeviceIndex++; 1274 DeviceListList = DeviceListList->flink; 1275 } /* else */ 1276 } 1277 1278 return agNULL; 1279 } 1280 1281 1282 1283 1284 #ifdef TD_DISCOVER 1285 /***************************************************************************** 1286 *! \brief tdsaDiscover 1287 * 1288 * Purpose: This function is called to trigger topology discovery within a 1289 * portcontext. 1290 * 1291 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1292 * instance. 1293 * \param onePortContext: Pointer to the portal context instance. 1294 * \param type: Type of discovery. It can be SAS or SATA. 1295 * \param option: discovery option. It can be Full or Incremental discovery. 1296 * 1297 * \return: 1298 * tiSuccess Discovery initiated. 1299 * tiError Discovery could not be initiated at this time. 1300 * 1301 * \note: 1302 * 1303 *****************************************************************************/ 1304 osGLOBAL bit32 1305 tdsaDiscover( 1306 tiRoot_t *tiRoot, 1307 tdsaPortContext_t *onePortContext, 1308 bit32 type, 1309 bit32 option 1310 ) 1311 1312 { 1313 bit32 ret = tiError; 1314 TI_DBG3(("tdsaDiscover: start\n")); 1315 1316 if (onePortContext->valid == agFALSE) 1317 { 1318 TI_DBG1(("tdsaDiscover: aborting discovery\n")); 1319 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1320 return ret; 1321 } 1322 1323 switch ( option ) 1324 { 1325 case TDSA_DISCOVERY_OPTION_FULL_START: 1326 TI_DBG3(("tdsaDiscover: full\n")); 1327 onePortContext->discovery.type = TDSA_DISCOVERY_OPTION_FULL_START; 1328 if ( type == TDSA_DISCOVERY_TYPE_SAS ) 1329 { 1330 ret = tdsaSASFullDiscover(tiRoot, onePortContext); 1331 } 1332 #ifdef SATA_ENABLE 1333 else if ( type == TDSA_DISCOVERY_TYPE_SATA ) 1334 { 1335 if (onePortContext->discovery.status == DISCOVERY_SAS_DONE) 1336 { 1337 ret = tdsaSATAFullDiscover(tiRoot, onePortContext); 1338 } 1339 } 1340 #endif 1341 break; 1342 case TDSA_DISCOVERY_OPTION_INCREMENTAL_START: 1343 TI_DBG3(("tdsaDiscover: incremental\n")); 1344 onePortContext->discovery.type = TDSA_DISCOVERY_OPTION_INCREMENTAL_START; 1345 if ( type == TDSA_DISCOVERY_TYPE_SAS ) 1346 { 1347 TI_DBG3(("tdsaDiscover: incremental SAS\n")); 1348 ret = tdsaSASIncrementalDiscover(tiRoot, onePortContext); 1349 } 1350 #ifdef SATA_ENABLE 1351 else if ( type == TDSA_DISCOVERY_TYPE_SATA ) 1352 { 1353 if (onePortContext->discovery.status == DISCOVERY_SAS_DONE) 1354 { 1355 TI_DBG3(("tdsaDiscover: incremental SATA\n")); 1356 ret = tdsaSATAIncrementalDiscover(tiRoot, onePortContext); 1357 } 1358 } 1359 #endif 1360 break; 1361 case TDSA_DISCOVERY_OPTION_ABORT: 1362 TI_DBG1(("tdsaDiscover: abort\n")); 1363 break; 1364 default: 1365 break; 1366 1367 } 1368 if (ret != tiSuccess) 1369 { 1370 TI_DBG1(("tdsaDiscover: fail, error 0x%x\n", ret)); 1371 } 1372 return ret; 1373 } 1374 1375 /***************************************************************************** 1376 *! \brief tdsaSASFullDiscover 1377 * 1378 * Purpose: This function is called to trigger full SAS topology discovery 1379 * within a portcontext. 1380 * 1381 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1382 * instance. 1383 * \param onePortContext: Pointer to the portal context instance. 1384 * 1385 * \return: 1386 * tiSuccess Discovery initiated. 1387 * tiError Discovery could not be initiated at this time. 1388 * 1389 * \note: 1390 * 1391 *****************************************************************************/ 1392 osGLOBAL bit32 1393 tdsaSASFullDiscover( 1394 tiRoot_t *tiRoot, 1395 tdsaPortContext_t *onePortContext 1396 ) 1397 { 1398 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1399 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1400 tdsaDeviceData_t *oneDeviceData = agNULL; 1401 tdList_t *DeviceListList; 1402 int i, j; 1403 bit8 portMaxRate; 1404 TI_DBG3(("tdsaSASFullDiscover: start\n")); 1405 if (onePortContext->valid == agFALSE) 1406 { 1407 TI_DBG1(("tdsaSASFullDiscover: aborting discovery\n")); 1408 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1409 return tiError; 1410 } 1411 /* 1412 1. abort all IO; may need a new LL API since TD does not queue IO's 1413 2. initializes(or invalidate) devices belonging to the port 1414 3. onePortContext->DiscoveryState == ITD_DSTATE_STARTED 1415 4. add directly connected one; if directed-SAS, spin-up 1416 5. tdsaSASUpStreamDiscoverStart(agRoot, pPort, pDevice) 1417 */ 1418 /* 1419 invalidate all devices belonging to the portcontext except direct attached SAS/SATA 1420 */ 1421 DeviceListList = tdsaAllShared->MainDeviceList.flink; 1422 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 1423 { 1424 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 1425 TI_DBG3(("tdsaSASFullDiscover: STARTED loop id %d\n", oneDeviceData->id)); 1426 TI_DBG3(("tdsaSASFullDiscover: STARTED loop sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1427 TI_DBG3(("tdsaSASFullDiscover: STARTED loop sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1428 if (oneDeviceData->tdPortContext == onePortContext && 1429 (onePortContext->nativeSATAMode == agFALSE && onePortContext->directAttatchedSAS == agFALSE) ) 1430 1431 { 1432 TI_DBG3(("tdsaSASFullDiscover: invalidate\n")); 1433 oneDeviceData->valid = agFALSE; 1434 oneDeviceData->processed = agFALSE; 1435 } 1436 else 1437 { 1438 TI_DBG3(("tdsaSASFullDiscover: not invalidate\n")); 1439 /* no changes */ 1440 } 1441 DeviceListList = DeviceListList->flink; 1442 } 1443 1444 onePortContext->DiscoveryState = ITD_DSTATE_STARTED; 1445 /* nativeSATAMode is set in ossaHwCB() in link up */ 1446 if (onePortContext->nativeSATAMode == agFALSE) /* default: SAS and SAS/SATA mode */ 1447 { 1448 if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE && 1449 SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) ) 1450 { 1451 for(i=0;i<TD_MAX_NUM_PHYS;i++) 1452 { 1453 if (onePortContext->PhyIDList[i] == agTRUE) 1454 { 1455 1456 for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++) 1457 { 1458 saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL); 1459 } 1460 break; 1461 } 1462 } 1463 } 1464 /* 1465 add the device 1466 1. add device in TD layer 1467 2. call saRegisterNewDevice 1468 3. update agDevHandle in ossaDeviceRegistrationCB() 1469 */ 1470 portMaxRate = onePortContext->LinkRate; 1471 oneDeviceData = tdsaPortSASDeviceAdd( 1472 tiRoot, 1473 onePortContext, 1474 onePortContext->sasIDframe, 1475 agFALSE, 1476 portMaxRate, 1477 IT_NEXUS_TIMEOUT, 1478 0, 1479 SAS_DEVICE_TYPE, 1480 agNULL, 1481 0xFF 1482 ); 1483 if (oneDeviceData) 1484 { 1485 if (oneDeviceData->registered == agFALSE) 1486 { 1487 /* 1488 set the timer and wait till the device(directly attached. eg Expander) to be registered. 1489 Then, in tdsaDeviceRegistrationTimerCB(), tdsaSASUpStreamDiscoverStart() is called 1490 */ 1491 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData); 1492 } 1493 else 1494 { 1495 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData); 1496 } 1497 } 1498 #ifdef REMOVED 1499 // temp testing code 1500 tdsaReportManInfoSend(tiRoot, oneDeviceData); 1501 //end temp testing code 1502 #endif 1503 } 1504 else /* SATAOnlyMode*/ 1505 { 1506 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess); 1507 } 1508 1509 return tiSuccess; 1510 } 1511 1512 /***************************************************************************** 1513 *! \brief tdsaSASUpStreamDiscoverStart 1514 * 1515 * Purpose: This function is called to trigger upstream traverse in topology 1516 * within a portcontext. 1517 * 1518 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1519 * instance. 1520 * \param onePortContext: Pointer to the portal context instance. 1521 * \param oneDeviceData: Pointer to the device data. 1522 * 1523 * \return: 1524 * None 1525 * 1526 * \note: 1527 * 1528 *****************************************************************************/ 1529 osGLOBAL void 1530 tdsaSASUpStreamDiscoverStart( 1531 tiRoot_t *tiRoot, 1532 tdsaPortContext_t *onePortContext, 1533 tdsaDeviceData_t *oneDeviceData 1534 ) 1535 { 1536 tdsaExpander_t *oneExpander; 1537 1538 TI_DBG3(("tdsaSASUpStreamDiscoverStart: start\n")); 1539 1540 if (onePortContext->valid == agFALSE) 1541 { 1542 TI_DBG1(("tdsaSASUpStreamDiscoverStart: aborting discovery\n")); 1543 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1544 return; 1545 } 1546 1547 /* 1548 1. update discovery state to UP_STREAM 1549 2. if (expander) add it 1550 3. tdsaSASUpStreamDiscovering 1551 1552 */ 1553 onePortContext->discovery.status = DISCOVERY_UP_STREAM; 1554 if ( 1555 (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 1556 || 1557 (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) 1558 ) 1559 { 1560 oneExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, oneDeviceData); 1561 if ( oneExpander != agNULL) 1562 { 1563 /* (2.2.1) Add to discovering list */ 1564 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander); 1565 } 1566 else 1567 { 1568 TI_DBG1(("tdsaSASUpStreamDiscoverStart: failed to allocate expander or discovey aborted\n")); 1569 return; 1570 } 1571 } 1572 1573 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 1574 1575 return; 1576 } 1577 1578 /***************************************************************************** 1579 *! \brief tdsaSASUpStreamDiscovering 1580 * 1581 * Purpose: For each expander in the expander list, this function sends SMP to 1582 * find information for discovery and calls 1583 * tdsaSASDownStreamDiscoverStart() function. 1584 * 1585 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1586 * instance. 1587 * \param onePortContext: Pointer to the portal context instance. 1588 * \param oneDeviceData: Pointer to the device data. 1589 * 1590 * \return: 1591 * None 1592 * 1593 * \note: 1594 * 1595 *****************************************************************************/ 1596 osGLOBAL void 1597 tdsaSASUpStreamDiscovering( 1598 tiRoot_t *tiRoot, 1599 tdsaPortContext_t *onePortContext, 1600 tdsaDeviceData_t *oneDeviceData 1601 ) 1602 { 1603 tdList_t *ExpanderList; 1604 tdsaExpander_t *oneNextExpander = agNULL; 1605 1606 TI_DBG3(("tdsaSASUpStreamDiscovering: start\n")); 1607 if (onePortContext->valid == agFALSE) 1608 { 1609 TI_DBG1(("tdsaSASUpStreamDiscovering: aborting discovery\n")); 1610 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1611 return; 1612 } 1613 /* 1614 1. find the next expander 1615 2. if (there is next expander) send report general with saSMPStart 1616 else tdsaSASDownStreamDiscoverStart 1617 1618 */ 1619 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1620 if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 1621 { 1622 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1623 TI_DBG3(("tdsaSASUpStreamDiscovering: should be the end\n")); 1624 oneNextExpander = agNULL; 1625 } 1626 else 1627 { 1628 TDLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList)); 1629 oneNextExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList); 1630 TDLIST_ENQUEUE_AT_HEAD(&(oneNextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 1631 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1632 1633 TI_DBG3(("tdssSASDiscoveringExpander tdsaSASUpStreamDiscovering: dequeue head\n")); 1634 TI_DBG3(("tdsaSASUpStreamDiscovering: expander id %d\n", oneNextExpander->id)); 1635 } 1636 1637 if (oneNextExpander != agNULL) 1638 { 1639 tdsaReportGeneralSend(tiRoot, oneNextExpander->tdDevice); 1640 } 1641 else 1642 { 1643 TI_DBG3(("tdsaSASUpStreamDiscovering: No more expander list\n")); 1644 tdsaSASDownStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData); 1645 } 1646 1647 return; 1648 } 1649 1650 /***************************************************************************** 1651 *! \brief tdsaSASDownStreamDiscoverStart 1652 * 1653 * Purpose: This function is called to trigger downstream traverse in topology 1654 * within a portcontext. 1655 * 1656 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1657 * instance. 1658 * \param onePortContext: Pointer to the portal context instance. 1659 * \param oneDeviceData: Pointer to the device data. 1660 * 1661 * \return: 1662 * None 1663 * 1664 * \note: 1665 * 1666 *****************************************************************************/ 1667 osGLOBAL void 1668 tdsaSASDownStreamDiscoverStart( 1669 tiRoot_t *tiRoot, 1670 tdsaPortContext_t *onePortContext, 1671 tdsaDeviceData_t *oneDeviceData 1672 ) 1673 { 1674 tdsaExpander_t *oneExpander; 1675 tdsaExpander_t *UpStreamExpander; 1676 TI_DBG3(("tdsaSASDownStreamDiscoverStart: start\n")); 1677 1678 if (onePortContext->valid == agFALSE) 1679 { 1680 TI_DBG1(("tdsaSASDownStreamDiscoverStart: aborting discovery\n")); 1681 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1682 return; 1683 } 1684 /* 1685 1. update discover state 1686 2. if (expander is root) add it 1687 else just add it 1688 3. tdsaSASDownStreamDiscovering 1689 1690 */ 1691 /* set discovery status */ 1692 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 1693 1694 TI_DBG3(("tdsaSASDownStreamDiscoverStart: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData)); 1695 1696 /* If it's an expander */ 1697 if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 1698 || (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE)) 1699 { 1700 oneExpander = oneDeviceData->tdExpander; 1701 UpStreamExpander = oneExpander->tdUpStreamExpander; 1702 1703 /* If the two expanders are the root of two edge sets; sub-to-sub */ 1704 if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->tdUpStreamExpander == oneExpander ) ) 1705 { 1706 TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root found pExpander=%p pUpStreamExpander=%p\n", 1707 oneExpander, UpStreamExpander)); 1708 //Saves the root expander 1709 onePortContext->discovery.RootExp = oneExpander; 1710 TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 1711 TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 1712 1713 /* reset up stream inform for pExpander */ 1714 oneExpander->tdUpStreamExpander = agNULL; 1715 /* Add the pExpander to discovering list */ 1716 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander); 1717 1718 /* reset up stream inform for oneExpander */ 1719 UpStreamExpander->tdUpStreamExpander = agNULL; 1720 /* Add the UpStreamExpander to discovering list */ 1721 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, UpStreamExpander); 1722 } 1723 /* If the two expanders are not the root of two edge sets. eg) one root */ 1724 else 1725 { 1726 //Saves the root expander 1727 onePortContext->discovery.RootExp = oneExpander; 1728 1729 TI_DBG3(("tdsaSASDownStreamDiscoverStart: NO Root pExpander=%p\n", oneExpander)); 1730 TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 1731 TI_DBG3(("tdsaSASDownStreamDiscoverStart: Root exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 1732 1733 /* (2.2.2.1) Add the pExpander to discovering list */ 1734 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander); 1735 } 1736 } 1737 1738 /* Continue down stream discovering */ 1739 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 1740 1741 return; 1742 } 1743 1744 /***************************************************************************** 1745 *! \brief tdsaSASDownStreamDiscovering 1746 * 1747 * Purpose: For each expander in the expander list, this function sends SMP to 1748 * find information for discovery and calls 1749 * tdsaSASDownStreamDiscoverStart() function. 1750 * 1751 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1752 * instance. 1753 * \param onePortContext: Pointer to the portal context instance. 1754 * \param oneDeviceData: Pointer to the device data. 1755 * 1756 * \return: 1757 * None 1758 * 1759 * \note: 1760 * 1761 *****************************************************************************/ 1762 osGLOBAL void 1763 tdsaSASDownStreamDiscovering( 1764 tiRoot_t *tiRoot, 1765 tdsaPortContext_t *onePortContext, 1766 tdsaDeviceData_t *oneDeviceData 1767 ) 1768 { 1769 tdsaExpander_t *NextExpander = agNULL; 1770 tdList_t *ExpanderList; 1771 1772 TI_DBG3(("tdsaSASDownStreamDiscovering: start\n")); 1773 1774 TI_DBG3(("tdsaSASDownStreamDiscovering: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData)); 1775 1776 if (onePortContext->valid == agFALSE) 1777 { 1778 TI_DBG1(("tdsaSASDownStreamDiscovering: aborting discovery\n")); 1779 tdsaSASDiscoverAbort(tiRoot, onePortContext); 1780 return; 1781 } 1782 1783 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1784 if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList))) 1785 { 1786 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1787 TI_DBG3(("tdsaSASDownStreamDiscovering: should be the end\n")); 1788 NextExpander = agNULL; 1789 } 1790 else 1791 { 1792 TDLIST_DEQUEUE_FROM_HEAD(&ExpanderList, &(onePortContext->discovery.discoveringExpanderList)); 1793 NextExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList); 1794 TDLIST_ENQUEUE_AT_HEAD(&(NextExpander->linkNode), &(onePortContext->discovery.discoveringExpanderList)); 1795 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1796 TI_DBG3(("tdssSASDiscoveringExpander tdsaSASDownStreamDiscovering: dequeue head\n")); 1797 TI_DBG3(("tdsaSASDownStreamDiscovering: expander id %d\n", NextExpander->id)); 1798 1799 } 1800 1801 /* If there is an expander for continue discoving */ 1802 if ( NextExpander != agNULL) 1803 { 1804 TI_DBG3(("tdsaSASDownStreamDiscovering: Found pNextExpander=%p\n, discoveryStatus=0x%x", 1805 NextExpander, onePortContext->discovery.status)); 1806 1807 switch (onePortContext->discovery.status) 1808 { 1809 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 1810 case DISCOVERY_DOWN_STREAM: 1811 /* Send report general for the next expander */ 1812 TI_DBG3(("tdsaSASDownStreamDiscovering: DownStream pNextExpander->pDevice=%p\n", NextExpander->tdDevice)); 1813 tdsaReportGeneralSend(tiRoot, NextExpander->tdDevice); 1814 break; 1815 /* If the discovery status is DISCOVERY_CONFIG_ROUTING */ 1816 case DISCOVERY_CONFIG_ROUTING: 1817 case DISCOVERY_REPORT_PHY_SATA: 1818 1819 /* set discovery status */ 1820 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 1821 1822 TI_DBG3(("tdsaSASDownStreamDiscovering: pPort->discovery.status=DISCOVERY_CONFIG_ROUTING, nake it DOWN_STREAM\n")); 1823 /* If not the last phy */ 1824 if ( NextExpander->discoveringPhyId < NextExpander->tdDevice->numOfPhys ) 1825 { 1826 TI_DBG3(("tdsaSASDownStreamDiscovering: pNextExpander->discoveringPhyId=0x%x pNextExpander->pDevice->numOfPhys=0x%x. Send More Discover\n", 1827 NextExpander->discoveringPhyId, NextExpander->tdDevice->numOfPhys)); 1828 /* Send discover for the next expander */ 1829 tdsaDiscoverSend(tiRoot, NextExpander->tdDevice); 1830 } 1831 /* If it's the last phy */ 1832 else 1833 { 1834 TI_DBG3(("tdsaSASDownStreamDiscovering: Last Phy, remove expander%p start DownStream=%p\n", 1835 NextExpander, NextExpander->tdDevice)); 1836 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, NextExpander); 1837 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, NextExpander->tdDevice); 1838 } 1839 break; 1840 1841 default: 1842 TI_DBG3(("tdsaSASDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status)); 1843 } 1844 } 1845 /* If no expander for continue discoving */ 1846 else 1847 { 1848 TI_DBG3(("tdsaSASDownStreamDiscovering: No more expander DONE\n")); 1849 /* discover done */ 1850 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess); 1851 } 1852 1853 return; 1854 } 1855 1856 /***************************************************************************** 1857 *! \brief tdsaCleanAllExp 1858 * 1859 * Purpose: This function cleans up expander data structures after discovery 1860 * is complete. 1861 * 1862 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1863 * instance. 1864 * \param onePortContext: Pointer to the portal context instance. 1865 * 1866 * \return: 1867 * None 1868 * 1869 * \note: 1870 * 1871 *****************************************************************************/ 1872 osGLOBAL void 1873 tdsaCleanAllExp( 1874 tiRoot_t *tiRoot, 1875 tdsaPortContext_t *onePortContext 1876 ) 1877 { 1878 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1879 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1880 tdList_t *ExpanderList; 1881 tdsaExpander_t *tempExpander; 1882 tdsaPortContext_t *tmpOnePortContext = onePortContext; 1883 1884 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: start\n")); 1885 1886 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: before all clean up\n")); 1887 tdsaDumpAllFreeExp(tiRoot); 1888 1889 /* clean up UpdiscoveringExpanderList*/ 1890 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: clean discoveringExpanderList\n")); 1891 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1892 if (!TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 1893 { 1894 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1895 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 1896 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 1897 { 1898 tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList); 1899 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi)); 1900 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo)); 1901 /* putting back to the free pool */ 1902 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1903 TDLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 1904 TDLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(tdsaAllShared->freeExpanderList)); 1905 1906 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 1907 { 1908 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1909 break; 1910 } 1911 else 1912 { 1913 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1914 } 1915 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 1916 1917 // ExpanderList = ExpanderList->flink; 1918 } 1919 } 1920 else 1921 { 1922 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1923 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: empty discoveringExpanderList\n")); 1924 } 1925 1926 /* reset UpdiscoveringExpanderList */ 1927 TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList)); 1928 1929 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: after all clean up\n")); 1930 tdsaDumpAllFreeExp(tiRoot); 1931 1932 return; 1933 } 1934 1935 /***************************************************************************** 1936 *! \brief tdsaFreeAllExp 1937 * 1938 * Purpose: This function frees up expander data structures as a part of 1939 * soft reset. 1940 * 1941 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 1942 * instance. 1943 * \param onePortContext: Pointer to the portal context instance. 1944 * 1945 * \return: 1946 * None 1947 * 1948 * \note: 1949 * 1950 *****************************************************************************/ 1951 osGLOBAL void 1952 tdsaFreeAllExp( 1953 tiRoot_t *tiRoot, 1954 tdsaPortContext_t *onePortContext 1955 ) 1956 { 1957 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1958 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1959 tdList_t *ExpanderList; 1960 tdsaExpander_t *tempExpander; 1961 tdsaPortContext_t *tmpOnePortContext = onePortContext; 1962 1963 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: start\n")); 1964 1965 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: before all clean up\n")); 1966 tdsaDumpAllFreeExp(tiRoot); 1967 1968 /* clean up UpdiscoveringExpanderList*/ 1969 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: clean discoveringExpanderList\n")); 1970 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1971 if (!TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 1972 { 1973 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1974 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 1975 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 1976 { 1977 tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList); 1978 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi)); 1979 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo)); 1980 /* putting back to the free pool */ 1981 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 1982 TDLIST_DEQUEUE_THIS(&(tempExpander->linkNode)); 1983 TDLIST_ENQUEUE_AT_TAIL(&(tempExpander->linkNode), &(tdsaAllShared->freeExpanderList)); 1984 1985 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 1986 { 1987 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1988 break; 1989 } 1990 else 1991 { 1992 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 1993 } 1994 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 1995 1996 // ExpanderList = ExpanderList->flink; 1997 } 1998 } 1999 else 2000 { 2001 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 2002 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: empty discoveringExpanderList\n")); 2003 } 2004 2005 /* reset UpdiscoveringExpanderList */ 2006 TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList)); 2007 2008 return; 2009 } 2010 /***************************************************************************** 2011 *! \brief tdsaResetValidDeviceData 2012 * 2013 * Purpose: This function resets valid and valid2 field for discovered devices 2014 * in the device list. This is used only in incremental discovery. 2015 * 2016 * \param agRoot : Pointer to chip/driver Instance. 2017 * \param onePortContext: Pointer to the portal context instance. 2018 * \param oneDeviceData: Pointer to the device data. 2019 * 2020 * \return: 2021 * None 2022 * 2023 * \note: 2024 * 2025 *****************************************************************************/ 2026 osGLOBAL void 2027 tdsaResetValidDeviceData( 2028 agsaRoot_t *agRoot, 2029 tdsaPortContext_t *onePortContext 2030 ) 2031 { 2032 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 2033 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 2034 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2035 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2036 tdList_t *DeviceListList; 2037 tdsaDeviceData_t *oneDeviceData; 2038 2039 TI_DBG3(("tdsaResetValidDeviceData: start\n")); 2040 2041 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2042 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2043 { 2044 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2045 TI_DBG1(("tdsaResetValidDeviceData: empty device list\n")); 2046 } 2047 else 2048 { 2049 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2050 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2051 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2052 { 2053 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2054 oneDeviceData->valid = oneDeviceData->valid2; 2055 oneDeviceData->valid2 = agFALSE; 2056 DeviceListList = DeviceListList->flink; 2057 TI_DBG3(("tdsaResetValidDeviceData: valid %d valid2 %d\n", oneDeviceData->valid, oneDeviceData->valid2)); 2058 } 2059 } 2060 2061 return; 2062 } 2063 2064 /***************************************************************************** 2065 *! \brief tdssReportChanges 2066 * 2067 * Purpose: This function goes throuhg device list and finds out whether 2068 * a device is removed and newly added. Based on the findings, 2069 * this function notifies OS layer of the change. 2070 * 2071 * \param agRoot : Pointer to chip/driver Instance. 2072 * \param onePortContext: Pointer to the portal context instance. 2073 * 2074 * \return: 2075 * None 2076 * 2077 * \note: 2078 * 2079 *****************************************************************************/ 2080 osGLOBAL void 2081 tdssReportChanges( 2082 agsaRoot_t *agRoot, 2083 tdsaPortContext_t *onePortContext 2084 ) 2085 { 2086 tdsaDeviceData_t *oneDeviceData = agNULL; 2087 tdList_t *DeviceListList; 2088 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 2089 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 2090 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2091 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2092 bit32 added = agFALSE, removed = agFALSE; 2093 2094 TI_DBG1(("tdssReportChanges: start\n")); 2095 2096 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2097 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2098 { 2099 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2100 TI_DBG1(("tdssReportChanges: empty device list\n")); 2101 return; 2102 } 2103 else 2104 { 2105 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2106 } 2107 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2108 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2109 { 2110 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2111 TI_DBG3(("tdssReportChanges: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2112 TI_DBG3(("tdssReportChanges: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2113 if ( oneDeviceData->tdPortContext == onePortContext) 2114 { 2115 TI_DBG3(("tdssReportChanges: right portcontext\n")); 2116 if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) ) 2117 { 2118 TI_DBG3(("tdssReportChanges: same\n")); 2119 /* reset valid bit */ 2120 oneDeviceData->valid = oneDeviceData->valid2; 2121 oneDeviceData->valid2 = agFALSE; 2122 } 2123 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) ) 2124 { 2125 TI_DBG3(("tdssReportChanges: removed\n")); 2126 removed = agTRUE; 2127 /* reset valid bit */ 2128 oneDeviceData->valid = oneDeviceData->valid2; 2129 oneDeviceData->valid2 = agFALSE; 2130 /* reset NumOfFCA */ 2131 oneDeviceData->satDevData.NumOfFCA = 0; 2132 2133 if ( (oneDeviceData->registered == agTRUE) && 2134 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) 2135 || DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) ) 2136 ) 2137 { 2138 tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 2139 } 2140 else if (oneDeviceData->registered == agTRUE) 2141 { 2142 TI_DBG1(("tdssReportChanges: calling saDeregisterDeviceHandle, did %d\n", oneDeviceData->id)); 2143 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0); 2144 } 2145 2146 oneDeviceData->registered = agFALSE; 2147 2148 #ifdef REMOVED /* don't remove device from the device list. May screw up ordering of report */ 2149 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 2150 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 2151 #endif 2152 } 2153 else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) ) 2154 { 2155 TI_DBG3(("tdssReportChanges: added\n")); 2156 added = agTRUE; 2157 /* reset valid bit */ 2158 oneDeviceData->valid = oneDeviceData->valid2; 2159 oneDeviceData->valid2 = agFALSE; 2160 } 2161 else 2162 { 2163 TI_DBG6(("tdssReportChanges: else\n")); 2164 } 2165 } 2166 else 2167 { 2168 TI_DBG1(("tdssReportChanges: different portcontext\n")); 2169 } 2170 DeviceListList = DeviceListList->flink; 2171 } 2172 /* arrival or removal at once */ 2173 if (added == agTRUE) 2174 { 2175 TI_DBG3(("tdssReportChanges: added at the end\n")); 2176 #ifdef AGTIAPI_CTL 2177 if (tdsaAllShared->SASConnectTimeLimit) 2178 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDeviceChange, 2179 tiDeviceArrival); 2180 else 2181 #endif 2182 ostiInitiatorEvent( 2183 tiRoot, 2184 onePortContext->tiPortalContext, 2185 agNULL, 2186 tiIntrEventTypeDeviceChange, 2187 tiDeviceArrival, 2188 agNULL 2189 ); 2190 2191 } 2192 if (removed == agTRUE) 2193 { 2194 TI_DBG3(("tdssReportChanges: removed at the end\n")); 2195 ostiInitiatorEvent( 2196 tiRoot, 2197 onePortContext->tiPortalContext, 2198 agNULL, 2199 tiIntrEventTypeDeviceChange, 2200 tiDeviceRemoval, 2201 agNULL 2202 ); 2203 } 2204 2205 if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE) 2206 { 2207 TI_DBG1(("tdssReportChanges: missed chance to report. forced to report OK\n")); 2208 onePortContext->discovery.forcedOK = agFALSE; 2209 ostiInitiatorEvent( 2210 tiRoot, 2211 onePortContext->tiPortalContext, 2212 agNULL, 2213 tiIntrEventTypeDiscovery, 2214 tiDiscOK, 2215 agNULL 2216 ); 2217 } 2218 2219 if (added == agFALSE && removed == agFALSE) 2220 { 2221 TI_DBG3(("tdssReportChanges: the same\n")); 2222 } 2223 return; 2224 } 2225 /***************************************************************************** 2226 *! \brief tdssReportRemovals 2227 * 2228 * Purpose: This function goes through device list and removes all devices 2229 * belong to the portcontext. This function also deregiters those 2230 * devices. This function is called in case of incremental discovery 2231 * failure. 2232 * 2233 * \param agRoot : Pointer to chip/driver Instance. 2234 * \param onePortContext: Pointer to the portal context instance. 2235 * \param oneDeviceData: Pointer to the device data. 2236 * 2237 * \return: 2238 * None 2239 * 2240 * \note: 2241 * 2242 *****************************************************************************/ 2243 osGLOBAL void 2244 tdssReportRemovals( 2245 agsaRoot_t *agRoot, 2246 tdsaPortContext_t *onePortContext, 2247 bit32 flag 2248 ) 2249 { 2250 tdsaDeviceData_t *oneDeviceData = agNULL; 2251 tdList_t *DeviceListList; 2252 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 2253 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 2254 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2255 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2256 bit32 removed = agFALSE; 2257 agsaEventSource_t *eventSource; 2258 bit32 PhyID; 2259 bit32 HwAckSatus; 2260 agsaDevHandle_t *agDevHandle = agNULL; 2261 2262 TI_DBG2(("tdssReportRemovals: start\n")); 2263 /* in case nothing was registered */ 2264 PhyID = onePortContext->eventPhyID; 2265 if (tdsaAllShared->eventSource[PhyID].EventValid == agTRUE && 2266 onePortContext->RegisteredDevNums == 0 && 2267 PhyID != 0xFF 2268 ) 2269 { 2270 TI_DBG2(("tdssReportRemovals: calling saHwEventAck\n")); 2271 eventSource = &(tdsaAllShared->eventSource[PhyID].Source); 2272 HwAckSatus = saHwEventAck( 2273 agRoot, 2274 agNULL, /* agContext */ 2275 0, 2276 eventSource, /* agsaEventSource_t */ 2277 0, 2278 0 2279 ); 2280 if ( HwAckSatus != AGSA_RC_SUCCESS) 2281 { 2282 TI_DBG1(("tdssReportRemovals: failing in saHwEventAck; status %d\n", HwAckSatus)); 2283 } 2284 2285 /* toggle */ 2286 tdsaAllShared->eventSource[PhyID].EventValid = agFALSE; 2287 if (onePortContext->valid == agFALSE) 2288 { 2289 /* put device belonging to the port to freedevice list */ 2290 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2291 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2292 { 2293 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2294 if (oneDeviceData->tdPortContext == onePortContext) 2295 { 2296 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 2297 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2298 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 2299 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 2300 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2301 { 2302 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2303 break; 2304 } 2305 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2306 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2307 } 2308 else 2309 { 2310 DeviceListList = DeviceListList->flink; 2311 } 2312 } /* while */ 2313 2314 tdsaPortContextReInit(tiRoot, onePortContext); 2315 /* 2316 put all devices belonging to the onePortContext 2317 back to the free link 2318 */ 2319 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK); 2320 TDLIST_DEQUEUE_THIS(&(onePortContext->MainLink)); 2321 TDLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(tdsaAllShared->FreePortContextList)); 2322 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK); 2323 } 2324 } 2325 2326 else 2327 { 2328 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2329 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2330 { 2331 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2332 TI_DBG1(("tdssReportRemovals: 1st empty device list\n")); 2333 return; 2334 } 2335 else 2336 { 2337 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2338 } 2339 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2340 /* needs to clean up devices which were not removed in ossaDeregisterDeviceHandleCB() since port was in valid (discovery error) */ 2341 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2342 { 2343 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2344 if (oneDeviceData == agNULL) 2345 { 2346 TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n")); 2347 return; 2348 } 2349 TI_DBG2(("tdssReportRemovals: 1st loop did %d\n", oneDeviceData->id)); 2350 TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2351 TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2352 TI_DBG2(("tdssReportRemovals: valid %d\n", oneDeviceData->valid)); 2353 TI_DBG2(("tdssReportRemovals: valid2 %d\n", oneDeviceData->valid2)); 2354 TI_DBG2(("tdssReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 2355 TI_DBG2(("tdssReportRemovals: registered %d\n", oneDeviceData->registered)); 2356 if ( oneDeviceData->tdPortContext == onePortContext && oneDeviceData->valid == agFALSE && 2357 oneDeviceData->valid2 == agFALSE && oneDeviceData->registered == agFALSE 2358 ) 2359 { 2360 /* remove oneDevice from MainLink */ 2361 TI_DBG2(("tdssReportRemovals: delete from MainLink\n")); 2362 agDevHandle = oneDeviceData->agDevHandle; 2363 tdsaDeviceDataReInit(tiRoot, oneDeviceData); 2364 //save agDevHandle and tdPortContext 2365 oneDeviceData->agDevHandle = agDevHandle; 2366 oneDeviceData->tdPortContext = onePortContext; 2367 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 2368 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2369 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 2370 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 2371 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2372 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2373 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2374 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2375 { 2376 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2377 break; 2378 } 2379 else 2380 { 2381 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2382 } 2383 } 2384 else 2385 { 2386 DeviceListList = DeviceListList->flink; 2387 } 2388 } /* while */ 2389 2390 2391 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2392 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2393 { 2394 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2395 TI_DBG1(("tdssReportRemovals: 2nd empty device list\n")); 2396 return; 2397 } 2398 else 2399 { 2400 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2401 } 2402 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2403 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2404 { 2405 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2406 if (oneDeviceData == agNULL) 2407 { 2408 TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n")); 2409 return; 2410 } 2411 TI_DBG2(("tdssReportRemovals: loop did %d\n", oneDeviceData->id)); 2412 TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2413 TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2414 TI_DBG2(("tdssReportRemovals: valid %d\n", oneDeviceData->valid)); 2415 TI_DBG2(("tdssReportRemovals: valid2 %d\n", oneDeviceData->valid2)); 2416 TI_DBG2(("tdssReportRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 2417 TI_DBG2(("tdssReportRemovals: registered %d\n", oneDeviceData->registered)); 2418 if ( oneDeviceData->tdPortContext == onePortContext) 2419 { 2420 TI_DBG2(("tdssReportRemovals: right portcontext pid %d\n", onePortContext->id)); 2421 if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE) 2422 { 2423 TI_DBG2(("tdssReportRemovals: removing\n")); 2424 2425 /* notify only reported devices to OS layer*/ 2426 if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || 2427 DEVICE_IS_STP_TARGET(oneDeviceData) || 2428 DEVICE_IS_SATA_DEVICE(oneDeviceData) 2429 ) 2430 { 2431 removed = agTRUE; 2432 } 2433 2434 if ( (oneDeviceData->registered == agTRUE) && 2435 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) 2436 || DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) ) 2437 ) 2438 { 2439 /* all targets except expanders */ 2440 TI_DBG2(("tdssReportRemovals: calling tdsaAbortAll\n")); 2441 TI_DBG2(("tdssReportRemovals: did %d\n", oneDeviceData->id)); 2442 TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2443 TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2444 tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 2445 } 2446 else if (oneDeviceData->registered == agTRUE) 2447 { 2448 /* expanders */ 2449 TI_DBG1(("tdssReportRemovals: calling saDeregisterDeviceHandle, did %d\n", oneDeviceData->id)); 2450 TI_DBG2(("tdssReportRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2451 TI_DBG2(("tdssReportRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2452 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0); 2453 } 2454 2455 /* reset valid bit */ 2456 oneDeviceData->valid = agFALSE; 2457 oneDeviceData->valid2 = agFALSE; 2458 oneDeviceData->registered = agFALSE; 2459 /* reset NumOfFCA */ 2460 oneDeviceData->satDevData.NumOfFCA = 0; 2461 2462 } 2463 /* called by port invalid case */ 2464 if (flag == agTRUE) 2465 { 2466 oneDeviceData->tdPortContext = agNULL; 2467 TI_DBG1(("tdssReportRemovals: nulling-out tdPortContext; oneDeviceData did %d\n", oneDeviceData->id)); 2468 } 2469 #ifdef REMOVED /* removed */ 2470 /* directly attached SATA -> always remove it */ 2471 if (oneDeviceData->DeviceType == TD_SATA_DEVICE && 2472 oneDeviceData->directlyAttached == agTRUE) 2473 { 2474 TI_DBG1(("tdssReportRemovals: device did %d\n", oneDeviceData->id)); 2475 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 2476 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceLis)); 2477 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2478 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2479 { 2480 break; 2481 } 2482 } 2483 else 2484 { 2485 DeviceListList = DeviceListList->flink; 2486 } 2487 #endif /* REMOVED */ 2488 DeviceListList = DeviceListList->flink; 2489 } 2490 else 2491 { 2492 if (oneDeviceData->tdPortContext != agNULL) 2493 { 2494 TI_DBG2(("tdssReportRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d oneDeviceData did %d\n", 2495 oneDeviceData->tdPortContext->id, onePortContext->id, oneDeviceData->id)); 2496 } 2497 else 2498 { 2499 TI_DBG1(("tdssReportRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d oneDeviceData did %d\n", 2500 onePortContext->id, oneDeviceData->id)); 2501 } 2502 DeviceListList = DeviceListList->flink; 2503 } 2504 } 2505 2506 if (removed == agTRUE) 2507 { 2508 TI_DBG2(("tdssReportRemovals: removed at the end\n")); 2509 ostiInitiatorEvent( 2510 tiRoot, 2511 onePortContext->tiPortalContext, 2512 agNULL, 2513 tiIntrEventTypeDeviceChange, 2514 tiDeviceRemoval, 2515 agNULL 2516 ); 2517 } 2518 } /* big else */ 2519 return; 2520 } 2521 2522 /* 2523 changes valid and valid2 based on discovery type 2524 */ 2525 osGLOBAL void 2526 tdssInternalRemovals( 2527 agsaRoot_t *agRoot, 2528 tdsaPortContext_t *onePortContext 2529 ) 2530 { 2531 tdsaDeviceData_t *oneDeviceData = agNULL; 2532 tdList_t *DeviceListList; 2533 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 2534 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 2535 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2536 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2537 2538 TI_DBG2(("tdssInternalRemovals: start\n")); 2539 2540 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2541 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2542 { 2543 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2544 TI_DBG1(("tdssInternalRemovals: empty device list\n")); 2545 return; 2546 } 2547 else 2548 { 2549 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2550 } 2551 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2552 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2553 { 2554 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2555 TI_DBG3(("tdssInternalRemovals: loop did %d\n", oneDeviceData->id)); 2556 TI_DBG3(("tdssInternalRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2557 TI_DBG3(("tdssInternalRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2558 TI_DBG3(("tdssInternalRemovals: valid %d\n", oneDeviceData->valid)); 2559 TI_DBG3(("tdssInternalRemovals: valid2 %d\n", oneDeviceData->valid2)); 2560 TI_DBG3(("tdssInternalRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 2561 TI_DBG3(("tdssInternalRemovals: registered %d\n", oneDeviceData->registered)); 2562 if ( oneDeviceData->tdPortContext == onePortContext) 2563 { 2564 TI_DBG3(("tdssInternalRemovals: right portcontext pid %d\n", onePortContext->id)); 2565 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START) 2566 { 2567 TI_DBG3(("tdssInternalRemovals: incremental discovery\n")); 2568 oneDeviceData->valid2 = agFALSE; 2569 } 2570 else 2571 { 2572 TI_DBG3(("tdssInternalRemovals: full discovery\n")); 2573 oneDeviceData->valid = agFALSE; 2574 } 2575 DeviceListList = DeviceListList->flink; 2576 } 2577 else 2578 { 2579 if (oneDeviceData->tdPortContext != agNULL) 2580 { 2581 TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id)); 2582 } 2583 else 2584 { 2585 TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 2586 } 2587 DeviceListList = DeviceListList->flink; 2588 } 2589 } 2590 2591 2592 return; 2593 } 2594 2595 /* resets all valid and valid2 */ 2596 osGLOBAL void 2597 tdssDiscoveryErrorRemovals( 2598 agsaRoot_t *agRoot, 2599 tdsaPortContext_t *onePortContext 2600 ) 2601 { 2602 tdsaDeviceData_t *oneDeviceData = agNULL; 2603 tdList_t *DeviceListList; 2604 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 2605 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 2606 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2607 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2608 2609 TI_DBG1(("tdssDiscoveryErrorRemovals: start\n")); 2610 2611 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 2612 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList))) 2613 { 2614 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2615 TI_DBG1(("tdssDiscoveryErrorRemovals: empty device list\n")); 2616 return; 2617 } 2618 else 2619 { 2620 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 2621 } 2622 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2623 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2624 { 2625 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2626 TI_DBG2(("tdssDiscoveryErrorRemovals: loop did %d\n", oneDeviceData->id)); 2627 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2628 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2629 TI_DBG2(("tdssDiscoveryErrorRemovals: valid %d\n", oneDeviceData->valid)); 2630 TI_DBG2(("tdssDiscoveryErrorRemovals: valid2 %d\n", oneDeviceData->valid2)); 2631 TI_DBG2(("tdssDiscoveryErrorRemovals: directlyAttached %d\n", oneDeviceData->directlyAttached)); 2632 TI_DBG2(("tdssDiscoveryErrorRemovals: registered %d\n", oneDeviceData->registered)); 2633 if ( oneDeviceData->tdPortContext == onePortContext) 2634 { 2635 TI_DBG2(("tdssDiscoveryErrorRemovals: right portcontext pid %d\n", onePortContext->id)); 2636 oneDeviceData->valid = agFALSE; 2637 oneDeviceData->valid2 = agFALSE; 2638 /* reset NumOfFCA */ 2639 oneDeviceData->satDevData.NumOfFCA = 0; 2640 2641 if ( (oneDeviceData->registered == agTRUE) && 2642 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) 2643 || DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData) ) 2644 ) 2645 { 2646 /* all targets other than expanders */ 2647 TI_DBG2(("tdssDiscoveryErrorRemovals: calling tdsaAbortAll\n")); 2648 TI_DBG2(("tdssDiscoveryErrorRemovals: did %d\n", oneDeviceData->id)); 2649 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2650 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2651 tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 2652 } 2653 else if (oneDeviceData->registered == agTRUE) 2654 { 2655 /* expanders */ 2656 TI_DBG2(("tdssDiscoveryErrorRemovals: calling saDeregisterDeviceHandle\n")); 2657 TI_DBG2(("tdssDiscoveryErrorRemovals: did %d\n", oneDeviceData->id)); 2658 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrHi 0x%08x \n", oneDeviceData->SASAddressID.sasAddressHi)); 2659 TI_DBG2(("tdssDiscoveryErrorRemovals: sasAddrLo 0x%08x \n", oneDeviceData->SASAddressID.sasAddressLo)); 2660 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0); 2661 } 2662 2663 oneDeviceData->registered = agFALSE; 2664 DeviceListList = DeviceListList->flink; 2665 } 2666 else 2667 { 2668 if (oneDeviceData->tdPortContext != agNULL) 2669 { 2670 TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id)); 2671 } 2672 else 2673 { 2674 TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id)); 2675 } 2676 DeviceListList = DeviceListList->flink; 2677 } 2678 } 2679 2680 2681 return; 2682 } 2683 2684 /***************************************************************************** 2685 *! \brief tdsaSASDiscoverAbort 2686 * 2687 * Purpose: This function aborts on-going discovery. 2688 * 2689 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2690 * instance. 2691 * \param onePortContext: Pointer to the portal context instance. 2692 * 2693 * \return: 2694 * None 2695 * 2696 * \note: 2697 * 2698 *****************************************************************************/ 2699 /* this called when discovery is aborted 2700 aborted by whom 2701 */ 2702 osGLOBAL void 2703 tdsaSASDiscoverAbort( 2704 tiRoot_t *tiRoot, 2705 tdsaPortContext_t *onePortContext 2706 ) 2707 { 2708 2709 TI_DBG2(("tdsaSASDiscoverAbort: start\n")); 2710 TI_DBG2(("tdsaSASDiscoverAbort: pPort=%p DONE\n", onePortContext)); 2711 TI_DBG2(("tdsaSASDiscoverAbort: DiscoveryState %d\n", onePortContext->DiscoveryState)); 2712 2713 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED; 2714 /* clean up expanders data strucures; move to free exp when device is cleaned */ 2715 tdsaCleanAllExp(tiRoot, onePortContext); 2716 2717 /* unregister devices */ 2718 tdssReportRemovals(onePortContext->agRoot, 2719 onePortContext, 2720 agFALSE 2721 ); 2722 } 2723 2724 #ifdef AGTIAPI_CTL 2725 2726 STATIC void 2727 tdsaCTLNextDevice( 2728 tiRoot_t *tiRoot, 2729 tdsaPortContext_t *onePortContext, 2730 tdIORequest_t *tdIORequest, 2731 tdList_t *DeviceList); 2732 2733 STATIC void 2734 tdsaCTLIOCompleted( 2735 agsaRoot_t *agRoot, 2736 agsaIORequest_t *agIORequest, 2737 bit32 agIOStatus, 2738 bit32 agIOInfoLen, 2739 void *agParam, 2740 bit16 sspTag, 2741 bit32 agOtherInfo) 2742 { 2743 tiRoot_t *tiRoot = (tiRoot_t*) 2744 ((tdsaRootOsData_t*)agRoot->osData)->tiRoot; 2745 tdIORequestBody_t *tdIORequestBody; 2746 tdIORequest_t *tdIORequest; 2747 tdsaDeviceData_t *oneDeviceData; 2748 2749 tdIORequest = (tdIORequest_t *)agIORequest->osData; 2750 tdIORequestBody = &tdIORequest->tdIORequestBody; 2751 tdIORequestBody->ioCompleted = agTRUE; 2752 tdIORequestBody->ioStarted = agFALSE; 2753 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData; 2754 2755 TI_DBG6(("tdsaCTLIOCompleted: stat x%x len %d id %d\n", agIOStatus, 2756 agIOInfoLen, oneDeviceData->id)); 2757 2758 //if ((agIOStatus == OSSA_IO_SUCCESS) && (agIOInfoLen == 0)) 2759 /* SCSI command was completed OK, this is the normal path. */ 2760 if (agIOInfoLen) 2761 { 2762 TI_DBG6(("tdsaCTLIOCompleted: SASDevAddr 0x%x / 0x%x PhyId 0x%x WARN " 2763 "setting CTL\n", 2764 oneDeviceData->SASAddressID.sasAddressHi, 2765 oneDeviceData->SASAddressID.sasAddressLo, 2766 oneDeviceData->SASAddressID.phyIdentifier)); 2767 tdhexdump("tdsaCTLIOCompleted: response", (bit8 *)agParam, agIOInfoLen); 2768 } 2769 2770 tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest, 2771 oneDeviceData->MainLink.flink); 2772 } /* tdsaCTLIOCompleted */ 2773 2774 STATIC int 2775 tdsaCTLModeSelect( 2776 tiRoot_t *tiRoot, 2777 tiDeviceHandle_t *tiDeviceHandle, 2778 tdIORequest_t *tdIORequest) 2779 { 2780 tiIORequest_t *tiIORequest; 2781 tdsaDeviceData_t *oneDeviceData; 2782 agsaRoot_t *agRoot = agNULL; 2783 tdsaRoot_t *tdsaRoot = (tdsaRoot_t*)tiRoot->tdData; 2784 tdsaContext_t *tdsaAllShared = (tdsaContext_t*) 2785 &tdsaRoot->tdsaAllShared; 2786 agsaIORequest_t *agIORequest = agNULL; 2787 agsaDevHandle_t *agDevHandle = agNULL; 2788 agsaSASRequestBody_t *agSASRequestBody = agNULL; 2789 bit32 tiStatus; 2790 bit32 saStatus; 2791 tdIORequestBody_t *tdIORequestBody; 2792 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest; 2793 unsigned char *virtAddr; 2794 tiSgl_t agSgl; 2795 static unsigned char cdb[6] = 2796 { 2797 MODE_SELECT, 2798 PAGE_FORMAT, 2799 0, 2800 0, 2801 DR_MODE_PG_SZ 2802 }; 2803 2804 virtAddr = (unsigned char*)tdIORequest->virtAddr; 2805 virtAddr[0] = DR_MODE_PG_CODE; /* Disconnect-Reconnect mode page code */ 2806 virtAddr[1] = DR_MODE_PG_LENGTH; /* DR Mode pg length */ 2807 virtAddr[8] = tdsaAllShared->SASConnectTimeLimit >> 8; 2808 virtAddr[9] = tdsaAllShared->SASConnectTimeLimit & 0xff; 2809 2810 oneDeviceData = (tdsaDeviceData_t*)tiDeviceHandle->tdData; 2811 TI_DBG4(("tdsaCTLModeSelect: id %d\n", oneDeviceData->id)); 2812 2813 agRoot = oneDeviceData->agRoot; 2814 agDevHandle = oneDeviceData->agDevHandle; 2815 tiIORequest = &tdIORequest->tiIORequest; 2816 2817 tdIORequestBody = &tdIORequest->tdIORequestBody; 2818 2819 //tdIORequestBody->IOCompletionFunc = tdsaCTLIOCompleted;//itdssIOCompleted; 2820 tdIORequestBody->tiDevHandle = tiDeviceHandle; 2821 tdIORequestBody->IOType.InitiatorRegIO.expDataLength = DR_MODE_PG_SZ; 2822 2823 agIORequest = &tdIORequestBody->agIORequest; 2824 agIORequest->sdkData = agNULL; /* LL takes care of this */ 2825 2826 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); 2827 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq); 2828 2829 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, cdb, 6); 2830 agSSPInitiatorRequest->dataLength = DR_MODE_PG_SZ; 2831 2832 agSSPInitiatorRequest->firstBurstSize = 0; 2833 2834 tdIORequestBody->agRequestType = AGSA_SSP_INIT_WRITE; 2835 tdIORequestBody->ioStarted = agTRUE; 2836 tdIORequestBody->ioCompleted = agFALSE; 2837 2838 agSgl.lower = BIT32_TO_LEBIT32(tdIORequest->physLower32); 2839 #if (BITS_PER_LONG > 32) 2840 agSgl.upper = BIT32_TO_LEBIT32(tdIORequest->physUpper32); 2841 #else 2842 agSgl1.upper = 0; 2843 #endif 2844 agSgl.type = BIT32_TO_LEBIT32(tiSgl); 2845 agSgl.len = BIT32_TO_LEBIT32(DR_MODE_PG_SZ); 2846 2847 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */ 2848 tiStatus = itdssIOPrepareSGL(tiRoot, tdIORequestBody, &agSgl, 2849 tdIORequest->virtAddr); 2850 if (tiStatus != tiSuccess) 2851 { 2852 TI_DBG1(("tdsaCTLModeSelect: can't get SGL\n")); 2853 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle2, DR_MODE_PG_SZ); 2854 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest)); 2855 return tiError; 2856 } 2857 2858 saStatus = saSSPStart(agRoot, agIORequest, 2859 tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, 2860 AGSA_SSP_INIT_WRITE, agSASRequestBody, agNULL, 2861 &tdsaCTLIOCompleted); 2862 if (saStatus == AGSA_RC_SUCCESS) 2863 { 2864 tiStatus = tiSuccess; 2865 TI_DBG4(("tdsaCTLModeSelect: saSSPStart OK\n")); 2866 } 2867 else 2868 { 2869 tdIORequestBody->ioStarted = agFALSE; 2870 tdIORequestBody->ioCompleted = agTRUE; 2871 if (saStatus == AGSA_RC_BUSY) 2872 { 2873 tiStatus = tiBusy; 2874 TI_DBG4(("tdsaCTLModeSelect: saSSPStart busy\n")); 2875 } 2876 else 2877 { 2878 tiStatus = tiError; 2879 TI_DBG4(("tdsaCTLModeSelect: saSSPStart Error\n")); 2880 } 2881 tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest, 2882 oneDeviceData->MainLink.flink); 2883 } 2884 return tiStatus; 2885 } /* tdsaCTLModeSelect */ 2886 2887 STATIC void 2888 tdsaCTLNextDevice( 2889 tiRoot_t *tiRoot, 2890 tdsaPortContext_t *onePortContext, 2891 tdIORequest_t *tdIORequest, 2892 tdList_t *DeviceList) 2893 { 2894 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 2895 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2896 tdsaDeviceData_t *oneDeviceData; 2897 tiIntrEventType_t eventType; 2898 bit32 eventStatus; 2899 int rc; 2900 2901 /* 2902 * From the device list, returns only valid devices 2903 */ 2904 for (; DeviceList && DeviceList != &(tdsaAllShared->MainDeviceList); 2905 DeviceList = DeviceList->flink) 2906 { 2907 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceList); 2908 TI_DBG6(("tdsaCTLNextDevice: devHandle %p\n", 2909 &(oneDeviceData->tiDeviceHandle))); 2910 if (oneDeviceData->tdPortContext != onePortContext) 2911 continue; 2912 if ((oneDeviceData->discovered == agFALSE) && 2913 (oneDeviceData->registered == agTRUE) && 2914 DEVICE_IS_SSP_TARGET(oneDeviceData) && 2915 !DEVICE_IS_SSP_INITIATOR(oneDeviceData)) 2916 { 2917 oneDeviceData->discovered = agTRUE; 2918 rc = tdsaCTLModeSelect(tiRoot, &oneDeviceData->tiDeviceHandle, 2919 tdIORequest); 2920 TI_DBG1(("tdsaCTLNextDevice: ModeSelect ret %d\n", rc)); 2921 return; 2922 } 2923 } 2924 TI_DBG2(("tdsaCTLNextDevice: no more devices found\n")); 2925 2926 eventType = tdIORequest->eventType; 2927 eventStatus = tdIORequest->eventStatus; 2928 2929 /* no more devices, free the memory */ 2930 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle2, DR_MODE_PG_SZ); 2931 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest)); 2932 2933 /* send Discovery Done event */ 2934 ostiInitiatorEvent(tiRoot, onePortContext->tiPortalContext, agNULL, 2935 eventType, eventStatus, agNULL); 2936 } /* tdsaCTLNextDevice */ 2937 2938 osGLOBAL void 2939 tdsaCTLSet( 2940 tiRoot_t *tiRoot, 2941 tdsaPortContext_t *onePortContext, 2942 tiIntrEventType_t eventType, 2943 bit32 eventStatus) 2944 { 2945 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 2946 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2947 tdIORequest_t *tdIORequest; 2948 tdIORequestBody_t *tdIORequestBody; 2949 tiIORequest_t *tiIORequest; 2950 bit32 memAllocStatus; 2951 void *osMemHandle; 2952 bit32 physUpper32; 2953 bit32 physLower32; 2954 2955 TI_DBG2(("tdsaCTLSet: tiPortalContext pid %d etyp %x stat %x\n", 2956 onePortContext->id, eventType, eventStatus)); 2957 2958 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED) 2959 { 2960 TI_DBG1(("tdsaCTLSet: discovery not completed\n")); 2961 return; 2962 } 2963 2964 /* use the same memory for all valid devices */ 2965 memAllocStatus = ostiAllocMemory(tiRoot, &osMemHandle, (void **)&tdIORequest, 2966 &physUpper32, &physLower32, 8, 2967 sizeof(*tdIORequest), agTRUE); 2968 if (memAllocStatus != tiSuccess || tdIORequest == agNULL) 2969 { 2970 TI_DBG1(("tdsaCTLSet: ostiAllocMemory failed\n")); 2971 return;// tiError; 2972 } 2973 osti_memset(tdIORequest, 0, sizeof(*tdIORequest)); 2974 2975 tdIORequest->osMemHandle = osMemHandle; 2976 tdIORequest->eventType = eventType; 2977 tdIORequest->eventStatus = eventStatus; 2978 2979 tiIORequest = &tdIORequest->tiIORequest; 2980 tdIORequestBody = &tdIORequest->tdIORequestBody; 2981 /* save context if we need to abort later */ 2982 tiIORequest->tdData = tdIORequestBody; 2983 2984 tdIORequestBody->IOCompletionFunc = NULL;//itdssIOCompleted; 2985 tdIORequestBody->tiIORequest = tiIORequest; 2986 tdIORequestBody->IOType.InitiatorRegIO.expDataLength = 16; 2987 2988 tdIORequestBody->agIORequest.osData = (void *)tdIORequest; //tdIORequestBody; 2989 2990 memAllocStatus = ostiAllocMemory(tiRoot, &tdIORequest->osMemHandle2, 2991 (void **)&tdIORequest->virtAddr, 2992 &tdIORequest->physUpper32, 2993 &tdIORequest->physLower32, 2994 8, DR_MODE_PG_SZ, agFALSE); 2995 if (memAllocStatus != tiSuccess || tdIORequest == agNULL) 2996 { 2997 TI_DBG1(("tdsaCTLSet: ostiAllocMemory noncached failed\n")); 2998 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest)); 2999 return;// tiError; 3000 } 3001 3002 osti_memset(tdIORequest->virtAddr, 0, DR_MODE_PG_SZ); 3003 tdsaCTLNextDevice(tiRoot, onePortContext, tdIORequest, 3004 tdsaAllShared->MainDeviceList.flink); 3005 } /* tdsaCTLSet*/ 3006 #endif 3007 3008 /***************************************************************************** 3009 *! \brief tdsaSASDiscoverDone 3010 * 3011 * Purpose: This function called to finish up SAS discovery. 3012 * 3013 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3014 * instance. 3015 * \param onePortContext: Pointer to the portal context instance. 3016 * 3017 * \return: 3018 * None 3019 * 3020 * \note: 3021 * 3022 *****************************************************************************/ 3023 osGLOBAL void 3024 tdsaSASDiscoverDone( 3025 tiRoot_t *tiRoot, 3026 tdsaPortContext_t *onePortContext, 3027 bit32 flag 3028 ) 3029 { 3030 #ifndef SATA_ENABLE 3031 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 3032 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 3033 #endif 3034 3035 TI_DBG3(("tdsaSASDiscoverDone: start\n")); 3036 TI_DBG3(("tdsaSASDiscoverDone: pPort=%p DONE\n", onePortContext)); 3037 TI_DBG3(("tdsaSASDiscoverDone: pid %d\n", onePortContext->id)); 3038 3039 /* Set discovery status */ 3040 onePortContext->discovery.status = DISCOVERY_SAS_DONE; 3041 3042 #ifdef TD_INTERNAL_DEBUG /* debugging only */ 3043 TI_DBG3(("tdsaSASDiscoverDone: BEFORE\n")); 3044 tdsaDumpAllExp(tiRoot, onePortContext, agNULL); 3045 tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL); 3046 #endif 3047 3048 /* clean up expanders data strucures; move to free exp when device is cleaned */ 3049 tdsaCleanAllExp(tiRoot, onePortContext); 3050 3051 #ifdef TD_INTERNAL_DEBUG /* debugging only */ 3052 TI_DBG3(("tdsaSASDiscoverDone: AFTER\n")); 3053 tdsaDumpAllExp(tiRoot, onePortContext, agNULL); 3054 tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL); 3055 #endif 3056 3057 3058 /* call back to notify discovery is done */ 3059 /* SATA is NOT enbled */ 3060 #ifndef SATA_ENABLE 3061 if (onePortContext->discovery.SeenBC == agTRUE) 3062 { 3063 TI_DBG3(("tdsaSASDiscoverDone: broadcast change; discover again\n")); 3064 tdssInternalRemovals(onePortContext->agRoot, 3065 onePortContext 3066 ); 3067 3068 /* processed broadcast change */ 3069 onePortContext->discovery.SeenBC = agFALSE; 3070 if (tdsaAllShared->ResetInDiscovery != 0 && 3071 onePortContext->discovery.ResetTriggerred == agTRUE) 3072 { 3073 TI_DBG2(("tdsaSASDiscoverDone: tdsaBCTimer\n")); 3074 tdsaBCTimer(tiRoot, onePortContext); 3075 } 3076 else 3077 { 3078 tdsaDiscover( 3079 tiRoot, 3080 onePortContext, 3081 TDSA_DISCOVERY_TYPE_SAS, 3082 TDSA_DISCOVERY_OPTION_INCREMENTAL_START 3083 ); 3084 } 3085 } 3086 else 3087 { 3088 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED; 3089 3090 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 3091 { 3092 if (flag == tiSuccess) 3093 { 3094 #ifdef AGTIAPI_CTL 3095 if (tdsaAllShared->SASConnectTimeLimit) 3096 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery, 3097 tiDiscOK); 3098 else 3099 #endif 3100 ostiInitiatorEvent( 3101 tiRoot, 3102 onePortContext->tiPortalContext, 3103 agNULL, 3104 tiIntrEventTypeDiscovery, 3105 tiDiscOK, 3106 agNULL 3107 ); 3108 } 3109 else 3110 { 3111 TI_DBG1(("tdsaSASDiscoverDone: discovery failed\n")); 3112 tdssDiscoveryErrorRemovals(onePortContext->agRoot, 3113 onePortContext 3114 ); 3115 3116 ostiInitiatorEvent( 3117 tiRoot, 3118 onePortContext->tiPortalContext, 3119 agNULL, 3120 tiIntrEventTypeDiscovery, 3121 tiDiscFailed, 3122 agNULL 3123 ); 3124 } 3125 } 3126 else 3127 { 3128 if (flag == tiSuccess) 3129 { 3130 tdssReportChanges(onePortContext->agRoot, 3131 onePortContext 3132 ); 3133 } 3134 else 3135 { 3136 tdssReportRemovals(onePortContext->agRoot, 3137 onePortContext, 3138 agFALSE 3139 ); 3140 } 3141 } 3142 } 3143 #ifdef TBD 3144 /* ACKing BC */ 3145 tdsaAckBC(tiRoot, onePortContext); 3146 #endif 3147 3148 #endif 3149 3150 #ifdef SATA_ENABLE 3151 3152 if (flag == tiSuccess) 3153 { 3154 TI_DBG3(("tdsaSASDiscoverDone: calling SATA discovery\n")); 3155 /* 3156 tdsaSATAFullDiscover() or tdsaincrementalDiscover() 3157 call sata discover 3158 when sata discover is done, call ostiInitiatorEvent 3159 */ 3160 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 3161 { 3162 TI_DBG3(("tdsaSASDiscoverDone: calling FULL SATA discovery\n")); 3163 tdsaDiscover( 3164 tiRoot, 3165 onePortContext, 3166 AG_SA_DISCOVERY_TYPE_SATA, 3167 TDSA_DISCOVERY_OPTION_FULL_START 3168 ); 3169 } 3170 else 3171 { 3172 TI_DBG3(("tdsaSASDiscoverDone: calling INCREMENTAL SATA discovery\n")); 3173 tdsaDiscover( 3174 tiRoot, 3175 onePortContext, 3176 AG_SA_DISCOVERY_TYPE_SATA, 3177 TDSA_DISCOVERY_OPTION_INCREMENTAL_START 3178 ); 3179 } 3180 } 3181 else 3182 { 3183 /* error case */ 3184 TI_DBG1(("tdsaSASDiscoverDone: Error; clean up\n")); 3185 tdssDiscoveryErrorRemovals(onePortContext->agRoot, 3186 onePortContext 3187 ); 3188 3189 onePortContext->discovery.SeenBC = agFALSE; 3190 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED; 3191 ostiInitiatorEvent( 3192 tiRoot, 3193 onePortContext->tiPortalContext, 3194 agNULL, 3195 tiIntrEventTypeDiscovery, 3196 tiDiscFailed, 3197 agNULL 3198 ); 3199 } 3200 #endif 3201 return; 3202 } 3203 3204 //temp only for testing 3205 osGLOBAL void 3206 tdsaReportManInfoSend( 3207 tiRoot_t *tiRoot, 3208 tdsaDeviceData_t *oneDeviceData 3209 ) 3210 { 3211 agsaRoot_t *agRoot; 3212 3213 agRoot = oneDeviceData->agRoot; 3214 3215 TI_DBG2(("tdsaReportManInfoSend: start\n")); 3216 3217 tdSMPStart( 3218 tiRoot, 3219 agRoot, 3220 oneDeviceData, 3221 SMP_REPORT_MANUFACTURE_INFORMATION, 3222 agNULL, 3223 0, 3224 AGSA_SMP_INIT_REQ, 3225 agNULL, 3226 0 3227 ); 3228 3229 return; 3230 } 3231 3232 3233 osGLOBAL void 3234 tdsaReportManInfoRespRcvd( 3235 tiRoot_t *tiRoot, 3236 agsaRoot_t *agRoot, 3237 tdsaDeviceData_t *oneDeviceData, 3238 tdssSMPFrameHeader_t *frameHeader, 3239 agsaFrameHandle_t frameHandle 3240 ) 3241 { 3242 tdsaPortContext_t *onePortContext; 3243 tdsaDiscovery_t *discovery; 3244 3245 TI_DBG2(("tdsaReportManInfoRespRcvd: start\n")); 3246 TI_DBG2(("tdsaReportManInfoRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3247 TI_DBG2(("tdsaReportManInfoRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3248 3249 onePortContext = oneDeviceData->tdPortContext; 3250 discovery = &(onePortContext->discovery); 3251 3252 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 3253 { 3254 TI_DBG2(("tdsaReportManInfoRespRcvd: SMP accepted\n")); 3255 } 3256 else 3257 { 3258 TI_DBG1(("tdsaReportManInfoRespRcvd: SMP NOT accepted; fn result 0x%x\n", frameHeader->smpFunctionResult)); 3259 } 3260 3261 TI_DBG2(("tdsaReportManInfoRespRcvd: discovery retries %d\n", discovery->retries)); 3262 discovery->retries++; 3263 3264 if (discovery->retries >= DISCOVERY_RETRIES) 3265 { 3266 TI_DBG1(("tdsaReportManInfoRespRcvd: retries are over\n")); 3267 discovery->retries = 0; 3268 /* failed the discovery */ 3269 } 3270 else 3271 { 3272 TI_DBG1(("tdsaReportManInfoRespRcvd: keep retrying\n")); 3273 // start timer 3274 tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData); 3275 } 3276 3277 return; 3278 } 3279 3280 //end temp only for testing 3281 3282 /***************************************************************************** 3283 *! \brief tdsaReportGeneralSend 3284 * 3285 * Purpose: This function sends Report General SMP to a device. 3286 * 3287 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3288 * instance. 3289 * \param oneDeviceData: Pointer to the device data. 3290 * 3291 * \return: 3292 * None 3293 * 3294 * \note: 3295 * 3296 *****************************************************************************/ 3297 osGLOBAL void 3298 tdsaReportGeneralSend( 3299 tiRoot_t *tiRoot, 3300 tdsaDeviceData_t *oneDeviceData 3301 ) 3302 { 3303 agsaRoot_t *agRoot; 3304 3305 agRoot = oneDeviceData->agRoot; 3306 3307 TI_DBG3(("tdsaReportGeneralSend: start\n")); 3308 3309 tdSMPStart( 3310 tiRoot, 3311 agRoot, 3312 oneDeviceData, 3313 SMP_REPORT_GENERAL, 3314 agNULL, 3315 0, 3316 AGSA_SMP_INIT_REQ, 3317 agNULL, 3318 0 3319 ); 3320 3321 return; 3322 } 3323 3324 /***************************************************************************** 3325 *! \brief tdsaReportGeneralRespRcvd 3326 * 3327 * Purpose: This function processes Report General response. 3328 * 3329 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3330 * instance. 3331 * \param agRoot: Pointer to chip/driver Instance. 3332 * \param oneDeviceData: Pointer to the device data. 3333 * \param frameHeader: Pointer to SMP frame header. 3334 * \param frameHandle: A Handle used to refer to the response frame 3335 * 3336 * \return: 3337 * None 3338 * 3339 * \note: 3340 * 3341 *****************************************************************************/ 3342 osGLOBAL void 3343 tdsaReportGeneralRespRcvd( 3344 tiRoot_t *tiRoot, 3345 agsaRoot_t *agRoot, 3346 agsaIORequest_t *agIORequest, 3347 tdsaDeviceData_t *oneDeviceData, 3348 tdssSMPFrameHeader_t *frameHeader, 3349 agsaFrameHandle_t frameHandle 3350 ) 3351 { 3352 smpRespReportGeneral_t tdSMPReportGeneralResp; 3353 smpRespReportGeneral_t *ptdSMPReportGeneralResp; 3354 tdsaExpander_t *oneExpander; 3355 tdsaPortContext_t *onePortContext; 3356 tdsaDiscovery_t *discovery; 3357 #ifdef REMOVED 3358 bit32 i; 3359 #endif 3360 #ifndef DIRECT_SMP 3361 tdssSMPRequestBody_t *tdSMPRequestBody; 3362 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData; 3363 #endif 3364 3365 TI_DBG3(("tdsaReportGeneralRespRcvd: start\n")); 3366 TI_DBG3(("tdsaReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3367 TI_DBG3(("tdsaReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3368 ptdSMPReportGeneralResp = &tdSMPReportGeneralResp; 3369 osti_memset(&tdSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t)); 3370 #ifdef DIRECT_SMP 3371 saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t)); 3372 #else 3373 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t)); 3374 #endif 3375 3376 //tdhexdump("tdsaReportGeneralRespRcvd", (bit8 *)ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t)); 3377 #ifndef DIRECT_SMP 3378 ostiFreeMemory( 3379 tiRoot, 3380 tdSMPRequestBody->IndirectSMPReqosMemHandle, 3381 tdSMPRequestBody->IndirectSMPReqLen 3382 ); 3383 ostiFreeMemory( 3384 tiRoot, 3385 tdSMPRequestBody->IndirectSMPResposMemHandle, 3386 tdSMPRequestBody->IndirectSMPRespLen 3387 ); 3388 #endif 3389 3390 onePortContext = oneDeviceData->tdPortContext; 3391 discovery = &(onePortContext->discovery); 3392 3393 if (onePortContext->valid == agFALSE) 3394 { 3395 TI_DBG1(("tdsaReportGeneralRespRcvd: aborting discovery\n")); 3396 tdsaSASDiscoverAbort(tiRoot, onePortContext); 3397 return; 3398 } 3399 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 3400 { 3401 oneDeviceData->numOfPhys = (bit8) ptdSMPReportGeneralResp->numOfPhys; 3402 oneExpander = oneDeviceData->tdExpander; 3403 oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(ptdSMPReportGeneralResp); 3404 #ifdef REMOVED 3405 for ( i = 0; i < oneDeviceData->numOfPhys; i++ ) 3406 { 3407 oneExpander->currentIndex[i] = 0; 3408 } 3409 #endif 3410 oneExpander->configReserved = 0; 3411 oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(ptdSMPReportGeneralResp) ? 1 : 0; 3412 oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(ptdSMPReportGeneralResp) ? 1 : 0; 3413 TI_DBG3(("tdsaReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n", 3414 oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex)); 3415 TI_DBG3(("tdsaReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n", 3416 oneExpander->configRouteTable, oneExpander->configuring)); 3417 if (oneExpander->configuring == 1) 3418 { 3419 discovery->retries++; 3420 if (discovery->retries >= DISCOVERY_RETRIES) 3421 { 3422 TI_DBG1(("tdsaReportGeneralRespRcvd: retries are over\n")); 3423 discovery->retries = 0; 3424 /* failed the discovery */ 3425 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3426 } 3427 else 3428 { 3429 TI_DBG1(("tdsaReportGeneralRespRcvd: keep retrying\n")); 3430 // start timer for sending ReportGeneral 3431 tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData); 3432 } 3433 } 3434 else 3435 { 3436 discovery->retries = 0; 3437 tdsaDiscoverSend(tiRoot, oneDeviceData); 3438 } 3439 } 3440 else 3441 { 3442 TI_DBG1(("tdsaReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery\n", frameHeader->smpFunctionResult)); 3443 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3444 } 3445 return; 3446 } 3447 3448 3449 /***************************************************************************** 3450 *! \brief tdsaDiscoverSend 3451 * 3452 * Purpose: This function sends Discovery SMP to a device. 3453 * 3454 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3455 * instance. 3456 * \param oneDeviceData: Pointer to the device data. 3457 * 3458 * \return: 3459 * None 3460 * 3461 * \note: 3462 * 3463 *****************************************************************************/ 3464 osGLOBAL void 3465 tdsaDiscoverSend( 3466 tiRoot_t *tiRoot, 3467 tdsaDeviceData_t *oneDeviceData 3468 ) 3469 { 3470 agsaRoot_t *agRoot; 3471 tdsaExpander_t *oneExpander; 3472 smpReqDiscover_t smpDiscoverReq; 3473 3474 TI_DBG3(("tdsaDiscoverSend: start\n")); 3475 TI_DBG3(("tdsaDiscoverSend: device %p did %d\n", oneDeviceData, oneDeviceData->id)); 3476 agRoot = oneDeviceData->agRoot; 3477 oneExpander = oneDeviceData->tdExpander; 3478 TI_DBG3(("tdsaDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId)); 3479 3480 3481 osti_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t)); 3482 3483 smpDiscoverReq.reserved1 = 0; 3484 smpDiscoverReq.reserved2 = 0; 3485 smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId; 3486 smpDiscoverReq.reserved3 = 0; 3487 3488 3489 tdSMPStart( 3490 tiRoot, 3491 agRoot, 3492 oneDeviceData, 3493 SMP_DISCOVER, 3494 (bit8 *)&smpDiscoverReq, 3495 sizeof(smpReqDiscover_t), 3496 AGSA_SMP_INIT_REQ, 3497 agNULL, 3498 0 3499 ); 3500 return; 3501 } 3502 3503 3504 /***************************************************************************** 3505 *! \brief tdsaDiscoverRespRcvd 3506 * 3507 * Purpose: This function processes Discovery response. 3508 * 3509 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3510 * instance. 3511 * \param agRoot: Pointer to chip/driver Instance. 3512 * \param oneDeviceData: Pointer to the device data. 3513 * \param frameHeader: Pointer to SMP frame header. 3514 * \param frameHandle: A Handle used to refer to the response frame 3515 * 3516 * \return: 3517 * None 3518 * 3519 * \note: 3520 * 3521 *****************************************************************************/ 3522 osGLOBAL void 3523 tdsaDiscoverRespRcvd( 3524 tiRoot_t *tiRoot, 3525 agsaRoot_t *agRoot, 3526 agsaIORequest_t *agIORequest, 3527 tdsaDeviceData_t *oneDeviceData, 3528 tdssSMPFrameHeader_t *frameHeader, 3529 agsaFrameHandle_t frameHandle 3530 ) 3531 { 3532 smpRespDiscover_t *ptdSMPDiscoverResp; 3533 tdsaPortContext_t *onePortContext; 3534 tdsaExpander_t *oneExpander; 3535 tdsaDiscovery_t *discovery; 3536 #ifndef DIRECT_SMP 3537 tdssSMPRequestBody_t *tdSMPRequestBody; 3538 #endif 3539 3540 TI_DBG3(("tdsaDiscoverRespRcvd: start\n")); 3541 TI_DBG3(("tdsaDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 3542 TI_DBG3(("tdsaDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 3543 3544 3545 onePortContext = oneDeviceData->tdPortContext; 3546 oneExpander = oneDeviceData->tdExpander; 3547 discovery = &(onePortContext->discovery); 3548 #ifndef DIRECT_SMP 3549 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData; 3550 #endif 3551 3552 if (onePortContext->valid == agFALSE) 3553 { 3554 TI_DBG1(("tdsaDiscoverRespRcvd: aborting discovery\n")); 3555 tdsaSASDiscoverAbort(tiRoot, onePortContext); 3556 return; 3557 } 3558 ptdSMPDiscoverResp = &(discovery->SMPDiscoverResp); 3559 #ifdef DIRECT_SMP 3560 saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 3561 #else 3562 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 3563 #endif 3564 //tdhexdump("tdsaDiscoverRespRcvd", (bit8 *)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 3565 3566 #ifndef DIRECT_SMP 3567 ostiFreeMemory( 3568 tiRoot, 3569 tdSMPRequestBody->IndirectSMPReqosMemHandle, 3570 tdSMPRequestBody->IndirectSMPReqLen 3571 ); 3572 ostiFreeMemory( 3573 tiRoot, 3574 tdSMPRequestBody->IndirectSMPResposMemHandle, 3575 tdSMPRequestBody->IndirectSMPRespLen 3576 ); 3577 #endif 3578 3579 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 3580 { 3581 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3582 { 3583 tdsaSASUpStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp); 3584 } 3585 else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3586 { 3587 tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp); 3588 } 3589 else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 3590 { 3591 /* not done with configuring routing 3592 1. set the timer 3593 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 3594 */ 3595 TI_DBG2(("tdsaDiscoverRespRcvd: still configuring routing; setting timer\n")); 3596 TI_DBG2(("tdsaDiscoverRespRcvd: onePortContext %p oneDeviceData %p ptdSMPDiscoverResp %p\n", onePortContext, oneDeviceData, ptdSMPDiscoverResp)); 3597 tdhexdump("tdsaDiscoverRespRcvd", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 3598 3599 tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp); 3600 } 3601 else 3602 { 3603 /* nothing */ 3604 } 3605 } 3606 else if (frameHeader->smpFunctionResult == PHY_VACANT) 3607 { 3608 TI_DBG3(("tdsaDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", 3609 oneExpander->discoveringPhyId)); 3610 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 3611 { 3612 tdsaSASUpStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander); 3613 } 3614 else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 3615 { 3616 tdsaSASDownStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander); 3617 } 3618 else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 3619 { 3620 /* not done with configuring routing 3621 1. set the timer 3622 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 3623 */ 3624 TI_DBG1(("tdsaDiscoverRespRcvd: still configuring routing; setting timer\n")); 3625 TI_DBG1(("tdsaDiscoverRespRcvd: onePortContext %p oneDeviceData %p ptdSMPDiscoverResp %p\n", onePortContext, oneDeviceData, ptdSMPDiscoverResp)); 3626 tdhexdump("tdsaDiscoverRespRcvd", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 3627 3628 tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp); 3629 } 3630 } 3631 else 3632 { 3633 TI_DBG1(("tdsaDiscoverRespRcvd: Discovery Error SMP function return result error=%x\n", 3634 frameHeader->smpFunctionResult)); 3635 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3636 } 3637 return; 3638 } 3639 3640 /***************************************************************************** 3641 *! \brief tdsaSASUpStreamDiscoverExpanderPhy 3642 * 3643 * Purpose: This function actully does upstream traverse and finds out detailed 3644 * information about topology. 3645 * 3646 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 3647 * instance. 3648 * \param onePortContext: Pointer to the portal context instance. 3649 * \param oneExpander: Pointer to the expander data. 3650 * \param pDiscoverResp: Pointer to the Discovery SMP respsonse. 3651 * 3652 * \return: 3653 * None 3654 * 3655 * \note: 3656 * 3657 *****************************************************************************/ 3658 osGLOBAL void 3659 tdsaSASUpStreamDiscoverExpanderPhy( 3660 tiRoot_t *tiRoot, 3661 tdsaPortContext_t *onePortContext, 3662 tdsaExpander_t *oneExpander, 3663 smpRespDiscover_t *pDiscoverResp 3664 ) 3665 { 3666 tdsaDeviceData_t *oneDeviceData; 3667 tdsaDeviceData_t *AttachedDevice = agNULL; 3668 tdsaExpander_t *AttachedExpander; 3669 agsaSASIdentify_t sasIdentify; 3670 bit8 connectionRate; 3671 bit32 attachedSasHi, attachedSasLo; 3672 tdsaSASSubID_t agSASSubID; 3673 3674 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: start\n")); 3675 if (onePortContext->valid == agFALSE) 3676 { 3677 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: aborting discovery\n")); 3678 tdsaSASDiscoverAbort(tiRoot, onePortContext); 3679 return; 3680 } 3681 3682 oneDeviceData = oneExpander->tdDevice; 3683 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 3684 oneExpander->discoveringPhyId, 3685 oneDeviceData->SASAddressID.sasAddressHi, 3686 oneDeviceData->SASAddressID.sasAddressLo)); 3687 TI_DBG3((" Attached device: %s\n", 3688 ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 3689 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 3690 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 3691 3692 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 3693 { 3694 TI_DBG3((" SAS address : %08x-%08x\n", 3695 DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 3696 DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 3697 TI_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 3698 TI_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 3699 TI_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 3700 TI_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 3701 TI_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 3702 TI_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 3703 TI_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 3704 TI_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 3705 TI_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 3706 } 3707 /* end for debugging */ 3708 3709 /* for debugging */ 3710 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 3711 { 3712 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 3713 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 3714 tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 3715 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3716 return; 3717 } 3718 3719 /* saving routing attribute for non self-configuring expanders */ 3720 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 3721 3722 /* for debugging */ 3723 // dumpRoutingAttributes(tiRoot, oneExpander, pDiscoverResp->phyIdentifier); 3724 3725 if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE ) 3726 { 3727 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n")); 3728 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 3729 { 3730 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device\n")); 3731 3732 /* discovery error */ 3733 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 3734 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 3735 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 3736 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 3737 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 3738 3739 /* (2.1.3) discovery done */ 3740 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3741 return; 3742 } 3743 } 3744 else 3745 { 3746 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n")); 3747 3748 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 3749 { 3750 /* Setup sasIdentify for the attached device */ 3751 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 3752 sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70); 3753 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 3754 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 3755 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 3756 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 3757 3758 /* incremental discovery */ 3759 agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 3760 agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 3761 agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 3762 agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 3763 3764 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 3765 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 3766 3767 /* If the phy has subtractive routing attribute */ 3768 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 3769 { 3770 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_ROUTING_SUBTRACTIVE\n")); 3771 /* Setup upstream phys */ 3772 tdsaSASExpanderUpStreamPhyAdd(tiRoot, oneExpander, (bit8) pDiscoverResp->attachedPhyIdentifier); 3773 /* If the expander already has an upsteam device set up */ 3774 if (oneExpander->hasUpStreamDevice == agTRUE) 3775 { 3776 /* If the sas address doesn't match */ 3777 if ( ((oneExpander->upStreamSASAddressHi != attachedSasHi) || 3778 (oneExpander->upStreamSASAddressLo != attachedSasLo)) && 3779 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 3780 DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 3781 ) 3782 { 3783 /* TODO: discovery error, callback */ 3784 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address\n")); 3785 /* call back to notify discovery error */ 3786 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 3787 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 3788 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 3789 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 3790 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 3791 /* discovery done */ 3792 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3793 } 3794 } 3795 else 3796 { 3797 /* Setup SAS address for up stream device */ 3798 oneExpander->hasUpStreamDevice = agTRUE; 3799 oneExpander->upStreamSASAddressHi = attachedSasHi; 3800 oneExpander->upStreamSASAddressLo = attachedSasLo; 3801 3802 if ( (onePortContext->sasLocalAddressHi != attachedSasHi) 3803 || (onePortContext->sasLocalAddressLo != attachedSasLo) ) 3804 { 3805 /* Find the device from the discovered list */ 3806 AttachedDevice = tdsaPortSASDeviceFind(tiRoot, onePortContext, attachedSasLo, attachedSasHi); 3807 /* If the device has been discovered before */ 3808 if ( AttachedDevice != agNULL) 3809 { 3810 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Seen This Device Before\n")); 3811 /* If attached device is an edge expander */ 3812 if ( AttachedDevice->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) 3813 { 3814 /* The attached device is an expander */ 3815 AttachedExpander = AttachedDevice->tdExpander; 3816 /* If the two expanders are the root of the two edge expander sets */ 3817 if ( (AttachedExpander->upStreamSASAddressHi == 3818 DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 3819 && (AttachedExpander->upStreamSASAddressLo == 3820 DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo)) ) 3821 { 3822 /* Setup upstream expander for the pExpander */ 3823 oneExpander->tdUpStreamExpander = AttachedExpander; 3824 } 3825 /* If the two expanders are not the root of the two edge expander sets */ 3826 else 3827 { 3828 /* TODO: loop found, discovery error, callback */ 3829 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error loop detection\n")); 3830 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 3831 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 3832 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 3833 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 3834 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 3835 /* discovery done */ 3836 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3837 } 3838 } 3839 /* If attached device is not an edge expander */ 3840 else 3841 { 3842 /*TODO: should not happen, ASSERT */ 3843 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!\n")); 3844 } 3845 } 3846 /* If the device has not been discovered before */ 3847 else 3848 { 3849 /* Add the device */ 3850 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: New device\n")); 3851 /* read minimum rate from the configuration 3852 onePortContext->LinkRate is SPC's local link rate 3853 */ 3854 connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp))); 3855 TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: link rate 0x%x\n", onePortContext->LinkRate)); 3856 TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 3857 TI_DBG3(("siSASUpStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 3858 //hhhhhhhh 3859 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 3860 { 3861 /* incremental discovery */ 3862 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 3863 { 3864 AttachedDevice = tdsaPortSASDeviceAdd( 3865 tiRoot, 3866 onePortContext, 3867 sasIdentify, 3868 agFALSE, 3869 connectionRate, 3870 IT_NEXUS_TIMEOUT, 3871 0, 3872 STP_DEVICE_TYPE, 3873 oneDeviceData, 3874 pDiscoverResp->phyIdentifier 3875 ); 3876 } 3877 else 3878 { 3879 /* incremental discovery */ 3880 AttachedDevice = tdsaFindRegNValid( 3881 onePortContext->agRoot, 3882 onePortContext, 3883 &agSASSubID 3884 ); 3885 /* not registered and not valid; add this*/ 3886 if (AttachedDevice == agNULL) 3887 { 3888 AttachedDevice = tdsaPortSASDeviceAdd( 3889 tiRoot, 3890 onePortContext, 3891 sasIdentify, 3892 agFALSE, 3893 connectionRate, 3894 IT_NEXUS_TIMEOUT, 3895 0, 3896 STP_DEVICE_TYPE, 3897 oneDeviceData, 3898 pDiscoverResp->phyIdentifier 3899 ); 3900 } 3901 } 3902 } 3903 else 3904 { 3905 /* incremental discovery */ 3906 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 3907 { 3908 AttachedDevice = tdsaPortSASDeviceAdd( 3909 tiRoot, 3910 onePortContext, 3911 sasIdentify, 3912 agFALSE, 3913 connectionRate, 3914 IT_NEXUS_TIMEOUT, 3915 0, 3916 SAS_DEVICE_TYPE, 3917 oneDeviceData, 3918 pDiscoverResp->phyIdentifier 3919 ); 3920 } 3921 else 3922 { 3923 /* incremental discovery */ 3924 AttachedDevice = tdsaFindRegNValid( 3925 onePortContext->agRoot, 3926 onePortContext, 3927 &agSASSubID 3928 ); 3929 /* not registered and not valid; add this*/ 3930 if (AttachedDevice == agNULL) 3931 { 3932 AttachedDevice = tdsaPortSASDeviceAdd( 3933 tiRoot, 3934 onePortContext, 3935 sasIdentify, 3936 agFALSE, 3937 connectionRate, 3938 IT_NEXUS_TIMEOUT, 3939 0, 3940 SAS_DEVICE_TYPE, 3941 oneDeviceData, 3942 pDiscoverResp->phyIdentifier 3943 ); 3944 } 3945 } 3946 } 3947 /* If the device is added successfully */ 3948 if ( AttachedDevice != agNULL) 3949 { 3950 3951 /* (3.1.2.3.2.3.2.1) callback about new device */ 3952 if ( DISCRSP_IS_SSP_TARGET(pDiscoverResp) 3953 || DISCRSP_IS_SSP_INITIATOR(pDiscoverResp) 3954 || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) 3955 || DISCRSP_IS_SMP_INITIATOR(pDiscoverResp) ) 3956 { 3957 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n", 3958 attachedSasHi, attachedSasLo)); 3959 } 3960 else 3961 { 3962 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n")); 3963 } 3964 /* If the attached device is an expander */ 3965 if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 3966 || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) ) 3967 { 3968 /* Allocate an expander data structure */ 3969 AttachedExpander = tdssSASDiscoveringExpanderAlloc( 3970 tiRoot, 3971 onePortContext, 3972 AttachedDevice 3973 ); 3974 3975 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander)); 3976 /* If allocate successfully */ 3977 if ( AttachedExpander != agNULL) 3978 { 3979 /* Add the pAttachedExpander to discovering list */ 3980 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander); 3981 /* Setup upstream expander for the pExpander */ 3982 oneExpander->tdUpStreamExpander = AttachedExpander; 3983 } 3984 /* If failed to allocate */ 3985 else 3986 { 3987 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n")); 3988 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 3989 } 3990 } 3991 /* If the attached device is an end device */ 3992 else 3993 { 3994 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found end device\n")); 3995 /* LP2006-05-26 added upstream device to the newly found device */ 3996 AttachedDevice->tdExpander = oneExpander; 3997 oneExpander->tdUpStreamExpander = agNULL; 3998 } 3999 } 4000 else 4001 { 4002 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to add a device\n")); 4003 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4004 } 4005 } 4006 } 4007 } 4008 } /* substractive routing */ 4009 } 4010 } 4011 4012 4013 oneExpander->discoveringPhyId ++; 4014 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4015 { 4016 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 4017 { 4018 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n")); 4019 /* continue discovery for the next phy */ 4020 tdsaDiscoverSend(tiRoot, oneDeviceData); 4021 } 4022 else 4023 { 4024 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n")); 4025 4026 /* remove the expander from the discovering list */ 4027 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander); 4028 /* continue upstream discovering */ 4029 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 4030 } 4031 } 4032 else 4033 { 4034 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 4035 4036 } 4037 4038 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 4039 4040 return; 4041 } 4042 4043 // for debugging only 4044 osGLOBAL tdsaExpander_t * 4045 tdsaFindUpStreamConfigurableExp(tiRoot_t *tiRoot, 4046 tdsaExpander_t *oneExpander) 4047 { 4048 tdsaExpander_t *ret=agNULL; 4049 tdsaExpander_t *UpsreamExpander = oneExpander->tdUpStreamExpander; 4050 4051 TI_DBG3(("tdsaFindUpStreamConfigurableExp: start\n")); 4052 TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4053 TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4054 4055 4056 if (UpsreamExpander) 4057 { 4058 TI_DBG3(("tdsaFindUpStreamConfigurableExp: NO upsream expander\n")); 4059 } 4060 else 4061 { 4062 while (UpsreamExpander) 4063 { 4064 TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrHi 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressHi)); 4065 TI_DBG3(("tdsaFindUpStreamConfigurableExp: exp addrLo 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressLo)); 4066 4067 UpsreamExpander = UpsreamExpander->tdUpStreamExpander; 4068 } 4069 } 4070 return ret; 4071 } 4072 4073 /***************************************************************************** 4074 *! \brief tdsaSASUpStreamDiscoverExpanderPhySkip 4075 * 4076 * Purpose: This function skips a phy which returned PHY_VACANT in SMP 4077 * response in upstream 4078 * 4079 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4080 * instance. 4081 * \param onePortContext: Pointer to the portal context instance. 4082 * \param oneExpander: Pointer to the expander data. 4083 * 4084 * \return: 4085 * None 4086 * 4087 * \note: 4088 * 4089 *****************************************************************************/ 4090 osGLOBAL void 4091 tdsaSASUpStreamDiscoverExpanderPhySkip( 4092 tiRoot_t *tiRoot, 4093 tdsaPortContext_t *onePortContext, 4094 tdsaExpander_t *oneExpander 4095 ) 4096 { 4097 tdsaDeviceData_t *oneDeviceData; 4098 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: start\n")); 4099 oneDeviceData = oneExpander->tdDevice; 4100 4101 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 4102 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 4103 4104 oneExpander->discoveringPhyId ++; 4105 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM) 4106 { 4107 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 4108 { 4109 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 4110 /* continue discovery for the next phy */ 4111 tdsaDiscoverSend(tiRoot, oneDeviceData); 4112 } 4113 else 4114 { 4115 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: No More Phys\n")); 4116 4117 /* remove the expander from the discovering list */ 4118 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander); 4119 /* continue upstream discovering */ 4120 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 4121 } 4122 } 4123 else 4124 { 4125 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status)); 4126 4127 } 4128 4129 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 4130 4131 4132 return; 4133 } 4134 4135 4136 // for debugging only 4137 osGLOBAL tdsaExpander_t * 4138 tdsaFindDownStreamConfigurableExp(tiRoot_t *tiRoot, 4139 tdsaExpander_t *oneExpander) 4140 { 4141 tdsaExpander_t *ret=agNULL; 4142 tdsaExpander_t *DownsreamExpander = oneExpander->tdCurrentDownStreamExpander; 4143 4144 TI_DBG3(("tdsaFindDownStreamConfigurableExp: start\n")); 4145 TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4146 TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4147 4148 4149 if (DownsreamExpander) 4150 { 4151 TI_DBG3(("tdsaFindDownStreamConfigurableExp: NO downsream expander\n")); 4152 } 4153 else 4154 { 4155 while (DownsreamExpander) 4156 { 4157 TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrHi 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressHi)); 4158 TI_DBG3(("tdsaFindDownStreamConfigurableExp: exp addrLo 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressLo)); 4159 4160 DownsreamExpander = DownsreamExpander->tdCurrentDownStreamExpander; 4161 } 4162 } 4163 return ret; 4164 } 4165 4166 // for debugging only 4167 osGLOBAL void 4168 dumpRoutingAttributes( 4169 tiRoot_t *tiRoot, 4170 tdsaExpander_t *oneExpander, 4171 bit8 phyID 4172 ) 4173 { 4174 bit32 i; 4175 4176 TI_DBG3(("dumpRoutingAttributes: start\n")); 4177 TI_DBG3(("dumpRoutingAttributes: phyID %d\n", phyID)); 4178 TI_DBG3(("dumpRoutingAttributes: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4179 TI_DBG3(("dumpRoutingAttributes: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4180 4181 for(i=0;i <= ((bit32)phyID + 1); i++) 4182 { 4183 TI_DBG3(("dumpRoutingAttributes: index %d routing attribute %d\n", i, oneExpander->routingAttribute[i])); 4184 } 4185 return; 4186 } 4187 4188 /***************************************************************************** 4189 *! \brief tdsaDumpAllExp 4190 * 4191 * Purpose: This function prints out all expanders seen by discovery. 4192 * 4193 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4194 * instance. 4195 * \param onePortContext: Pointer to the portal context instance. 4196 * \param oneExpander: Pointer to the expander data. 4197 * 4198 * \return: 4199 * None 4200 * 4201 * \note: For debugging only 4202 * 4203 *****************************************************************************/ 4204 osGLOBAL void 4205 tdsaDumpAllExp( 4206 tiRoot_t *tiRoot, 4207 tdsaPortContext_t *onePortContext, 4208 tdsaExpander_t *oneExpander 4209 ) 4210 { 4211 #if 0 /* for debugging only */ 4212 tdList_t *ExpanderList; 4213 tdsaExpander_t *tempExpander; 4214 tdsaExpander_t *UpsreamExpander; 4215 tdsaExpander_t *DownsreamExpander; 4216 tdsaPortContext_t *tmpOnePortContext = onePortContext; 4217 4218 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: start\n")); 4219 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: onePortcontext %p oneExpander %p\n", onePortContext, oneExpander)); 4220 4221 /* debugging */ 4222 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 4223 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4224 { 4225 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 4226 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: empty discoveringExpanderList\n")); 4227 return; 4228 } 4229 else 4230 { 4231 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 4232 } 4233 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink; 4234 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList)) 4235 { 4236 tempExpander = TDLIST_OBJECT_BASE(tdsaExpander_t, linkNode, ExpanderList); 4237 UpsreamExpander = tempExpander->tdUpStreamExpander; 4238 DownsreamExpander = tempExpander->tdCurrentDownStreamExpander; 4239 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: expander id %d\n", tempExpander->id)); 4240 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi)); 4241 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo)); 4242 if (UpsreamExpander) 4243 { 4244 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Up exp addrHi 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressHi)); 4245 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Up exp addrLo 0x%08x\n", UpsreamExpander->tdDevice->SASAddressID.sasAddressLo)); 4246 } 4247 else 4248 { 4249 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Upstream expander\n")); 4250 } 4251 if (DownsreamExpander) 4252 { 4253 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Down exp addrHi 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressHi)); 4254 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: Down exp addrLo 0x%08x\n", DownsreamExpander->tdDevice->SASAddressID.sasAddressLo)); 4255 } 4256 else 4257 { 4258 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Downstream expander\n")); 4259 } 4260 4261 ExpanderList = ExpanderList->flink; 4262 } 4263 #endif 4264 return; 4265 4266 } 4267 4268 /***************************************************************************** 4269 *! \brief tdsaDumpAllUpExp 4270 * 4271 * Purpose: This function prints out all upstream expanders seen by discovery. 4272 * 4273 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4274 * instance. 4275 * \param onePortContext: Pointer to the portal context instance. 4276 * \param oneExpander: Pointer to the expander data. 4277 * 4278 * \return: 4279 * None 4280 * 4281 * \note: For debugging only 4282 * 4283 *****************************************************************************/ 4284 osGLOBAL void 4285 tdsaDumpAllUpExp( 4286 tiRoot_t *tiRoot, 4287 tdsaPortContext_t *onePortContext, 4288 tdsaExpander_t *oneExpander 4289 ) 4290 { 4291 return; 4292 4293 } 4294 4295 /***************************************************************************** 4296 *! \brief tdsaDumpAllFreeExp 4297 * 4298 * Purpose: This function prints out all free expanders. 4299 * 4300 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4301 * instance. 4302 * \return: 4303 * None 4304 * 4305 * \note: For debugging only 4306 * 4307 *****************************************************************************/ 4308 osGLOBAL void 4309 tdsaDumpAllFreeExp( 4310 tiRoot_t *tiRoot 4311 ) 4312 { 4313 4314 return; 4315 } 4316 4317 /***************************************************************************** 4318 *! \brief tdsaDuplicateConfigSASAddr 4319 * 4320 * Purpose: This function finds whether SAS address has added to the routing 4321 * table of expander or not. 4322 * 4323 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4324 * instance. 4325 * \param oneExpander: Pointer to the expander data. 4326 * \param configSASAddressHi: Upper 4 byte of SAS address. 4327 * \param configSASAddressLo: Lower 4 byte of SAS address. 4328 * 4329 * \return: 4330 * agTRUE No need to add configSASAddress. 4331 * agFALSE Need to add configSASAddress. 4332 * 4333 * \note: 4334 * 4335 *****************************************************************************/ 4336 osGLOBAL bit32 4337 tdsaDuplicateConfigSASAddr( 4338 tiRoot_t *tiRoot, 4339 tdsaExpander_t *oneExpander, 4340 bit32 configSASAddressHi, 4341 bit32 configSASAddressLo 4342 ) 4343 { 4344 bit32 i; 4345 bit32 ret = agFALSE; 4346 TI_DBG3(("tdsaDuplicateConfigSASAddr: start\n")); 4347 4348 if (oneExpander == agNULL) 4349 { 4350 TI_DBG3(("tdsaDuplicateConfigSASAddr: NULL expander\n")); 4351 return agTRUE; 4352 } 4353 4354 if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi && 4355 oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo 4356 ) 4357 { 4358 TI_DBG3(("tdsaDuplicateConfigSASAddr: unnecessary\n")); 4359 return agTRUE; 4360 } 4361 4362 TI_DBG3(("tdsaDuplicateConfigSASAddr: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4363 TI_DBG3(("tdsaDuplicateConfigSASAddr: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4364 TI_DBG3(("tdsaDuplicateConfigSASAddr: configsasAddressHi 0x%08x\n", configSASAddressHi)); 4365 TI_DBG3(("tdsaDuplicateConfigSASAddr: configsasAddressLo 0x%08x\n", configSASAddressLo)); 4366 TI_DBG3(("tdsaDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4367 for(i=0;i<oneExpander->configSASAddrTableIndex;i++) 4368 { 4369 if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi && 4370 oneExpander->configSASAddressLoTable[i] == configSASAddressLo 4371 ) 4372 { 4373 TI_DBG3(("tdsaDuplicateConfigSASAddr: FOUND!!!\n")); 4374 ret = agTRUE; 4375 break; 4376 } 4377 } 4378 /* new one; let's add it */ 4379 if (ret == agFALSE) 4380 { 4381 TI_DBG3(("tdsaDuplicateConfigSASAddr: adding configSAS Addr!!!\n")); 4382 TI_DBG3(("tdsaDuplicateConfigSASAddr: configSASAddrTableIndex %d\n", oneExpander->configSASAddrTableIndex)); 4383 oneExpander->configSASAddressHiTable[oneExpander->configSASAddrTableIndex] = configSASAddressHi; 4384 oneExpander->configSASAddressLoTable[oneExpander->configSASAddrTableIndex] = configSASAddressLo; 4385 oneExpander->configSASAddrTableIndex++; 4386 } 4387 4388 return ret; 4389 } 4390 /***************************************************************************** 4391 *! \brief tdsaFindConfigurableExp 4392 * 4393 * Purpose: This function finds whether there is a configurable expander in 4394 * the upstream expander list. 4395 * 4396 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4397 * instance. 4398 * \param onePortContext: Pointer to the portal context instance. 4399 * \param oneExpander: Pointer to the expander data. 4400 * 4401 * \return: 4402 * agTRUE There is configurable expander. 4403 * agFALSE There is not configurable expander. 4404 * 4405 * \note: 4406 * 4407 *****************************************************************************/ 4408 osGLOBAL tdsaExpander_t * 4409 tdsaFindConfigurableExp( 4410 tiRoot_t *tiRoot, 4411 tdsaPortContext_t *onePortContext, 4412 tdsaExpander_t *oneExpander 4413 ) 4414 { 4415 tdsaExpander_t *tempExpander; 4416 tdsaPortContext_t *tmpOnePortContext = onePortContext; 4417 tdsaExpander_t *ret = agNULL; 4418 4419 TI_DBG3(("tdsaFindConfigurableExp: start\n")); 4420 4421 if (oneExpander == agNULL) 4422 { 4423 TI_DBG3(("tdsaFindConfigurableExp: NULL expander\n")); 4424 return agNULL; 4425 } 4426 4427 TI_DBG3(("tdsaFindConfigurableExp: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4428 TI_DBG3(("tdsaFindConfigurableExp: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4429 4430 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK); 4431 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList))) 4432 { 4433 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 4434 TI_DBG3(("tdsaFindConfigurableExp: empty UpdiscoveringExpanderList\n")); 4435 return agNULL; 4436 } 4437 else 4438 { 4439 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK); 4440 } 4441 tempExpander = oneExpander->tdUpStreamExpander; 4442 while (tempExpander) 4443 { 4444 TI_DBG3(("tdsaFindConfigurableExp: loop exp addrHi 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressHi)); 4445 TI_DBG3(("tdsaFindConfigurableExp: loop exp addrLo 0x%08x\n", tempExpander->tdDevice->SASAddressID.sasAddressLo)); 4446 if (tempExpander->configRouteTable) 4447 { 4448 TI_DBG3(("tdsaFindConfigurableExp: found configurable expander\n")); 4449 ret = tempExpander; 4450 break; 4451 } 4452 tempExpander = tempExpander->tdUpStreamExpander; 4453 } 4454 4455 return ret; 4456 } 4457 4458 /***************************************************************************** 4459 *! \brief tdsaSASDownStreamDiscoverExpanderPhy 4460 * 4461 * Purpose: This function actully does downstream traverse and finds out detailed 4462 * information about topology. 4463 * 4464 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 4465 * instance. 4466 * \param onePortContext: Pointer to the portal context instance. 4467 * \param oneExpander: Pointer to the expander data. 4468 * \param pDiscoverResp: Pointer to the Discovery SMP respsonse. 4469 * 4470 * \return: 4471 * None 4472 * 4473 * \note: 4474 * 4475 *****************************************************************************/ 4476 osGLOBAL void 4477 tdsaSASDownStreamDiscoverExpanderPhy( 4478 tiRoot_t *tiRoot, 4479 tdsaPortContext_t *onePortContext, 4480 tdsaExpander_t *oneExpander, 4481 smpRespDiscover_t *pDiscoverResp 4482 ) 4483 { 4484 tdsaDeviceData_t *oneDeviceData; 4485 tdsaExpander_t *UpStreamExpander; 4486 tdsaDeviceData_t *AttachedDevice = agNULL; 4487 tdsaExpander_t *AttachedExpander; 4488 agsaSASIdentify_t sasIdentify; 4489 bit8 connectionRate; 4490 bit32 attachedSasHi, attachedSasLo; 4491 tdsaSASSubID_t agSASSubID; 4492 tdsaExpander_t *ConfigurableExpander = agNULL; 4493 bit32 dupConfigSASAddr = agFALSE; 4494 bit32 configSASAddressHi; 4495 bit32 configSASAddressLo; 4496 4497 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: start\n")); 4498 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 4499 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 4500 4501 TD_ASSERT(tiRoot, "(tdsaSASDownStreamDiscoverExpanderPhy) agRoot NULL"); 4502 TD_ASSERT(onePortContext, "(tdsaSASDownStreamDiscoverExpanderPhy) pPort NULL"); 4503 TD_ASSERT(oneExpander, "(tdsaSASDownStreamDiscoverExpanderPhy) pExpander NULL"); 4504 TD_ASSERT(pDiscoverResp, "(tdsaSASDownStreamDiscoverExpanderPhy) pDiscoverResp NULL"); 4505 4506 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->tdDevice)); 4507 4508 if (onePortContext->valid == agFALSE) 4509 { 4510 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: aborting discovery\n")); 4511 tdsaSASDiscoverAbort(tiRoot, onePortContext); 4512 return; 4513 } 4514 #ifdef TD_INTERNAL_DEBUG 4515 tdsaDumpAllExp(tiRoot, onePortContext, oneExpander); 4516 tdsaFindUpStreamConfigurableExp(tiRoot, oneExpander); 4517 tdsaFindDownStreamConfigurableExp(tiRoot, oneExpander); 4518 #endif 4519 /* (1) Find the device structure of the expander */ 4520 oneDeviceData = oneExpander->tdDevice; 4521 TD_ASSERT(oneDeviceData, "(tdsaSASDownStreamDiscoverExpanderPhy) pDevice NULL"); 4522 4523 /* for debugging */ 4524 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Phy #%d of SAS %08x-%08x\n", 4525 oneExpander->discoveringPhyId, 4526 oneDeviceData->SASAddressID.sasAddressHi, 4527 oneDeviceData->SASAddressID.sasAddressLo)); 4528 TI_DBG3((" Attached device: %s\n", 4529 ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 0 ? "No Device" : 4530 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 1 ? "End Device" : 4531 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == 2 ? "Edge Expander" : "Fanout Expander"))))); 4532 /* for debugging */ 4533 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier) 4534 { 4535 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: !!! Incorrect SMP response !!!\n")); 4536 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: Request PhyID #%d Response PhyID #%d\n", oneExpander->discoveringPhyId, pDiscoverResp->phyIdentifier)); 4537 tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 4538 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4539 return; 4540 } 4541 4542 #ifdef TD_INTERNAL_DEBUG /* debugging only */ 4543 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_NO_DEVICE) 4544 { 4545 tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t)); 4546 } 4547 #endif 4548 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 4549 { 4550 TI_DBG3((" SAS address : %08x-%08x\n", 4551 DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp), 4552 DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp))); 4553 TI_DBG3((" SSP Target : %d\n", DISCRSP_IS_SSP_TARGET(pDiscoverResp)?1:0)); 4554 TI_DBG3((" STP Target : %d\n", DISCRSP_IS_STP_TARGET(pDiscoverResp)?1:0)); 4555 TI_DBG3((" SMP Target : %d\n", DISCRSP_IS_SMP_TARGET(pDiscoverResp)?1:0)); 4556 TI_DBG3((" SATA DEVICE : %d\n", DISCRSP_IS_SATA_DEVICE(pDiscoverResp)?1:0)); 4557 TI_DBG3((" SSP Initiator : %d\n", DISCRSP_IS_SSP_INITIATOR(pDiscoverResp)?1:0)); 4558 TI_DBG3((" STP Initiator : %d\n", DISCRSP_IS_STP_INITIATOR(pDiscoverResp)?1:0)); 4559 TI_DBG3((" SMP Initiator : %d\n", DISCRSP_IS_SMP_INITIATOR(pDiscoverResp)?1:0)); 4560 TI_DBG3((" Phy ID : %d\n", pDiscoverResp->phyIdentifier)); 4561 TI_DBG3((" Attached Phy ID: %d\n", pDiscoverResp->attachedPhyIdentifier)); 4562 4563 } 4564 /* end for debugging */ 4565 4566 /* saving routing attribute for non self-configuring expanders */ 4567 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp); 4568 4569 /* for debugging */ 4570 // dumpRoutingAttributes(tiRoot, oneExpander, pDiscoverResp->phyIdentifier); 4571 4572 oneExpander->discoverSMPAllowed = agTRUE; 4573 4574 /* If a device is attached */ 4575 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE) 4576 { 4577 /* Setup sasIdentify for the attached device */ 4578 sasIdentify.phyIdentifier = pDiscoverResp->phyIdentifier; 4579 sasIdentify.deviceType_addressFrameType = (bit8)(pDiscoverResp->attachedDeviceType & 0x70); 4580 sasIdentify.initiator_ssp_stp_smp = pDiscoverResp->attached_Ssp_Stp_Smp_Sata_Initiator; 4581 sasIdentify.target_ssp_stp_smp = pDiscoverResp->attached_SataPS_Ssp_Stp_Smp_Sata_Target; 4582 *(bit32*)sasIdentify.sasAddressHi = *(bit32*)pDiscoverResp->attachedSasAddressHi; 4583 *(bit32*)sasIdentify.sasAddressLo = *(bit32*)pDiscoverResp->attachedSasAddressLo; 4584 4585 /* incremental discovery */ 4586 agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 4587 agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 4588 agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 4589 agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 4590 4591 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp); 4592 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp); 4593 4594 /* If it's a direct routing */ 4595 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT) 4596 { 4597 /* If the attached device is an expander */ 4598 if ( (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 4599 || (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) ) 4600 4601 { 4602 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error direct routing can't connect to expander\n")); 4603 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4604 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4605 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4606 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4607 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4608 4609 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4610 4611 return; 4612 } 4613 } 4614 4615 /* If the expander's attached device is not myself */ 4616 if ( (attachedSasHi != onePortContext->sasLocalAddressHi) 4617 || (attachedSasLo != onePortContext->sasLocalAddressLo) ) 4618 { 4619 /* Find the attached device from discovered list */ 4620 AttachedDevice = tdsaPortSASDeviceFind(tiRoot, onePortContext, attachedSasLo, attachedSasHi); 4621 /* If the device has not been discovered before */ 4622 if ( AttachedDevice == agNULL) //11 4623 { 4624 /* If the phy has subtractive routing attribute */ 4625 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE && 4626 (DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE || 4627 DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 4628 ) 4629 { 4630 /* TODO: discovery error, callback */ 4631 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error subtractive routing error - inconsistent SAS address\n")); 4632 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4633 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4634 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4635 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4636 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4637 /* discovery done */ 4638 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4639 } 4640 else 4641 { 4642 /* Add the device */ 4643 /* read minimum rate from the configuration 4644 onePortContext->LinkRate is SPC's local link rate 4645 */ 4646 connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp))); 4647 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: link rate 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 4648 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: negotiatedPhyLinkRate 0x%x\n", DISCRSP_GET_LINKRATE(pDiscoverResp))); 4649 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: connectionRate 0x%x\n", connectionRate)); 4650 4651 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 4652 { 4653 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 4654 { 4655 AttachedDevice = tdsaPortSASDeviceAdd( 4656 tiRoot, 4657 onePortContext, 4658 sasIdentify, 4659 agFALSE, 4660 connectionRate, 4661 IT_NEXUS_TIMEOUT, 4662 0, 4663 STP_DEVICE_TYPE, 4664 oneDeviceData, 4665 pDiscoverResp->phyIdentifier 4666 ); 4667 } 4668 else 4669 { 4670 /* incremental discovery */ 4671 AttachedDevice = tdsaFindRegNValid( 4672 onePortContext->agRoot, 4673 onePortContext, 4674 &agSASSubID 4675 ); 4676 /* not registered and not valid; add this*/ 4677 if (AttachedDevice == agNULL) 4678 { 4679 AttachedDevice = tdsaPortSASDeviceAdd( 4680 tiRoot, 4681 onePortContext, 4682 sasIdentify, 4683 agFALSE, 4684 connectionRate, 4685 IT_NEXUS_TIMEOUT, 4686 0, 4687 STP_DEVICE_TYPE, 4688 oneDeviceData, 4689 pDiscoverResp->phyIdentifier 4690 ); 4691 } 4692 } 4693 } 4694 else 4695 { 4696 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 4697 { 4698 AttachedDevice = tdsaPortSASDeviceAdd( 4699 tiRoot, 4700 onePortContext, 4701 sasIdentify, 4702 agFALSE, 4703 connectionRate, 4704 IT_NEXUS_TIMEOUT, 4705 0, 4706 SAS_DEVICE_TYPE, 4707 oneDeviceData, 4708 pDiscoverResp->phyIdentifier 4709 ); 4710 } 4711 else 4712 { 4713 /* incremental discovery */ 4714 AttachedDevice = tdsaFindRegNValid( 4715 onePortContext->agRoot, 4716 onePortContext, 4717 &agSASSubID 4718 ); 4719 /* not registered and not valid; add this*/ 4720 if (AttachedDevice == agNULL) 4721 { 4722 AttachedDevice = tdsaPortSASDeviceAdd( 4723 tiRoot, 4724 onePortContext, 4725 sasIdentify, 4726 agFALSE, 4727 connectionRate, 4728 IT_NEXUS_TIMEOUT, 4729 0, 4730 SAS_DEVICE_TYPE, 4731 oneDeviceData, 4732 pDiscoverResp->phyIdentifier 4733 ); 4734 } 4735 } 4736 } 4737 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice)); 4738 /* If the device is added successfully */ 4739 if ( AttachedDevice != agNULL) 4740 { 4741 if ( SA_IDFRM_IS_SSP_TARGET(&sasIdentify) 4742 || SA_IDFRM_IS_SMP_TARGET(&sasIdentify) 4743 || SA_IDFRM_IS_SSP_INITIATOR(&sasIdentify) 4744 || SA_IDFRM_IS_SMP_INITIATOR(&sasIdentify) ) 4745 { 4746 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n")); 4747 4748 } 4749 else 4750 { 4751 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) || 4752 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) ) 4753 { 4754 4755 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n")); 4756 } 4757 else 4758 { 4759 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Other type of device.\n")); 4760 } 4761 } 4762 4763 /* LP2006-05-26 added upstream device to the newly found device */ 4764 AttachedDevice->tdExpander = oneExpander; 4765 4766 /* If the phy has table routing attribute */ 4767 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 4768 { 4769 /* If the attached device is a fan out expander */ 4770 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 4771 { 4772 /* TODO: discovery error, callback */ 4773 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys are connected\n")); 4774 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4775 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4776 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4777 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4778 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4779 /* discovery done */ 4780 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4781 } 4782 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 4783 { 4784 /* Allocate an expander data structure */ 4785 AttachedExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, AttachedDevice); 4786 4787 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander)); 4788 /* If allocate successfully */ 4789 if ( AttachedExpander != agNULL) 4790 { 4791 /* set up downstream information on configurable expander */ 4792 if (oneExpander->configRouteTable) 4793 { 4794 tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 4795 } 4796 /* Setup upstream information */ 4797 tdsaSASExpanderUpStreamPhyAdd(tiRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 4798 AttachedExpander->hasUpStreamDevice = agTRUE; 4799 AttachedExpander->upStreamSASAddressHi 4800 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4801 AttachedExpander->upStreamSASAddressLo 4802 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4803 AttachedExpander->tdUpStreamExpander = oneExpander; 4804 /* (2.3.2.2.2.2.2.2.2) Add the pAttachedExpander to discovering list */ 4805 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander); 4806 } 4807 /* If failed to allocate */ 4808 else 4809 { 4810 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n")); 4811 /* discovery done */ 4812 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4813 } 4814 } 4815 } 4816 /* If status is still DISCOVERY_DOWN_STREAM */ 4817 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4818 { 4819 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before\n")); 4820 tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander); 4821 UpStreamExpander = oneExpander->tdUpStreamExpander; 4822 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander); 4823 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 4824 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 4825 if (ConfigurableExpander) 4826 { 4827 if ( (ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi 4828 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 4829 (ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo 4830 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 4831 ) 4832 { /* directly attached between oneExpander and ConfigurableExpander */ 4833 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before loc 1\n")); 4834 configSASAddressHi = oneExpander->tdDevice->SASAddressID.sasAddressHi; 4835 configSASAddressLo = oneExpander->tdDevice->SASAddressID.sasAddressLo; 4836 } 4837 else 4838 { 4839 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st before loc 2\n")); 4840 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 4841 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 4842 } 4843 } /* if !ConfigurableExpander */ 4844 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot, 4845 ConfigurableExpander, 4846 configSASAddressHi, 4847 configSASAddressLo 4848 ); 4849 4850 4851 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 4852 { 4853 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 1st q123\n")); 4854 UpStreamExpander->tdCurrentDownStreamExpander = oneExpander; 4855 ConfigurableExpander->currentDownStreamPhyIndex = 4856 tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander); 4857 ConfigurableExpander->tdReturnginExpander = oneExpander; 4858 tdsaSASRoutingEntryAdd(tiRoot, 4859 ConfigurableExpander, 4860 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 4861 configSASAddressHi, 4862 configSASAddressLo 4863 ); 4864 } 4865 } 4866 } 4867 /* If fail to add the device */ 4868 else 4869 { 4870 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to add a device\n")); 4871 /* discovery done */ 4872 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4873 } 4874 } 4875 } 4876 /* If the device has been discovered before */ 4877 else /* haha discovered before */ 4878 { 4879 /* If the phy has subtractive routing attribute */ 4880 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE) 4881 { 4882 /* If the expander doesn't have up stream device */ 4883 if ( oneExpander->hasUpStreamDevice == agFALSE) 4884 { 4885 /* TODO: discovery error, callback */ 4886 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error loop, or end device connects to two expanders\n")); 4887 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4888 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4889 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4890 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4891 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4892 /* discovery done */ 4893 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4894 } 4895 /* If the expander has up stream device */ 4896 else 4897 { 4898 /* If sas address doesn't match */ 4899 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi) 4900 || (oneExpander->upStreamSASAddressLo != attachedSasLo) ) 4901 { 4902 /* TODO: discovery error, callback */ 4903 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two subtractive phys\n")); 4904 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4905 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4906 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4907 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4908 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4909 /* discovery done */ 4910 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4911 } 4912 } 4913 } 4914 /* If the phy has table routing attribute */ 4915 else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) 4916 { 4917 /* If the attached device is a fan out expander */ 4918 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE) 4919 { 4920 /* (2.3.3.2.1.1) TODO: discovery error, callback */ 4921 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error fan out expander to routing table phy\n")); 4922 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4923 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4924 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4925 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4926 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4927 /* discovery done */ 4928 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4929 } 4930 /* If the attached device is an edge expander */ 4931 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE) 4932 { 4933 /* Setup up stream inform */ 4934 AttachedExpander = AttachedDevice->tdExpander; 4935 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander)); 4936 //hhhhhh 4937 /* If the attached expander has up stream device */ 4938 if ( AttachedExpander->hasUpStreamDevice == agTRUE) 4939 { 4940 /* compare the sas address */ 4941 if ( (AttachedExpander->upStreamSASAddressHi 4942 != DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo)) 4943 || (AttachedExpander->upStreamSASAddressLo 4944 != DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo))) 4945 { 4946 /* TODO: discovery error, callback */ 4947 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (1)\n")); 4948 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4949 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4950 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4951 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4952 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4953 /* discovery done */ 4954 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4955 } 4956 else 4957 { 4958 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander)); 4959 /* set up downstream information on configurable expander */ 4960 if (oneExpander->configRouteTable) 4961 { 4962 tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId); 4963 } 4964 /* haha */ 4965 tdsaSASExpanderUpStreamPhyAdd(tiRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId); 4966 /* Add the pAttachedExpander to discovering list */ 4967 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander); 4968 } 4969 } 4970 /* If the attached expander doesn't have up stream device */ 4971 else 4972 { 4973 /* TODO: discovery error, callback */ 4974 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: **** Topology Error two table routing phys connected (2)\n")); 4975 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressLo 4976 = DEVINFO_GET_SAS_ADDRESSLO(&oneDeviceData->agDeviceInfo); 4977 onePortContext->discovery.sasAddressIDDiscoverError.sasAddressHi 4978 = DEVINFO_GET_SAS_ADDRESSHI(&oneDeviceData->agDeviceInfo); 4979 onePortContext->discovery.sasAddressIDDiscoverError.phyIdentifier = oneExpander->discoveringPhyId; 4980 /* discovery done */ 4981 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 4982 } 4983 } 4984 } /* for else if (DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) */ 4985 4986 /* do this regradless of sub or table */ 4987 /* If status is still DISCOVERY_DOWN_STREAM */ 4988 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 4989 { 4990 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before\n")); 4991 tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander); 4992 4993 UpStreamExpander = oneExpander->tdUpStreamExpander; 4994 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander); 4995 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 4996 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 4997 if (ConfigurableExpander) 4998 { 4999 if ( (ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi 5000 == DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo)) && 5001 (ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo 5002 == DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo)) 5003 ) 5004 { /* directly attached between oneExpander and ConfigurableExpander */ 5005 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before loc 1\n")); 5006 configSASAddressHi = oneExpander->tdDevice->SASAddressID.sasAddressHi; 5007 configSASAddressLo = oneExpander->tdDevice->SASAddressID.sasAddressLo; 5008 } 5009 else 5010 { 5011 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before loc 2\n")); 5012 configSASAddressHi = DEVINFO_GET_SAS_ADDRESSHI(&AttachedDevice->agDeviceInfo); 5013 configSASAddressLo = DEVINFO_GET_SAS_ADDRESSLO(&AttachedDevice->agDeviceInfo); 5014 } 5015 } /* if !ConfigurableExpander */ 5016 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot, 5017 ConfigurableExpander, 5018 configSASAddressHi, 5019 configSASAddressLo 5020 ); 5021 5022 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 5023 { 5024 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd q123 \n")); 5025 UpStreamExpander->tdCurrentDownStreamExpander = oneExpander; 5026 ConfigurableExpander->currentDownStreamPhyIndex = 5027 tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander); 5028 ConfigurableExpander->tdReturnginExpander = oneExpander; 5029 tdsaSASRoutingEntryAdd(tiRoot, 5030 ConfigurableExpander, 5031 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 5032 configSASAddressHi, 5033 configSASAddressLo 5034 ); 5035 } 5036 } /* if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) */ 5037 /* incremental discovery */ 5038 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START) 5039 { 5040 connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp))); 5041 5042 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp)) 5043 { 5044 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SATA_STP\n")); 5045 5046 tdsaPortSASDeviceAdd( 5047 tiRoot, 5048 onePortContext, 5049 sasIdentify, 5050 agFALSE, 5051 connectionRate, 5052 IT_NEXUS_TIMEOUT, 5053 0, 5054 STP_DEVICE_TYPE, 5055 oneDeviceData, 5056 pDiscoverResp->phyIdentifier 5057 ); 5058 } 5059 else 5060 { 5061 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SAS\n")); 5062 5063 tdsaPortSASDeviceAdd( 5064 tiRoot, 5065 onePortContext, 5066 sasIdentify, 5067 agFALSE, 5068 connectionRate, 5069 IT_NEXUS_TIMEOUT, 5070 0, 5071 SAS_DEVICE_TYPE, 5072 oneDeviceData, 5073 pDiscoverResp->phyIdentifier 5074 ); 5075 5076 } 5077 } 5078 5079 5080 }/* else; existing devce */ 5081 } /* not attached to myself */ 5082 /* If the attached device is myself */ 5083 else 5084 { 5085 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Self\n")); 5086 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 3rd before\n")); 5087 tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander); 5088 5089 UpStreamExpander = oneExpander->tdUpStreamExpander; 5090 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander); 5091 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot, 5092 ConfigurableExpander, 5093 onePortContext->sasLocalAddressHi, 5094 onePortContext->sasLocalAddressLo 5095 ); 5096 5097 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE) 5098 { 5099 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 3rd q123 Setup routing table\n")); 5100 UpStreamExpander->tdCurrentDownStreamExpander = oneExpander; 5101 ConfigurableExpander->currentDownStreamPhyIndex = 5102 tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander); 5103 ConfigurableExpander->tdReturnginExpander = oneExpander; 5104 tdsaSASRoutingEntryAdd(tiRoot, 5105 ConfigurableExpander, 5106 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 5107 onePortContext->sasLocalAddressHi, 5108 onePortContext->sasLocalAddressLo 5109 ); 5110 } 5111 } 5112 } 5113 /* If no device is attached */ 5114 else 5115 { 5116 } 5117 5118 5119 /* Increment the discovering phy id */ 5120 oneExpander->discoveringPhyId ++; 5121 5122 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 5123 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 5124 { 5125 /* If not the last phy */ 5126 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 5127 { 5128 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: More Phys to discover\n")); 5129 /* continue discovery for the next phy */ 5130 tdsaDiscoverSend(tiRoot, oneDeviceData); 5131 } 5132 /* If the last phy */ 5133 else 5134 { 5135 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: No More Phys\n")); 5136 5137 /* remove the expander from the discovering list */ 5138 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander); 5139 /* continue downstream discovering */ 5140 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 5141 } 5142 } 5143 else 5144 { 5145 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 5146 } 5147 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 5148 5149 return; 5150 } 5151 5152 /***************************************************************************** 5153 *! \brief tdsaSASDownStreamDiscoverExpanderPhySkip 5154 * 5155 * Purpose: This function skips a phy which returned PHY_VACANT in SMP 5156 * response in downstream 5157 * 5158 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5159 * instance. 5160 * \param onePortContext: Pointer to the portal context instance. 5161 * \param oneExpander: Pointer to the expander data. 5162 * 5163 * \return: 5164 * None 5165 * 5166 * \note: 5167 * 5168 *****************************************************************************/ 5169 osGLOBAL void 5170 tdsaSASDownStreamDiscoverExpanderPhySkip( 5171 tiRoot_t *tiRoot, 5172 tdsaPortContext_t *onePortContext, 5173 tdsaExpander_t *oneExpander 5174 ) 5175 { 5176 tdsaDeviceData_t *oneDeviceData; 5177 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: start\n")); 5178 oneDeviceData = oneExpander->tdDevice; 5179 5180 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 5181 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 5182 5183 /* Increment the discovering phy id */ 5184 oneExpander->discoveringPhyId ++; 5185 5186 /* If the discovery status is DISCOVERY_DOWN_STREAM */ 5187 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM ) 5188 { 5189 /* If not the last phy */ 5190 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys ) 5191 { 5192 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: More Phys to discover\n")); 5193 /* continue discovery for the next phy */ 5194 tdsaDiscoverSend(tiRoot, oneDeviceData); 5195 } 5196 /* If the last phy */ 5197 else 5198 { 5199 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: No More Phys\n")); 5200 5201 /* remove the expander from the discovering list */ 5202 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander); 5203 /* continue downstream discovering */ 5204 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData); 5205 } 5206 } 5207 else 5208 { 5209 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status)); 5210 } 5211 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1)); 5212 5213 return; 5214 } 5215 5216 /***************************************************************************** 5217 *! \brief tdsaSASRoutingEntryAdd 5218 * 5219 * Purpose: This function adds a routing entry in the configurable expander. 5220 * 5221 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5222 * instance. 5223 * \param oneExpander: Pointer to the expander data. 5224 * \param phyId: Phy identifier. 5225 * \param configSASAddressHi: Upper 4 byte of SAS address. 5226 * \param configSASAddressLo: Lower 4 byte of SAS address. 5227 * 5228 * \return: 5229 * agTRUE Routing entry is added successfully 5230 * agFALSE Routing entry is not added successfully 5231 * 5232 * \note: 5233 * 5234 *****************************************************************************/ 5235 osGLOBAL bit32 5236 tdsaSASRoutingEntryAdd( 5237 tiRoot_t *tiRoot, 5238 tdsaExpander_t *oneExpander, 5239 bit32 phyId, 5240 bit32 configSASAddressHi, 5241 bit32 configSASAddressLo 5242 ) 5243 { 5244 bit32 ret = agTRUE; 5245 smpReqConfigureRouteInformation_t confRoutingInfo; 5246 tdsaPortContext_t *onePortContext; 5247 bit32 i; 5248 agsaRoot_t *agRoot; 5249 5250 TI_DBG3(("tdsaSASRoutingEntryAdd: start\n")); 5251 TI_DBG3(("tdsaSASRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 5252 TI_DBG3(("tdsaSASRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 5253 TI_DBG3(("tdsaSASRoutingEntryAdd: phyid %d\n", phyId)); 5254 5255 /* needs to compare the location of oneExpander and configSASAddress 5256 add only if 5257 oneExpander 5258 | 5259 configSASaddress 5260 5261 */ 5262 if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi && 5263 oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo 5264 ) 5265 { 5266 TI_DBG3(("tdsaSASRoutingEntryAdd: unnecessary\n")); 5267 return ret; 5268 } 5269 if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE) 5270 { 5271 TI_DBG3(("tdsaSASRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId])); 5272 return ret; 5273 } 5274 5275 agRoot = oneExpander->tdDevice->agRoot; 5276 onePortContext = oneExpander->tdDevice->tdPortContext; 5277 5278 onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING; 5279 5280 /* reset smpReqConfigureRouteInformation_t */ 5281 osti_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t)); 5282 if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex ) 5283 { 5284 TI_DBG3(("tdsaSASRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi)); 5285 TI_DBG3(("tdsaSASRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo)); 5286 TI_DBG3(("tdsaSASRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId])); 5287 5288 oneExpander->configSASAddressHi = configSASAddressHi; 5289 oneExpander->configSASAddressLo = configSASAddressLo; 5290 confRoutingInfo.reserved1[0] = 0; 5291 confRoutingInfo.reserved1[1] = 0; 5292 OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId])); 5293 confRoutingInfo.reserved2 = 0; 5294 confRoutingInfo.phyIdentifier = (bit8)phyId; 5295 confRoutingInfo.reserved3[0] = 0; 5296 confRoutingInfo.reserved3[1] = 0; 5297 confRoutingInfo.disabledBit_reserved4 = 0; 5298 confRoutingInfo.reserved5[0] = 0; 5299 confRoutingInfo.reserved5[1] = 0; 5300 confRoutingInfo.reserved5[2] = 0; 5301 OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi); 5302 OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo); 5303 for ( i = 0; i < 16; i ++ ) 5304 { 5305 confRoutingInfo.reserved6[i] = 0; 5306 } 5307 tdSMPStart(tiRoot, agRoot, oneExpander->tdDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ, agNULL, 0); 5308 5309 oneExpander->currentIndex[phyId] ++; 5310 } 5311 else 5312 { 5313 TI_DBG1(("tdsaSASRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex)); 5314 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 5315 5316 ret = agFALSE; 5317 } 5318 5319 5320 return ret; 5321 } 5322 /***************************************************************************** 5323 *! \brief tdsaConfigRoutingInfoRespRcvd 5324 * 5325 * Purpose: This function processes Configure Routing Information response. 5326 * 5327 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5328 * instance. 5329 * \param agRoot: Pointer to chip/driver Instance. 5330 * \param oneDeviceData: Pointer to the device data. 5331 * \param frameHeader: Pointer to SMP frame header. 5332 * \param frameHandle: A Handle used to refer to the response frame 5333 * 5334 * \return: 5335 * None 5336 * 5337 * \note: 5338 * 5339 *****************************************************************************/ 5340 /* needs to traverse only upstream not downstream */ 5341 osGLOBAL void 5342 tdsaConfigRoutingInfoRespRcvd( 5343 tiRoot_t *tiRoot, 5344 agsaRoot_t *agRoot, 5345 agsaIORequest_t *agIORequest, 5346 tdsaDeviceData_t *oneDeviceData, 5347 tdssSMPFrameHeader_t *frameHeader, 5348 agsaFrameHandle_t frameHandle 5349 ) 5350 { 5351 tdsaExpander_t *oneExpander = oneDeviceData->tdExpander; 5352 tdsaExpander_t *UpStreamExpander; 5353 tdsaExpander_t *DownStreamExpander; 5354 tdsaExpander_t *ReturningExpander; 5355 tdsaExpander_t *ConfigurableExpander; 5356 5357 tdsaPortContext_t *onePortContext; 5358 tdsaDeviceData_t *ReturningExpanderDeviceData; 5359 bit32 dupConfigSASAddr = agFALSE; 5360 5361 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: start\n")); 5362 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 5363 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 5364 5365 onePortContext = oneDeviceData->tdPortContext; 5366 5367 if (onePortContext->valid == agFALSE) 5368 { 5369 TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: aborting discovery\n")); 5370 tdsaSASDiscoverAbort(tiRoot, onePortContext); 5371 return; 5372 } 5373 5374 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED || 5375 frameHeader->smpFunctionResult == PHY_VACANT 5376 ) 5377 { 5378 DownStreamExpander = oneExpander->tdCurrentDownStreamExpander; 5379 if (DownStreamExpander != agNULL) 5380 { 5381 DownStreamExpander->currentUpStreamPhyIndex ++; 5382 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 5383 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys)); 5384 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressHi)); 5385 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressLo)); 5386 5387 } 5388 5389 oneExpander->currentDownStreamPhyIndex++; 5390 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys)); 5391 5392 if ( DownStreamExpander != agNULL) 5393 { 5394 if (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys) 5395 { 5396 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: first if\n")); 5397 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 5398 5399 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex])); 5400 5401 tdsaSASRoutingEntryAdd(tiRoot, 5402 oneExpander, 5403 DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex], 5404 oneExpander->configSASAddressHi, 5405 oneExpander->configSASAddressLo 5406 ); 5407 } 5408 else 5409 { 5410 /* traversing up till discovery Root onePortContext->discovery.RootExp */ 5411 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else\n")); 5412 5413 UpStreamExpander = oneExpander->tdUpStreamExpander; 5414 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander); 5415 if (UpStreamExpander != agNULL) 5416 { 5417 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->tdDevice->SASAddressID.sasAddressHi)); 5418 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->tdDevice->SASAddressID.sasAddressLo)); 5419 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot, 5420 ConfigurableExpander, 5421 oneExpander->configSASAddressHi, 5422 oneExpander->configSASAddressLo 5423 ); 5424 5425 if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE) 5426 { 5427 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else if\n")); 5428 5429 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->tdDevice->SASAddressID.sasAddressHi)); 5430 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->tdDevice->SASAddressID.sasAddressLo)); 5431 5432 UpStreamExpander->tdCurrentDownStreamExpander = oneExpander; 5433 ConfigurableExpander->currentDownStreamPhyIndex = 5434 tdsaFindCurrentDownStreamPhyIndex(tiRoot, ConfigurableExpander); 5435 ConfigurableExpander->tdReturnginExpander = oneExpander->tdReturnginExpander; 5436 DownStreamExpander->currentUpStreamPhyIndex = 0; 5437 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex)); 5438 5439 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex])); 5440 tdsaSASRoutingEntryAdd(tiRoot, 5441 ConfigurableExpander, 5442 ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 5443 oneExpander->configSASAddressHi, 5444 oneExpander->configSASAddressLo 5445 ); 5446 } 5447 else 5448 { 5449 /* going back to where it was */ 5450 /* ConfigRoutingInfo is done for a target */ 5451 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n")); 5452 ReturningExpander = oneExpander->tdReturnginExpander; 5453 DownStreamExpander->currentUpStreamPhyIndex = 0; 5454 /* debugging */ 5455 if (ReturningExpander != agNULL) 5456 { 5457 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->tdDevice->SASAddressID.sasAddressHi)); 5458 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->tdDevice->SASAddressID.sasAddressLo)); 5459 5460 ReturningExpanderDeviceData = ReturningExpander->tdDevice; 5461 5462 /* No longer in DISCOVERY_CONFIG_ROUTING */ 5463 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 5464 5465 /* If not the last phy */ 5466 if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys ) 5467 { 5468 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: More Phys to discover\n")); 5469 /* continue discovery for the next phy */ 5470 /* needs to send only one Discovery not multiple times */ 5471 if (ReturningExpander->discoverSMPAllowed == agTRUE) 5472 { 5473 tdsaDiscoverSend(tiRoot, ReturningExpanderDeviceData); 5474 } 5475 ReturningExpander->discoverSMPAllowed = agFALSE; 5476 } 5477 /* If the last phy */ 5478 else 5479 { 5480 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: No More Phys\n")); 5481 ReturningExpander->discoverSMPAllowed = agTRUE; 5482 5483 /* remove the expander from the discovering list */ 5484 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, ReturningExpander); 5485 /* continue downstream discovering */ 5486 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, ReturningExpanderDeviceData); 5487 5488 //DownStreamExpander 5489 } 5490 } 5491 else 5492 { 5493 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander is NULL\n")); 5494 } 5495 } 5496 } 5497 else 5498 { 5499 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n")); 5500 } 5501 } 5502 } 5503 } 5504 else 5505 { 5506 TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=%x\n", frameHeader->smpFunctionResult)); 5507 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 5508 } 5509 return; 5510 } 5511 5512 /***************************************************************************** 5513 *! \brief tdsaReportPhySataSend 5514 * 5515 * Purpose: This function sends Report Phy SATA to a device. 5516 * 5517 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5518 * instance. 5519 * \param oneDeviceData: Pointer to the device data. 5520 * \param phyId: Phy Identifier. 5521 * 5522 * \return: 5523 * None 5524 * 5525 * \note: 5526 * 5527 *****************************************************************************/ 5528 osGLOBAL void 5529 tdsaReportPhySataSend( 5530 tiRoot_t *tiRoot, 5531 tdsaDeviceData_t *oneDeviceData, 5532 bit8 phyId 5533 ) 5534 { 5535 agsaRoot_t *agRoot; 5536 tdsaExpander_t *oneExpander; 5537 tdsaPortContext_t *onePortContext; 5538 smpReqReportPhySata_t smpReportPhySataReq; 5539 5540 TI_DBG3(("tdsaReportPhySataSend: start\n")); 5541 5542 agRoot = oneDeviceData->agRoot; 5543 onePortContext = oneDeviceData->tdPortContext; 5544 oneExpander = oneDeviceData->tdExpander; 5545 5546 if (onePortContext == agNULL) 5547 { 5548 TI_DBG1(("tdsaReportPhySataSend: Error!!! portcontext is NULL\n")); 5549 } 5550 5551 if (oneExpander == agNULL) 5552 { 5553 TI_DBG1(("tdsaReportPhySataSend: Error!!! expander is NULL\n")); 5554 return; 5555 } 5556 TI_DBG3(("tdsaReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id)); 5557 TI_DBG3(("tdsaReportPhySataSend: phyid %d\n", phyId)); 5558 5559 oneExpander->tdDeviceToProcess = oneDeviceData; 5560 5561 osti_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t)); 5562 5563 smpReportPhySataReq.phyIdentifier = phyId; 5564 5565 5566 tdSMPStart( 5567 tiRoot, 5568 agRoot, 5569 oneExpander->tdDevice, 5570 SMP_REPORT_PHY_SATA, 5571 (bit8 *)&smpReportPhySataReq, 5572 sizeof(smpReqReportPhySata_t), 5573 AGSA_SMP_INIT_REQ, 5574 agNULL, 5575 0 5576 ); 5577 5578 return; 5579 } 5580 5581 /***************************************************************************** 5582 *! \brief tdsaReportPhySataRcvd 5583 * 5584 * Purpose: This function processes Report Phy SATA response. 5585 * 5586 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5587 * instance. 5588 * \param agRoot: Pointer to chip/driver Instance. 5589 * \param oneDeviceData: Pointer to the device data. 5590 * \param frameHeader: Pointer to SMP frame header. 5591 * \param frameHandle: A Handle used to refer to the response frame 5592 * 5593 * \return: 5594 * None 5595 * 5596 * \note: 5597 * 5598 *****************************************************************************/ 5599 osGLOBAL void 5600 tdsaReportPhySataRcvd( 5601 tiRoot_t *tiRoot, 5602 agsaRoot_t *agRoot, 5603 agsaIORequest_t *agIORequest, 5604 tdsaDeviceData_t *oneDeviceData, 5605 tdssSMPFrameHeader_t *frameHeader, 5606 agsaFrameHandle_t frameHandle 5607 ) 5608 { 5609 smpRespReportPhySata_t SMPreportPhySataResp; 5610 smpRespReportPhySata_t *pSMPReportPhySataResp; 5611 tdsaExpander_t *oneExpander = oneDeviceData->tdExpander; 5612 tdsaPortContext_t *onePortContext; 5613 agsaFisRegDeviceToHost_t *fis; 5614 tdsaDeviceData_t *SataDevice; 5615 #ifndef DIRECT_SMP 5616 tdssSMPRequestBody_t *tdSMPRequestBody; 5617 #endif 5618 5619 TI_DBG3(("tdsaReportPhySataRcvd: start\n")); 5620 TI_DBG3(("tdsaReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 5621 TI_DBG3(("tdsaReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 5622 #ifndef DIRECT_SMP 5623 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData; 5624 #endif 5625 /* get the current sata device hanlde stored in the expander structure */ 5626 SataDevice = oneExpander->tdDeviceToProcess; 5627 pSMPReportPhySataResp = &SMPreportPhySataResp; 5628 #ifdef DIRECT_SMP 5629 saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 5630 #else 5631 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 5632 #endif 5633 5634 //tdhexdump("tdsaReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 5635 5636 #ifndef DIRECT_SMP 5637 ostiFreeMemory( 5638 tiRoot, 5639 tdSMPRequestBody->IndirectSMPReqosMemHandle, 5640 tdSMPRequestBody->IndirectSMPReqLen 5641 ); 5642 ostiFreeMemory( 5643 tiRoot, 5644 tdSMPRequestBody->IndirectSMPResposMemHandle, 5645 tdSMPRequestBody->IndirectSMPRespLen 5646 ); 5647 #endif 5648 5649 onePortContext = oneDeviceData->tdPortContext; 5650 5651 if (onePortContext->valid == agFALSE) 5652 { 5653 TI_DBG1(("tdsaReportPhySataRcvd: aborting discovery\n")); 5654 tdsaSASDiscoverAbort(tiRoot, onePortContext); 5655 return; 5656 } 5657 if (SataDevice == agNULL) 5658 { 5659 TI_DBG1(("tdsaReportPhySataRcvd: SataDevice is NULL, wrong\n")); 5660 tdsaSASDiscoverAbort(tiRoot, onePortContext); 5661 return; 5662 } 5663 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED || 5664 frameHeader->smpFunctionResult == PHY_VACANT 5665 ) 5666 { 5667 fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis; 5668 if (fis->h.fisType == REG_DEV_TO_HOST_FIS) 5669 { 5670 /* save signature */ 5671 TI_DBG3(("tdsaReportPhySataRcvd: saves the signature\n")); 5672 /* saves signature */ 5673 SataDevice->satDevData.satSignature[0] = fis->d.sectorCount; 5674 SataDevice->satDevData.satSignature[1] = fis->d.lbaLow; 5675 SataDevice->satDevData.satSignature[2] = fis->d.lbaMid; 5676 SataDevice->satDevData.satSignature[3] = fis->d.lbaHigh; 5677 SataDevice->satDevData.satSignature[4] = fis->d.device; 5678 SataDevice->satDevData.satSignature[5] = 0; 5679 SataDevice->satDevData.satSignature[6] = 0; 5680 SataDevice->satDevData.satSignature[7] = 0; 5681 5682 TI_DBG3(("tdsaReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n", 5683 SataDevice->satDevData.satSignature[0], 5684 SataDevice->satDevData.satSignature[1], 5685 SataDevice->satDevData.satSignature[2], 5686 SataDevice->satDevData.satSignature[3], 5687 SataDevice->satDevData.satSignature[4])); 5688 /* 5689 no longer, discovery sends sata identify device command 5690 tdsaSATAIdentifyDeviceCmdSend(tiRoot, SataDevice); 5691 */ 5692 SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice); 5693 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice); 5694 } 5695 else 5696 { 5697 TI_DBG3(("tdsaReportPhySataRcvd: getting next stp bride\n")); 5698 SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice); 5699 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice); 5700 } 5701 } 5702 else 5703 { 5704 TI_DBG3(("tdsaReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n", 5705 frameHeader->smpFunctionResult)); 5706 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 5707 } 5708 return; 5709 } 5710 5711 /***************************************************************************** 5712 *! \brief tdsaSASExpanderUpStreamPhyAdd 5713 * 5714 * Purpose: This function adds upstream expander to a specfic phy. 5715 * 5716 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5717 * instance. 5718 * \param oneExpander: Pointer to the expander data. 5719 * \param phyId: Phy Identifier. 5720 * 5721 * \return: 5722 * None 5723 * 5724 * \note: 5725 * 5726 *****************************************************************************/ 5727 osGLOBAL void 5728 tdsaSASExpanderUpStreamPhyAdd( 5729 tiRoot_t *tiRoot, 5730 tdsaExpander_t *oneExpander, 5731 bit8 phyId 5732 ) 5733 { 5734 bit32 i; 5735 bit32 hasSet = agFALSE; 5736 5737 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: start, phyid %d\n", phyId)); 5738 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 5739 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 5740 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 5741 5742 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 5743 { 5744 if ( oneExpander->upStreamPhys[i] == phyId ) 5745 { 5746 hasSet = agTRUE; 5747 break; 5748 } 5749 } 5750 5751 if ( hasSet == agFALSE ) 5752 { 5753 oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId; 5754 } 5755 5756 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys)); 5757 5758 /* for debugging */ 5759 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ ) 5760 { 5761 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i])); 5762 } 5763 return; 5764 } 5765 5766 /* 5767 just add phys in downstream in configurable expnader 5768 */ 5769 /***************************************************************************** 5770 *! \brief tdsaSASExpanderDownStreamPhyAdd 5771 * 5772 * Purpose: This function adds downstream expander to a specfic phy. 5773 * 5774 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5775 * instance. 5776 * \param oneExpander: Pointer to the expander data. 5777 * \param phyId: Phy Identifier. 5778 * 5779 * \return: 5780 * None 5781 * 5782 * \note: 5783 * 5784 *****************************************************************************/ 5785 osGLOBAL void 5786 tdsaSASExpanderDownStreamPhyAdd( 5787 tiRoot_t *tiRoot, 5788 tdsaExpander_t *oneExpander, 5789 bit8 phyId 5790 ) 5791 { 5792 bit32 i; 5793 bit32 hasSet = agFALSE; 5794 5795 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: start, phyid %d\n", phyId)); 5796 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 5797 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 5798 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 5799 5800 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 5801 { 5802 if ( oneExpander->downStreamPhys[i] == phyId ) 5803 { 5804 hasSet = agTRUE; 5805 break; 5806 } 5807 } 5808 5809 if ( hasSet == agFALSE ) 5810 { 5811 oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId; 5812 } 5813 5814 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys)); 5815 5816 /* for debugging */ 5817 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ ) 5818 { 5819 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i])); 5820 } 5821 return; 5822 } 5823 5824 /* oneExpander is the configurable expander of interest 5825 phyId is the first phyID in upStreamPhys[0] of downExpander 5826 */ 5827 /***************************************************************************** 5828 *! \brief tdsaFindCurrentDownStreamPhyIndex 5829 * 5830 * Purpose: This function finds CurrentDownStreamPhyIndex from a configurable 5831 * expander. 5832 * 5833 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5834 * instance. 5835 * \param oneExpander: Pointer to the configuralbe expander data. 5836 * 5837 * \return: 5838 * CurrentDownStreamPhyIndex 5839 * 5840 * 5841 *****************************************************************************/ 5842 osGLOBAL bit16 5843 tdsaFindCurrentDownStreamPhyIndex( 5844 tiRoot_t *tiRoot, 5845 tdsaExpander_t *oneExpander 5846 ) 5847 { 5848 tdsaExpander_t *DownStreamExpander; 5849 bit16 index = 0; 5850 bit16 i; 5851 bit8 phyId = 0; 5852 5853 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: start\n")); 5854 5855 if (oneExpander == agNULL) 5856 { 5857 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! oneExpander is NULL\n")); 5858 return 0; 5859 } 5860 5861 DownStreamExpander = oneExpander->tdCurrentDownStreamExpander; 5862 5863 if (DownStreamExpander == agNULL) 5864 { 5865 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! DownStreamExpander is NULL\n")); 5866 return 0; 5867 } 5868 5869 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: exp addrHi 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressHi)); 5870 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: exp addrLo 0x%08x\n", oneExpander->tdDevice->SASAddressID.sasAddressLo)); 5871 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: downstream exp addrHi 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressHi)); 5872 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: downstream exp addrLo 0x%08x\n", DownStreamExpander->tdDevice->SASAddressID.sasAddressLo)); 5873 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: numOfDownStreamPhys %d\n", oneExpander->numOfDownStreamPhys)); 5874 5875 phyId = DownStreamExpander->upStreamPhys[0]; 5876 5877 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: phyId %d\n", phyId)); 5878 5879 for (i=0; i<oneExpander->numOfDownStreamPhys;i++) 5880 { 5881 if (oneExpander->downStreamPhys[i] == phyId) 5882 { 5883 index = i; 5884 break; 5885 } 5886 } 5887 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: index %d\n", index)); 5888 return index; 5889 } 5890 /***************************************************************************** 5891 *! \brief tdsaPortSASDeviceFind 5892 * 5893 * Purpose: Given SAS address, this function finds a device with that SAS address 5894 * in the device list. 5895 * 5896 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5897 * instance. 5898 * \param onePortContext: Pointer to the portal context instance. 5899 * \param sasAddrLo: Lower 4 byte of SAS address. 5900 * \param sasAddrHi: Upper 4 byte of SAS address. 5901 * 5902 * \return: 5903 * agNULL When no device found 5904 * Pointer to device When device is found 5905 * 5906 * \note: 5907 * 5908 *****************************************************************************/ 5909 osGLOBAL tdsaDeviceData_t * 5910 tdsaPortSASDeviceFind( 5911 tiRoot_t *tiRoot, 5912 tdsaPortContext_t *onePortContext, 5913 bit32 sasAddrLo, 5914 bit32 sasAddrHi 5915 ) 5916 { 5917 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 5918 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 5919 tdsaDeviceData_t *oneDeviceData, *RetDeviceData=agNULL; 5920 tdList_t *DeviceListList; 5921 5922 TI_DBG3(("tdsaPortSASDeviceFind: start\n")); 5923 5924 TD_ASSERT((agNULL != tiRoot), ""); 5925 TD_ASSERT((agNULL != onePortContext), ""); 5926 5927 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK); 5928 5929 /* find a device's existence */ 5930 DeviceListList = tdsaAllShared->MainDeviceList.flink; 5931 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 5932 { 5933 TI_DBG3(("tdsaPortSASDeviceFind: Full discovery\n")); 5934 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 5935 { 5936 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 5937 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 5938 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 5939 (oneDeviceData->valid == agTRUE) && 5940 (oneDeviceData->tdPortContext == onePortContext) 5941 ) 5942 { 5943 TI_DBG3(("tdsaPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 5944 TI_DBG3(("tdsaPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 5945 TI_DBG3(("tdsaPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 5946 RetDeviceData = oneDeviceData; 5947 break; 5948 } 5949 DeviceListList = DeviceListList->flink; 5950 } 5951 } 5952 else 5953 { 5954 /* incremental discovery */ 5955 TI_DBG3(("tdsaPortSASDeviceFind: Incremental discovery\n")); 5956 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 5957 { 5958 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 5959 if ((oneDeviceData->SASAddressID.sasAddressHi == sasAddrHi) && 5960 (oneDeviceData->SASAddressID.sasAddressLo == sasAddrLo) && 5961 (oneDeviceData->valid2 == agTRUE) && 5962 (oneDeviceData->tdPortContext == onePortContext) 5963 ) 5964 { 5965 TI_DBG3(("tdsaPortSASDeviceFind: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 5966 TI_DBG3(("tdsaPortSASDeviceFind: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 5967 TI_DBG3(("tdsaPortSASDeviceFind: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 5968 5969 RetDeviceData = oneDeviceData; 5970 break; 5971 } 5972 DeviceListList = DeviceListList->flink; 5973 } 5974 } 5975 5976 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK); 5977 5978 return RetDeviceData; 5979 } 5980 5981 /* include both sas and stp-sata targets*/ 5982 /***************************************************************************** 5983 *! \brief tdsaPortSASDeviceAdd 5984 * 5985 * Purpose: This function adds the SAS device to the device list. 5986 * 5987 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 5988 * instance. 5989 * \param onePortContext: Pointer to the portal context instance. 5990 * \param sasIdentify: SAS identify address frame. 5991 * \param sasInitiator: SAS initiator. 5992 * \param connectionRate: Connection Rate. 5993 * \param itNexusTimeout: IT NEXUS timeout value. 5994 * \param firstBurstSize: First Burst Size. 5995 * \param deviceType: Device Type. 5996 * 5997 * \return: 5998 * Pointer to device data. 5999 * 6000 * \note: 6001 * 6002 *****************************************************************************/ 6003 GLOBAL tdsaDeviceData_t * 6004 tdsaPortSASDeviceAdd( 6005 tiRoot_t *tiRoot, 6006 tdsaPortContext_t *onePortContext, 6007 agsaSASIdentify_t sasIdentify, 6008 bit32 sasInitiator, 6009 bit8 connectionRate, 6010 bit32 itNexusTimeout, 6011 bit32 firstBurstSize, 6012 bit32 deviceType, 6013 tdsaDeviceData_t *oneExpDeviceData, 6014 bit8 phyID 6015 ) 6016 { 6017 tdsaDeviceData_t *oneDeviceData = agNULL; 6018 bit8 dev_s_rate = 0; 6019 bit8 sasorsata = 1; 6020 // bit8 devicetype; 6021 tdsaSASSubID_t agSASSubID; 6022 tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL; 6023 6024 TI_DBG3(("tdsaPortSASDeviceAdd: start\n")); 6025 TI_DBG3(("tdsaPortSASDeviceAdd: connectionRate %d\n", connectionRate)); 6026 6027 agSASSubID.sasAddressHi = SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify); 6028 agSASSubID.sasAddressLo = SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify); 6029 agSASSubID.initiator_ssp_stp_smp = sasIdentify.initiator_ssp_stp_smp; 6030 agSASSubID.target_ssp_stp_smp = sasIdentify.target_ssp_stp_smp; 6031 6032 /* old device and already registered to LL; added by link-up event */ 6033 if ( agFALSE == tdssNewSASorNot( 6034 onePortContext->agRoot, 6035 onePortContext, 6036 &agSASSubID 6037 ) 6038 ) 6039 { 6040 /* old device and already registered to LL; added by link-up event */ 6041 TI_DBG3(("tdsaPortSASDeviceAdd: OLD qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", agSASSubID.initiator_ssp_stp_smp, agSASSubID.target_ssp_stp_smp)); 6042 /* find the old device */ 6043 oneDeviceData = tdssNewAddSASToSharedcontext( 6044 onePortContext->agRoot, 6045 onePortContext, 6046 &agSASSubID, 6047 oneExpDeviceData, 6048 phyID 6049 ); 6050 6051 if (oneDeviceData == agNULL) 6052 { 6053 TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n")); 6054 } 6055 6056 /* If a device is allocated */ 6057 if ( oneDeviceData != agNULL ) 6058 { 6059 6060 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 6061 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 6062 6063 oneDeviceData->sasIdentify = sasIdentify; 6064 6065 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 6066 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 6067 6068 /* parse sasIDframe to fill in agDeviceInfo */ 6069 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 6070 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 6071 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 6072 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 6073 6074 oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify)); 6075 6076 /* adjusting connectionRate */ 6077 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 6078 if (oneAttachedExpDeviceData != agNULL) 6079 { 6080 connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6081 TI_DBG3(("tdsaPortSASDeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 6082 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6083 } 6084 else 6085 { 6086 TI_DBG3(("tdsaPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n")); 6087 } 6088 6089 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 6090 sasorsata = (bit8)deviceType; 6091 /* sTSDK spec device typ */ 6092 dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4)); 6093 dev_s_rate = (bit8)(dev_s_rate | connectionRate); 6094 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 6095 6096 6097 DEVINFO_PUT_SAS_ADDRESSLO( 6098 &oneDeviceData->agDeviceInfo, 6099 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 6100 ); 6101 DEVINFO_PUT_SAS_ADDRESSHI( 6102 &oneDeviceData->agDeviceInfo, 6103 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 6104 ); 6105 oneDeviceData->agContext.osData = oneDeviceData; 6106 oneDeviceData->agContext.sdkData = agNULL; 6107 6108 } 6109 return oneDeviceData; 6110 } /* old device */ 6111 6112 /* new device */ 6113 6114 TI_DBG3(("tdsaPortSASDeviceAdd: NEW qqqq initiator_ssp_stp_smp %d target_ssp_stp_smp %d\n", agSASSubID.initiator_ssp_stp_smp, agSASSubID.target_ssp_stp_smp)); 6115 6116 /* allocate a new device and set the valid bit */ 6117 oneDeviceData = tdssNewAddSASToSharedcontext( 6118 onePortContext->agRoot, 6119 onePortContext, 6120 &agSASSubID, 6121 oneExpDeviceData, 6122 phyID 6123 ); 6124 6125 if (oneDeviceData == agNULL) 6126 { 6127 TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n")); 6128 } 6129 6130 /* If a device is allocated */ 6131 if ( oneDeviceData != agNULL ) 6132 { 6133 6134 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&sasIdentify))); 6135 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&sasIdentify))); 6136 6137 oneDeviceData->sasIdentify = sasIdentify; 6138 6139 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 6140 TI_DBG3(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 6141 6142 6143 /* parse sasIDframe to fill in agDeviceInfo */ 6144 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 6145 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, (bit16)itNexusTimeout); 6146 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, (bit16)firstBurstSize); 6147 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, 1); 6148 6149 oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify)); 6150 6151 /* adjusting connectionRate */ 6152 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 6153 if (oneAttachedExpDeviceData != agNULL) 6154 { 6155 connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6156 TI_DBG3(("tdsaPortSASDeviceAdd: 2nd connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 6157 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6158 } 6159 else 6160 { 6161 TI_DBG3(("tdsaPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n")); 6162 } 6163 6164 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0 */ 6165 sasorsata = (bit8)deviceType; 6166 dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4)); 6167 dev_s_rate = (bit8)(dev_s_rate | connectionRate); 6168 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 6169 6170 6171 DEVINFO_PUT_SAS_ADDRESSLO( 6172 &oneDeviceData->agDeviceInfo, 6173 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify) 6174 ); 6175 DEVINFO_PUT_SAS_ADDRESSHI( 6176 &oneDeviceData->agDeviceInfo, 6177 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify) 6178 ); 6179 oneDeviceData->agContext.osData = oneDeviceData; 6180 oneDeviceData->agContext.sdkData = agNULL; 6181 6182 TI_DBG3(("tdsaPortSASDeviceAdd: did %d\n", oneDeviceData->id)); 6183 6184 /* don't add and register initiator for T2D */ 6185 if ( (((sasIdentify.initiator_ssp_stp_smp & DEVICE_SSP_BIT) == DEVICE_SSP_BIT) && 6186 ((sasIdentify.target_ssp_stp_smp & DEVICE_SSP_BIT) != DEVICE_SSP_BIT)) 6187 || 6188 (((sasIdentify.initiator_ssp_stp_smp & DEVICE_STP_BIT) == DEVICE_STP_BIT) && 6189 ((sasIdentify.target_ssp_stp_smp & DEVICE_SSP_BIT) != DEVICE_SSP_BIT)) 6190 ) 6191 { 6192 TI_DBG1(("tdsaPortSASDeviceAdd: initiator. no add and registration\n")); 6193 TI_DBG1(("tdsaPortSASDeviceAdd: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 6194 TI_DBG1(("tdsaPortSASDeviceAdd: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 6195 6196 } 6197 else 6198 { 6199 if (oneDeviceData->registered == agFALSE) 6200 { 6201 TI_DBG2(("tdsaPortSASDeviceAdd: did %d\n", oneDeviceData->id)); 6202 saRegisterNewDevice( /* tdsaPortSASDeviceAdd */ 6203 onePortContext->agRoot, 6204 &oneDeviceData->agContext, 6205 tdsaRotateQnumber(tiRoot, oneDeviceData), 6206 &oneDeviceData->agDeviceInfo, 6207 onePortContext->agPortContext, 6208 0 6209 ); 6210 } 6211 } 6212 } 6213 6214 return oneDeviceData; 6215 } 6216 6217 /***************************************************************************** 6218 *! \brief tdsaDiscoveryResetProcessed 6219 * 6220 * Purpose: This function called to reset "processed flag" of device belong to 6221 * a specified port. 6222 * 6223 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6224 * instance. 6225 * \param onePortContext: Pointer to the portal context instance. 6226 * 6227 * \return: 6228 * None 6229 * 6230 * \note: 6231 * 6232 *****************************************************************************/ 6233 6234 osGLOBAL void 6235 tdsaDiscoveryResetProcessed( 6236 tiRoot_t *tiRoot, 6237 tdsaPortContext_t *onePortContext 6238 ) 6239 { 6240 tdsaDeviceData_t *oneDeviceData = agNULL; 6241 tdList_t *DeviceListList; 6242 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 6243 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 6244 6245 TI_DBG6(("tdsaDiscoveryResetProcessed: start\n")); 6246 6247 /* reinitialize the device data belonging to this portcontext */ 6248 DeviceListList = tdsaAllShared->MainDeviceList.flink; 6249 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 6250 { 6251 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6252 TI_DBG6(("tdsaDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id)); 6253 if (oneDeviceData->tdPortContext == onePortContext) 6254 { 6255 TI_DBG6(("tdsaDiscoveryResetProcessed: resetting procssed flag\n")); 6256 oneDeviceData->processed = agFALSE; 6257 } 6258 DeviceListList = DeviceListList->flink; 6259 } 6260 6261 return; 6262 } 6263 6264 /***************************************************************************** 6265 *! \brief tdsaSATADiscoverDone 6266 * 6267 * Purpose: This function called to finish up SATA discovery. 6268 * 6269 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6270 * instance. 6271 * \param onePortContext: Pointer to the portal context instance. 6272 * \param flag: status of discovery (success or failure). 6273 * 6274 * \return: 6275 * None 6276 * 6277 * \note: 6278 * 6279 *****************************************************************************/ 6280 osGLOBAL void 6281 tdsaSATADiscoverDone( 6282 tiRoot_t *tiRoot, 6283 tdsaPortContext_t *onePortContext, 6284 bit32 flag 6285 ) 6286 { 6287 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 6288 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 6289 TI_DBG3(("tdsaSATADiscoverDone: start\n")); 6290 tdsaDiscoveryResetProcessed(tiRoot, onePortContext); 6291 6292 if (onePortContext->discovery.SeenBC == agTRUE) 6293 { 6294 TI_DBG3(("tdsaSATADiscoverDone: broadcast change; discover again\n")); 6295 tdssInternalRemovals(onePortContext->agRoot, 6296 onePortContext 6297 ); 6298 6299 /* processed broadcast change */ 6300 onePortContext->discovery.SeenBC = agFALSE; 6301 if (tdsaAllShared->ResetInDiscovery != 0 && 6302 onePortContext->discovery.ResetTriggerred == agTRUE) 6303 { 6304 TI_DBG1(("tdsaSATADiscoverDone: tdsaBCTimer\n")); 6305 tdsaBCTimer(tiRoot, onePortContext); 6306 } 6307 else 6308 { 6309 tdsaDiscover( 6310 tiRoot, 6311 onePortContext, 6312 TDSA_DISCOVERY_TYPE_SAS, 6313 TDSA_DISCOVERY_OPTION_INCREMENTAL_START 6314 ); 6315 } 6316 } 6317 else 6318 { 6319 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED; 6320 6321 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START) 6322 { 6323 if (flag == tiSuccess) 6324 { 6325 #ifdef AGTIAPI_CTL 6326 tdsaContext_t *tdsaAllShared = 6327 &((tdsaRoot_t*)tiRoot->tdData)->tdsaAllShared; 6328 6329 if (tdsaAllShared->SASConnectTimeLimit) 6330 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery, 6331 tiDiscOK); 6332 else 6333 #endif 6334 ostiInitiatorEvent( 6335 tiRoot, 6336 onePortContext->tiPortalContext, 6337 agNULL, 6338 tiIntrEventTypeDiscovery, 6339 tiDiscOK, 6340 agNULL 6341 ); 6342 } 6343 else 6344 { 6345 TI_DBG1(("tdsaSATADiscoverDone: Error; clean up\n")); 6346 tdssDiscoveryErrorRemovals(onePortContext->agRoot, 6347 onePortContext 6348 ); 6349 6350 ostiInitiatorEvent( 6351 tiRoot, 6352 onePortContext->tiPortalContext, 6353 agNULL, 6354 tiIntrEventTypeDiscovery, 6355 tiDiscFailed, 6356 agNULL 6357 ); 6358 } 6359 } 6360 else 6361 { 6362 if (flag == tiSuccess) 6363 { 6364 tdssReportChanges(onePortContext->agRoot, 6365 onePortContext 6366 ); 6367 } 6368 else 6369 { 6370 tdssReportRemovals(onePortContext->agRoot, 6371 onePortContext, 6372 agFALSE 6373 ); 6374 } 6375 } 6376 } 6377 #ifdef TBD 6378 /* ACKing BC */ 6379 tdsaAckBC(tiRoot, onePortContext); 6380 #endif 6381 return; 6382 } 6383 6384 osGLOBAL void 6385 tdsaAckBC( 6386 tiRoot_t *tiRoot, 6387 tdsaPortContext_t *onePortContext 6388 ) 6389 { 6390 #ifdef TBD /* not yet */ 6391 agsaEventSource_t eventSource[TD_MAX_NUM_PHYS]; 6392 bit32 HwAckSatus = AGSA_RC_SUCCESS; 6393 int i; 6394 TI_DBG3(("tdsaAckBC: start\n")); 6395 6396 for (i=0;i<TD_MAX_NUM_PHYS;i++) 6397 { 6398 if (onePortContext->BCPhyID[i] == agTRUE) 6399 { 6400 /* saHwEventAck() */ 6401 eventSource[i].agPortContext = onePortContext->agPortContext; 6402 eventSource[i].event = OSSA_HW_EVENT_BROADCAST_CHANGE; 6403 /* phy ID */ 6404 eventSource[i].param = i; 6405 HwAckSatus = saHwEventAck( 6406 onePortContext->agRoot, 6407 agNULL, /* agContext */ 6408 0, 6409 &eventSource[i], /* agsaEventSource_t */ 6410 0, 6411 0 6412 ); 6413 TI_DBG3(("tdsaAckBC: calling saHwEventAck\n")); 6414 6415 if ( HwAckSatus != AGSA_RC_SUCCESS) 6416 { 6417 TI_DBG1(("tdsaAckBC: failing in saHwEventAck; status %d\n", HwAckSatus)); 6418 return; 6419 } 6420 } 6421 onePortContext->BCPhyID[i] = agFALSE; 6422 } 6423 #endif 6424 } 6425 6426 #ifdef SATA_ENABLE 6427 6428 /***************************************************************************** 6429 *! \brief tdsaSATAFullDiscover 6430 * 6431 * Purpose: This function is called to trigger full SATA topology discovery 6432 * within a portcontext. 6433 * 6434 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6435 * instance. 6436 * \param onePortContext: Pointer to the portal context instance. 6437 * 6438 * \return: 6439 * tiSuccess Discovery initiated. 6440 * tiError Discovery could not be initiated at this time. 6441 * 6442 * \note: 6443 * 6444 *****************************************************************************/ 6445 osGLOBAL bit32 6446 tdsaSATAFullDiscover( 6447 tiRoot_t *tiRoot, 6448 tdsaPortContext_t *onePortContext 6449 ) 6450 { 6451 bit32 ret = tiSuccess; 6452 tdsaDeviceData_t *oneDeviceData = agNULL; 6453 bit32 deviceType; 6454 bit8 phyRate = SAS_CONNECTION_RATE_3_0G; 6455 bit32 i; 6456 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 6457 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 6458 // tdsaDeviceData_t *tdsaDeviceData = (tdsaDeviceData_t *)tdsaAllShared->DeviceMem; 6459 tdsaDeviceData_t *tdsaDeviceData; 6460 tdList_t *DeviceListList; 6461 6462 TI_DBG3(("tdsaSATAFullDiscover: start\n")); 6463 if (onePortContext->valid == agFALSE) 6464 { 6465 TI_DBG1(("tdsaSATAFullDiscover: aborting discovery\n")); 6466 tdsaSASDiscoverAbort(tiRoot, onePortContext); 6467 return tiError; 6468 } 6469 phyRate = onePortContext->LinkRate; 6470 DeviceListList = tdsaAllShared->MainDeviceList.flink; 6471 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6472 /* If port is SATA mode */ 6473 /* 6474 Native SATA mode is decided in ossaHWCB() SAS_LINK_UP or SATA_LINK_UP 6475 */ 6476 if (onePortContext->nativeSATAMode == agTRUE) 6477 { 6478 /* Decode device type */ 6479 deviceType = tdssSATADeviceTypeDecode(onePortContext->remoteSignature); 6480 /* Create a device descriptor for the SATA device attached to the port */ 6481 if ( deviceType == SATA_PM_DEVICE) 6482 { 6483 TI_DBG3(("tdsaSATAFullDiscover: Found a PM device\n")); 6484 oneDeviceData = tdsaPortSATADeviceAdd( 6485 tiRoot, 6486 onePortContext, 6487 agNULL, 6488 onePortContext->remoteSignature, 6489 agTRUE, 6490 0xF, 6491 phyRate, 6492 agNULL, 6493 0xFF 6494 ); 6495 } 6496 else 6497 { 6498 /* already added in ossahwcb() in SATA link up */ 6499 TI_DBG3(("tdsaSATAFullDiscover: Found a DIRECT SATA device\n")); 6500 } 6501 6502 /* Process for different device type */ 6503 switch ( deviceType ) 6504 { 6505 /* if it's PM */ 6506 case SATA_PM_DEVICE: 6507 { 6508 6509 TI_DBG3(("tdsaSATAFullDiscover: Process a PM device\n")); 6510 /* For each port of the PM */ 6511 for ( i = 0; i < SATA_MAX_PM_PORTS; i ++ ) 6512 { 6513 /* Read the signature */ 6514 /* Decode the device type */ 6515 /* Create device descriptor */ 6516 /* Callback with the discovered devices */ 6517 } 6518 break; 6519 } 6520 /* if it's ATA device */ 6521 case SATA_ATA_DEVICE: 6522 case SATA_ATAPI_DEVICE: 6523 { 6524 TI_DBG3(("tdsaSATAFullDiscover: Process an ATA device. Sending Identify Device cmd\n")); 6525 6526 /* to-check: for this direct attached one, already added and do nothing */ 6527 /* no longer, discovery sends sata identify device command */ 6528 //tdsaSATAIdentifyDeviceCmdSend(tiRoot, oneDeviceData); 6529 tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess); 6530 break; 6531 } 6532 /* Other devices */ 6533 default: 6534 { 6535 /* callback */ 6536 TI_DBG3(("siSATAFullDiscover: Process OTHER SATA device. Just report the device\n")); 6537 break; 6538 } 6539 } 6540 } 6541 /* If port is SAS mode */ 6542 else 6543 { 6544 TI_DBG3(("tdsaSATAFullDiscover: Discovering attached STP devices starts....\n")); 6545 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData); 6546 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData); 6547 } 6548 return ret; 6549 } 6550 6551 /* adding only direct attached SATA such as PM 6552 Other directly attached SATA device such as disk is reported by ossahwcb() in link up 6553 used in sata native mode 6554 */ 6555 /***************************************************************************** 6556 *! \brief tdsaPortSATADeviceAdd 6557 * 6558 * Purpose: This function adds the SATA device to the device list. 6559 * 6560 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6561 * instance. 6562 * \param onePortContext: Pointer to the portal context instance. 6563 * \param oneSTPBridge: STP bridge. 6564 * \param Signature: SATA signature. 6565 * \param pm: Port Multiplier. 6566 * \param pmField: Port Multiplier field. 6567 * \param connectionRate: Connection Rate. 6568 * 6569 * \return: 6570 * Pointer to device data. 6571 * 6572 * \note: 6573 * 6574 *****************************************************************************/ 6575 GLOBAL tdsaDeviceData_t * 6576 tdsaPortSATADeviceAdd( 6577 tiRoot_t *tiRoot, 6578 tdsaPortContext_t *onePortContext, 6579 tdsaDeviceData_t *oneSTPBridge, 6580 bit8 *Signature, 6581 bit8 pm, 6582 bit8 pmField, 6583 bit8 connectionRate, 6584 tdsaDeviceData_t *oneExpDeviceData, 6585 bit8 phyID 6586 ) 6587 { 6588 tdsaDeviceData_t *oneDeviceData = agNULL; 6589 agsaRoot_t *agRoot = onePortContext->agRoot; 6590 bit8 dev_s_rate = 0; 6591 bit8 sasorsata = SATA_DEVICE_TYPE; 6592 // bit8 devicetype = 0; 6593 bit8 flag = 0; 6594 bit8 TLR = 0; 6595 tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL; 6596 6597 TI_DBG3(("tdsaPortSATADeviceAdd: start\n")); 6598 6599 /* sanity check */ 6600 TD_ASSERT((agNULL != tiRoot), ""); 6601 TD_ASSERT((agNULL != agRoot), ""); 6602 TD_ASSERT((agNULL != onePortContext), ""); 6603 TD_ASSERT((agNULL != Signature), ""); 6604 6605 oneDeviceData = tdssNewAddSATAToSharedcontext( 6606 tiRoot, 6607 agRoot, 6608 onePortContext, 6609 agNULL, 6610 Signature, 6611 pm, 6612 pmField, 6613 connectionRate, 6614 oneExpDeviceData, 6615 phyID 6616 ); 6617 if (oneDeviceData == agNULL) 6618 { 6619 TI_DBG1(("tdsaPortSATADeviceAdd: no more device!!! oneDeviceData is null\n")); 6620 return agNULL; 6621 } 6622 6623 flag = (bit8)((phyID << 4) | TLR); 6624 DEVINFO_PUT_SMPTO(&oneDeviceData->agDeviceInfo, DEFAULT_SMP_TIMEOUT); 6625 DEVINFO_PUT_ITNEXUSTO(&oneDeviceData->agDeviceInfo, 0xFFF); 6626 DEVINFO_PUT_FBS(&oneDeviceData->agDeviceInfo, 0); 6627 DEVINFO_PUT_FLAG(&oneDeviceData->agDeviceInfo, flag); 6628 6629 /* adjusting connectionRate */ 6630 oneAttachedExpDeviceData = oneDeviceData->ExpDevice; 6631 if (oneAttachedExpDeviceData != agNULL) 6632 { 6633 connectionRate = (bit8)(MIN(connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6634 TI_DBG3(("tdsaPortSATADeviceAdd: 1st connectionRate 0x%x DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo) 0x%x\n", 6635 connectionRate, DEVINFO_GET_LINKRATE(&oneAttachedExpDeviceData->agDeviceInfo))); 6636 } 6637 else 6638 { 6639 TI_DBG3(("tdsaPortSATADeviceAdd: 1st oneAttachedExpDeviceData is NULL\n")); 6640 } 6641 6642 /* Device Type, SAS or SATA, connection rate; bit7 --- bit0*/ 6643 // dev_s_rate = dev_s_rate | (devicetype << 6); 6644 dev_s_rate = (bit8)(dev_s_rate | (sasorsata << 4)); 6645 dev_s_rate = (bit8)(dev_s_rate | connectionRate); 6646 DEVINFO_PUT_DEV_S_RATE(&oneDeviceData->agDeviceInfo, dev_s_rate); 6647 6648 osti_memset(&oneDeviceData->agDeviceInfo.sasAddressHi, 0, 4); 6649 osti_memset(&oneDeviceData->agDeviceInfo.sasAddressLo, 0, 4); 6650 6651 oneDeviceData->agContext.osData = oneDeviceData; 6652 oneDeviceData->agContext.sdkData = agNULL; 6653 6654 TI_DBG1(("tdsaPortSATADeviceAdd: did %d\n", oneDeviceData->id)); 6655 if (oneDeviceData->registered == agFALSE) 6656 { 6657 TI_DBG2(("tdsaPortSATADeviceAdd: did %d\n", oneDeviceData->id)); 6658 saRegisterNewDevice( /* tdsaPortSATADeviceAdd */ 6659 onePortContext->agRoot, 6660 &oneDeviceData->agContext, 6661 tdsaRotateQnumber(tiRoot, oneDeviceData), 6662 &oneDeviceData->agDeviceInfo, 6663 onePortContext->agPortContext, 6664 0 6665 ); 6666 } 6667 6668 return oneDeviceData; 6669 } 6670 #endif 6671 6672 /***************************************************************************** 6673 *! \brief tdsaFindRightDevice 6674 * 6675 * Purpose: This function returns device-to-be processed. 6676 * 6677 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6678 * instance. 6679 * \param onePortContext: Pointer to the portal context instance. 6680 * \param tdsaDeviceData: Pointer to the starting device data. 6681 * 6682 * \return: 6683 * Pointer to device data. 6684 * 6685 * \note: 6686 * 6687 *****************************************************************************/ 6688 osGLOBAL tdsaDeviceData_t * 6689 tdsaFindRightDevice( 6690 tiRoot_t *tiRoot, 6691 tdsaPortContext_t *onePortContext, 6692 tdsaDeviceData_t *tdsaDeviceData 6693 ) 6694 { 6695 tdList_t *DeviceListList; 6696 tdsaDeviceData_t *oneDeviceData = agNULL; 6697 bit32 found = agFALSE; 6698 6699 TI_DBG3(("tdsaFindHeadDevice: start\n")); 6700 6701 DeviceListList = tdsaDeviceData->MainLink.flink; 6702 6703 while (DeviceListList != &(tdsaDeviceData->MainLink)) 6704 { 6705 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6706 TI_DBG3(("tdsaFindRightDevice: did %d STP %d SATA %d \n", onePortContext->id, DEVICE_IS_STP_TARGET(oneDeviceData), DEVICE_IS_SATA_DEVICE(oneDeviceData))); 6707 DeviceListList = DeviceListList->flink; 6708 } 6709 6710 DeviceListList = tdsaDeviceData->MainLink.flink; 6711 6712 while (DeviceListList != &(tdsaDeviceData->MainLink)) 6713 { 6714 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6715 if ((oneDeviceData->registered == agTRUE) && 6716 (oneDeviceData->tdPortContext == onePortContext) && 6717 (oneDeviceData->processed == agFALSE) && 6718 (SA_IDFRM_IS_STP_TARGET(&oneDeviceData->sasIdentify) || 6719 SA_IDFRM_IS_SATA_DEVICE(&oneDeviceData->sasIdentify)) 6720 ) 6721 { 6722 TI_DBG3(("tdsaFindRightDevice: pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 6723 oneDeviceData->processed = agTRUE; 6724 found = agTRUE; 6725 break; 6726 } 6727 DeviceListList = DeviceListList->flink; 6728 } 6729 6730 if (found == agTRUE) 6731 { 6732 return oneDeviceData; 6733 } 6734 else 6735 { 6736 return agNULL; 6737 } 6738 } 6739 6740 6741 6742 // tdsaDeviceData is head of list 6743 /***************************************************************************** 6744 *! \brief tdsaDiscoveringStpSATADevice 6745 * 6746 * Purpose: For each device in the device list, this function peforms 6747 * SATA discovery. 6748 * 6749 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6750 * instance. 6751 * \param onePortContext: Pointer to the portal context instance. 6752 * \param oneDeviceData: Pointer to the heade of device list. 6753 * 6754 * \return: 6755 * None 6756 * 6757 * \note: 6758 * 6759 *****************************************************************************/ 6760 osGLOBAL void 6761 tdsaDiscoveringStpSATADevice( 6762 tiRoot_t *tiRoot, 6763 tdsaPortContext_t *onePortContext, 6764 tdsaDeviceData_t *oneDeviceData 6765 ) 6766 { 6767 bit32 status; 6768 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 6769 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 6770 // tdsaDeviceData_t *tdsaDeviceData = (tdsaDeviceData_t *)tdsaAllShared->DeviceMem; 6771 tdsaDeviceData_t *tdsaDeviceData; 6772 tdList_t *DeviceListList; 6773 6774 TI_DBG3(("tdsaDiscoveringStpSATADevice: start\n")); 6775 6776 DeviceListList = tdsaAllShared->MainDeviceList.flink; 6777 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6778 6779 if (oneDeviceData) 6780 { 6781 TI_DBG3(("tdsaDiscoveringStpSATADevice: Found STP-SATA Device=%p\n", oneDeviceData)); 6782 if ((SA_IDFRM_IS_SATA_DEVICE(&oneDeviceData->sasIdentify) || SA_IDFRM_IS_STP_TARGET(&oneDeviceData->sasIdentify)) 6783 && 6784 ((onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START && 6785 oneDeviceData->valid == agTRUE) || 6786 (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START && 6787 oneDeviceData->valid2 == agTRUE)) && 6788 (oneDeviceData->tdPortContext == onePortContext) 6789 ) 6790 { 6791 /* if found an STP bridges */ 6792 /* in order to get sata signature and etc */ 6793 TI_DBG3(("tdsaDiscoveringStpSATADevice: sending report phy sata\n")); 6794 tdsaReportPhySataSend(tiRoot, oneDeviceData, oneDeviceData->sasIdentify.phyIdentifier); 6795 //send ID in every discovery? No 6796 if (oneDeviceData->satDevData.IDDeviceValid == agFALSE) 6797 { 6798 TI_DBG3(("tdsaDiscoveringStpSATADevice: sending identify device data\n")); 6799 /* all internal */ 6800 status = tdsaDiscoveryStartIDDev(tiRoot, 6801 agNULL, 6802 &(oneDeviceData->tiDeviceHandle), 6803 agNULL, 6804 oneDeviceData); 6805 6806 if (status != tiSuccess) 6807 { 6808 /* identify device data is not valid */ 6809 TI_DBG1(("tdsaDiscoveringStpSATADevice: fail or busy %d\n", status)); 6810 oneDeviceData->satDevData.IDDeviceValid = agFALSE; 6811 } 6812 } 6813 } 6814 else 6815 { 6816 TI_DBG2(("tdsaDiscoveringStpSATADevice: moving to the next\n")); 6817 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData); 6818 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData); 6819 } 6820 } 6821 else 6822 { 6823 /* otherwise, there is no more SATA device found */ 6824 TI_DBG3(("tdsaDiscoveringStpSATADevice: No More Device; SATA discovery finished\n")); 6825 6826 tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess); 6827 } 6828 6829 return; 6830 } 6831 6832 /***************************************************************************** 6833 *! \brief tdsaSASIncrementalDiscover 6834 * 6835 * Purpose: This function is called to trigger incremental SAS topology discovery 6836 * within a portcontext. 6837 * 6838 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6839 * instance. 6840 * \param onePortContext: Pointer to the portal context instance. 6841 * 6842 * \return: 6843 * tiSuccess Discovery initiated. 6844 * tiError Discovery could not be initiated at this time. 6845 * 6846 * \note: 6847 * 6848 *****************************************************************************/ 6849 osGLOBAL bit32 6850 tdsaSASIncrementalDiscover( 6851 tiRoot_t *tiRoot, 6852 tdsaPortContext_t *onePortContext 6853 ) 6854 { 6855 tdsaDeviceData_t *oneDeviceData = agNULL; 6856 int i,j; 6857 bit8 portMaxRate; 6858 6859 TI_DBG3(("tdsaSASIncrementalDiscover: start\n")); 6860 6861 if (onePortContext->valid == agFALSE) 6862 { 6863 TI_DBG1(("tdsaSASIncrementalDiscover: aborting discovery\n")); 6864 tdsaSASDiscoverAbort(tiRoot, onePortContext); 6865 return tiError; 6866 } 6867 6868 onePortContext->DiscoveryState = ITD_DSTATE_STARTED; 6869 6870 /* nativeSATAMode is set in ossaHwCB() in link up */ 6871 if (onePortContext->nativeSATAMode == agFALSE) /* default: SAS and SAS/SATA mode */ 6872 { 6873 if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE && 6874 SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) ) 6875 { 6876 for(i=0;i<TD_MAX_NUM_PHYS;i++) 6877 { 6878 if (onePortContext->PhyIDList[i] == agTRUE) 6879 { 6880 6881 for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++) 6882 { 6883 saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL); 6884 } 6885 break; 6886 } 6887 } 6888 } 6889 /* 6890 add the device 6891 1. add device in TD layer 6892 2. call saRegisterNewDevice 6893 3. update agDevHandle in ossaDeviceRegistrationCB() 6894 */ 6895 portMaxRate = onePortContext->LinkRate; 6896 oneDeviceData = tdsaPortSASDeviceAdd( 6897 tiRoot, 6898 onePortContext, 6899 onePortContext->sasIDframe, 6900 agFALSE, 6901 portMaxRate, 6902 IT_NEXUS_TIMEOUT, 6903 0, 6904 SAS_DEVICE_TYPE, 6905 agNULL, 6906 0xFF 6907 ); 6908 if (oneDeviceData) 6909 { 6910 if (oneDeviceData->registered == agFALSE) 6911 { 6912 /* 6913 set the timer and wait till the device(directly attached. eg Expander) to be registered. 6914 Then, in tdsaDeviceRegistrationTimerCB(), tdsaSASUpStreamDiscoverStart() is called 6915 */ 6916 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData); 6917 } 6918 else 6919 { 6920 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData); 6921 } 6922 } 6923 } 6924 else /* SATAOnlyMode*/ 6925 { 6926 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess); 6927 } 6928 return tiSuccess; 6929 } 6930 6931 #ifdef SATA_ENABLE 6932 /* For the sake of completness; this is the same as tdsaSATAFullDiscover*/ 6933 /***************************************************************************** 6934 *! \brief tdsaSATAIncrementalDiscover 6935 * 6936 * Purpose: This function is called to trigger incremental SATA topology discovery 6937 * within a portcontext. 6938 * 6939 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 6940 * instance. 6941 * \param onePortContext: Pointer to the portal context instance. 6942 * 6943 * \return: 6944 * tiSuccess Discovery initiated. 6945 * tiError Discovery could not be initiated at this time. 6946 * 6947 * \note: 6948 * 6949 *****************************************************************************/ 6950 osGLOBAL bit32 6951 tdsaSATAIncrementalDiscover( 6952 tiRoot_t *tiRoot, 6953 tdsaPortContext_t *onePortContext 6954 ) 6955 { 6956 bit32 ret = tiSuccess; 6957 tdsaDeviceData_t *oneDeviceData = agNULL; 6958 bit32 deviceType; 6959 bit8 phyRate = SAS_CONNECTION_RATE_3_0G; 6960 bit32 i; 6961 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 6962 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 6963 // tdsaDeviceData_t *tdsaDeviceData = (tdsaDeviceData_t *)tdsaAllShared->DeviceMem; 6964 tdsaDeviceData_t *tdsaDeviceData; 6965 tdList_t *DeviceListList; 6966 6967 TI_DBG3(("tdsaSATAIncrementalDiscover: start\n")); 6968 6969 if (onePortContext->valid == agFALSE) 6970 { 6971 TI_DBG1(("tdsaSATAIncrementalDiscover: aborting discovery\n")); 6972 tdsaSASDiscoverAbort(tiRoot, onePortContext); 6973 return tiError; 6974 } 6975 6976 DeviceListList = tdsaAllShared->MainDeviceList.flink; 6977 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 6978 6979 /* If port is SATA mode */ 6980 /* 6981 Native SATA mode is decided in ossaHWCB() SAS_LINK_UP or SATA_LINK_UP 6982 */ 6983 if (onePortContext->nativeSATAMode == agTRUE) 6984 { 6985 /* Decode device type */ 6986 deviceType = tdssSATADeviceTypeDecode(onePortContext->remoteSignature); 6987 /* Create a device descriptor for the SATA device attached to the port */ 6988 if ( deviceType == SATA_PM_DEVICE) 6989 { 6990 TI_DBG3(("tdsaSATAIncrementalDiscover: Found a PM device\n")); 6991 oneDeviceData = tdsaPortSATADeviceAdd( 6992 tiRoot, 6993 onePortContext, 6994 agNULL, 6995 onePortContext->remoteSignature, 6996 agTRUE, 6997 0xF, 6998 phyRate, 6999 agNULL, 7000 0xFF); 7001 } 7002 else 7003 { 7004 /* already added in ossahwcb() in SATA link up */ 7005 TI_DBG3(("tdsaSATAIncrementalDiscover: Found a DIRECT SATA device\n")); 7006 } 7007 7008 /* Process for different device type */ 7009 switch ( deviceType ) 7010 { 7011 /* if it's PM */ 7012 case SATA_PM_DEVICE: 7013 { 7014 7015 TI_DBG3(("tdsaSATAIncrementalDiscover: Process a PM device\n")); 7016 /* For each port of the PM */ 7017 for ( i = 0; i < SATA_MAX_PM_PORTS; i ++ ) 7018 { 7019 /* Read the signature */ 7020 /* Decode the device type */ 7021 /* Create device descriptor */ 7022 /* Callback with the discovered devices */ 7023 } 7024 break; 7025 } 7026 /* if it's ATA device */ 7027 case SATA_ATA_DEVICE: 7028 case SATA_ATAPI_DEVICE: 7029 { 7030 TI_DBG3(("tdsaSATAIncrementalDiscover: Process an ATA device. Sending Identify Device cmd\n")); 7031 7032 /* to-check: for this direct attached one, already added and do nothing */ 7033 /* no longer, discovery sends sata identify device command */ 7034 //tdsaSATAIdentifyDeviceCmdSend(tiRoot, oneDeviceData); 7035 7036 tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess); 7037 7038 break; 7039 } 7040 /* Other devices */ 7041 default: 7042 { 7043 /* callback */ 7044 TI_DBG3(("siSATAIncrementalDiscover: Process OTHER SATA device. Just report the device\n")); 7045 7046 break; 7047 } 7048 } 7049 } 7050 /* If port is SAS mode */ 7051 else 7052 { 7053 TI_DBG3(("tdsaSATAIncrementalDiscover: Discovering attached STP devices starts....\n")); 7054 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData); 7055 7056 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData); 7057 } 7058 return ret; 7059 7060 } 7061 #endif 7062 7063 7064 /******************** SMP *******************************/ 7065 7066 /***************************************************************************** 7067 *! \brief tdSMPStart 7068 * 7069 * Purpose: This function sends SMP request. 7070 * 7071 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7072 * instance. 7073 * \param agRoot: Pointer to chip/driver Instance. 7074 * \param oneDeviceData: Pointer to the device data. 7075 * \param functionCode: SMP function code. 7076 * \param pSmpBody: Pointer to SMP payload. 7077 * \param smpBodySize: Size of SMP request without SMP header. 7078 * \param agRequestType: SPC-specfic request type 7079 * 7080 * \return: 7081 * tiSuccess SMP is sent successfully 7082 * tiError SMP is not sent successfully 7083 * 7084 * \note: 7085 * 7086 *****************************************************************************/ 7087 osGLOBAL bit32 7088 tdSMPStart( 7089 tiRoot_t *tiRoot, 7090 agsaRoot_t *agRoot, 7091 tdsaDeviceData_t *oneDeviceData, 7092 bit32 functionCode, 7093 bit8 *pSmpBody, /* smp payload itself w/o first 4 bytes(header) */ 7094 bit32 smpBodySize, /* smp payload size w/o first 4 bytes(header) */ 7095 bit32 agRequestType, 7096 tiIORequest_t *CurrentTaskTag, 7097 bit32 queueNumber 7098 ) 7099 { 7100 void *osMemHandle; 7101 bit32 PhysUpper32; 7102 bit32 PhysLower32; 7103 bit32 memAllocStatus; 7104 bit32 expectedRspLen = 0; 7105 7106 #ifdef REMOVED 7107 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7108 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared); 7109 #endif 7110 tdssSMPRequestBody_t *tdSMPRequestBody; 7111 agsaSASRequestBody_t *agSASRequestBody; 7112 agsaSMPFrame_t *agSMPFrame; 7113 agsaIORequest_t *agIORequest; 7114 agsaDevHandle_t *agDevHandle; 7115 tdssSMPFrameHeader_t tdSMPFrameHeader; 7116 tdsaPortContext_t *onePortContext = agNULL; 7117 bit32 status; 7118 7119 #ifndef DIRECT_SMP 7120 void *IndirectSMPReqosMemHandle; 7121 bit32 IndirectSMPReqPhysUpper32; 7122 bit32 IndirectSMPReqPhysLower32; 7123 bit32 IndirectSMPReqmemAllocStatus; 7124 bit8 *IndirectSMPReq; 7125 7126 void *IndirectSMPResposMemHandle; 7127 bit32 IndirectSMPRespPhysUpper32; 7128 bit32 IndirectSMPRespPhysLower32; 7129 bit32 IndirectSMPRespmemAllocStatus; 7130 bit8 *IndirectSMPResp; 7131 #endif 7132 7133 TI_DBG3(("tdSMPStart: start\n")); 7134 TI_DBG3(("tdSMPStart: oneDeviceData %p\n", oneDeviceData)); 7135 TI_DBG3(("tdSMPStart: sasAddressHi 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify))); 7136 TI_DBG3(("tdSMPStart: sasAddressLo 0x%08x\n", SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify))); 7137 TI_DBG3(("tdSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 7138 TI_DBG3(("tdSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 7139 7140 onePortContext = oneDeviceData->tdPortContext; 7141 7142 if (onePortContext != agNULL) 7143 { 7144 TI_DBG3(("tdSMPStart: pid %d\n", onePortContext->id)); 7145 /* increment the number of pending SMP */ 7146 onePortContext->discovery.pendingSMP++; 7147 } 7148 else 7149 { 7150 TI_DBG1(("tdSMPStart: Wrong!!! onePortContext is NULL\n")); 7151 return tiError; 7152 } 7153 7154 7155 7156 memAllocStatus = ostiAllocMemory( 7157 tiRoot, 7158 &osMemHandle, 7159 (void **)&tdSMPRequestBody, 7160 &PhysUpper32, 7161 &PhysLower32, 7162 8, 7163 sizeof(tdssSMPRequestBody_t), 7164 agTRUE 7165 ); 7166 7167 if (memAllocStatus != tiSuccess) 7168 { 7169 TI_DBG1(("tdSMPStart: ostiAllocMemory failed...\n")); 7170 return tiError; 7171 } 7172 7173 if (tdSMPRequestBody == agNULL) 7174 { 7175 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL tdSMPRequestBody\n")); 7176 return tiError; 7177 } 7178 /* saves mem handle for freeing later */ 7179 tdSMPRequestBody->osMemHandle = osMemHandle; 7180 7181 /* saves tdsaDeviceData */ 7182 tdSMPRequestBody->tdDevice = oneDeviceData; 7183 7184 /* saving port id */ 7185 tdSMPRequestBody->tdPortContext = onePortContext; 7186 7187 7188 agDevHandle = oneDeviceData->agDevHandle; 7189 7190 /* save the callback funtion */ 7191 tdSMPRequestBody->SMPCompletionFunc = itdssSMPCompleted; /* in itdcb.c */ 7192 7193 /* for simulate warm target reset */ 7194 tdSMPRequestBody->CurrentTaskTag = CurrentTaskTag; 7195 7196 /* initializes the number of SMP retries */ 7197 tdSMPRequestBody->retries = 0; 7198 7199 #ifdef TD_INTERNAL_DEBUG /* debugging */ 7200 TI_DBG4(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody)); 7201 TI_DBG4(("tdSMPStart: callback fn %p\n", tdSMPRequestBody->SMPCompletionFunc)); 7202 #endif 7203 7204 agIORequest = &(tdSMPRequestBody->agIORequest); 7205 agIORequest->osData = (void *) tdSMPRequestBody; 7206 agIORequest->sdkData = agNULL; /* SALL takes care of this */ 7207 7208 7209 agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody); 7210 agSMPFrame = &(agSASRequestBody->smpFrame); 7211 7212 TI_DBG3(("tdSMPStart: agIORequest %p\n", agIORequest)); 7213 TI_DBG3(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody)); 7214 7215 /* 7216 depending on functionCode, set expectedRspLen in smp 7217 */ 7218 switch (functionCode) 7219 { 7220 case SMP_REPORT_GENERAL: 7221 expectedRspLen = sizeof(smpRespReportGeneral_t) + 4; 7222 break; 7223 case SMP_REPORT_MANUFACTURE_INFORMATION: 7224 expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4; 7225 break; 7226 case SMP_DISCOVER: 7227 expectedRspLen = sizeof(smpRespDiscover_t) + 4; 7228 break; 7229 case SMP_REPORT_PHY_ERROR_LOG: 7230 expectedRspLen = 32 - 4; 7231 break; 7232 case SMP_REPORT_PHY_SATA: 7233 expectedRspLen = sizeof(smpRespReportPhySata_t) + 4; 7234 break; 7235 case SMP_REPORT_ROUTING_INFORMATION: 7236 expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4; 7237 break; 7238 case SMP_CONFIGURE_ROUTING_INFORMATION: 7239 expectedRspLen = 4; 7240 break; 7241 case SMP_PHY_CONTROL: 7242 expectedRspLen = 4; 7243 break; 7244 case SMP_PHY_TEST_FUNCTION: 7245 expectedRspLen = 4; 7246 break; 7247 case SMP_PMC_SPECIFIC: 7248 expectedRspLen = 4; 7249 break; 7250 default: 7251 expectedRspLen = 0; 7252 TI_DBG1(("tdSMPStart: error!!! undefined or unused smp function code 0x%x\n", functionCode)); 7253 return tiError; 7254 } 7255 7256 if (tiIS_SPC(agRoot)) 7257 { 7258 #ifdef DIRECT_SMP /* direct SMP with 48 or less payload */ 7259 if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */ 7260 { 7261 TI_DBG3(("tdSMPStart: DIRECT smp payload\n")); 7262 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); 7263 osti_memset(tdSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 7264 7265 /* SMP header */ 7266 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 7267 tdSMPFrameHeader.smpFunction = (bit8)functionCode; 7268 tdSMPFrameHeader.smpFunctionResult = 0; 7269 tdSMPFrameHeader.smpReserved = 0; 7270 7271 osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4); 7272 // osti_memcpy((tdSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 7273 osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize); 7274 7275 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 7276 agSMPFrame->outFrameBuf = tdSMPRequestBody->smpPayload; 7277 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 7278 /* to specify DIRECT SMP response */ 7279 agSMPFrame->inFrameLen = 0; 7280 7281 /* temporary solution for T2D Combo*/ 7282 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 7283 /* force smp repsonse to be direct */ 7284 agSMPFrame->expectedRespLen = 0; 7285 #else 7286 agSMPFrame->expectedRespLen = expectedRspLen; 7287 #endif 7288 // tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 7289 // tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 7290 // tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t)); 7291 } 7292 else 7293 { 7294 TI_DBG3(("tdSMPStart: INDIRECT smp payload\n")); 7295 } 7296 7297 #else 7298 7299 /* indirect SMP */ 7300 /* allocate Direct SMP request payload */ 7301 IndirectSMPReqmemAllocStatus = ostiAllocMemory( 7302 tiRoot, 7303 &IndirectSMPReqosMemHandle, 7304 (void **)&IndirectSMPReq, 7305 &IndirectSMPReqPhysUpper32, 7306 &IndirectSMPReqPhysLower32, 7307 8, 7308 smpBodySize + 4, 7309 agFALSE 7310 ); 7311 7312 if (IndirectSMPReqmemAllocStatus != tiSuccess) 7313 { 7314 TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP request...\n")); 7315 return tiError; 7316 } 7317 7318 if (IndirectSMPReq == agNULL) 7319 { 7320 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPReq\n")); 7321 return tiError; 7322 } 7323 7324 /* allocate indirect SMP response payload */ 7325 IndirectSMPRespmemAllocStatus = ostiAllocMemory( 7326 tiRoot, 7327 &IndirectSMPResposMemHandle, 7328 (void **)&IndirectSMPResp, 7329 &IndirectSMPRespPhysUpper32, 7330 &IndirectSMPRespPhysLower32, 7331 8, 7332 expectedRspLen, 7333 agFALSE 7334 ); 7335 7336 if (IndirectSMPRespmemAllocStatus != tiSuccess) 7337 { 7338 TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP reponse...\n")); 7339 return tiError; 7340 } 7341 7342 if (IndirectSMPResp == agNULL) 7343 { 7344 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPResp\n")); 7345 return tiError; 7346 } 7347 7348 /* saves mem handle for freeing later */ 7349 tdSMPRequestBody->IndirectSMPReqosMemHandle = IndirectSMPReqosMemHandle; 7350 tdSMPRequestBody->IndirectSMPResposMemHandle = IndirectSMPResposMemHandle; 7351 7352 /* saves Indirect SMP request/repsonse pointer and length for free them later */ 7353 tdSMPRequestBody->IndirectSMPReq = IndirectSMPReq; 7354 tdSMPRequestBody->IndirectSMPResp = IndirectSMPResp; 7355 tdSMPRequestBody->IndirectSMPReqLen = smpBodySize + 4; 7356 tdSMPRequestBody->IndirectSMPRespLen = expectedRspLen; 7357 7358 /* fill in indirect SMP request fields */ 7359 TI_DBG3(("tdSMPStart: INDIRECT smp payload\n")); 7360 7361 /* SMP request and response initialization */ 7362 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); 7363 osti_memset(IndirectSMPReq, 0, smpBodySize + 4); 7364 osti_memset(IndirectSMPResp, 0, expectedRspLen); 7365 7366 /* SMP request header */ 7367 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 7368 tdSMPFrameHeader.smpFunction = (bit8)functionCode; 7369 tdSMPFrameHeader.smpFunctionResult = 0; 7370 tdSMPFrameHeader.smpReserved = 0; 7371 7372 osti_memcpy(IndirectSMPReq, &tdSMPFrameHeader, 4); 7373 osti_memcpy(IndirectSMPReq+4, pSmpBody, smpBodySize); 7374 7375 /* Indirect SMP request */ 7376 agSMPFrame->outFrameBuf = agNULL; 7377 agSMPFrame->outFrameAddrUpper32 = IndirectSMPReqPhysUpper32; 7378 agSMPFrame->outFrameAddrLower32 = IndirectSMPReqPhysLower32; 7379 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 7380 7381 /* Indirect SMP response */ 7382 agSMPFrame->expectedRespLen = expectedRspLen; 7383 agSMPFrame->inFrameLen = expectedRspLen; /* without last 4 byte crc */ 7384 agSMPFrame->inFrameAddrUpper32 = IndirectSMPRespPhysUpper32; 7385 agSMPFrame->inFrameAddrLower32 = IndirectSMPRespPhysLower32; 7386 #endif 7387 } 7388 else /* SPCv controller */ 7389 { 7390 /* only direct mode for both request and response */ 7391 TI_DBG3(("tdSMPStart: DIRECT smp payload\n")); 7392 agSMPFrame->flag = 0; 7393 osti_memset(&tdSMPFrameHeader, 0, sizeof(tdssSMPFrameHeader_t)); 7394 osti_memset(tdSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 7395 7396 /* SMP header */ 7397 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 7398 tdSMPFrameHeader.smpFunction = (bit8)functionCode; 7399 tdSMPFrameHeader.smpFunctionResult = 0; 7400 tdSMPFrameHeader.smpReserved = 0; 7401 7402 osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4); 7403 // osti_memcpy((tdSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 7404 osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize); 7405 7406 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 7407 agSMPFrame->outFrameBuf = tdSMPRequestBody->smpPayload; 7408 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 7409 /* to specify DIRECT SMP response */ 7410 agSMPFrame->inFrameLen = 0; 7411 7412 /* temporary solution for T2D Combo*/ 7413 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 7414 /* force smp repsonse to be direct */ 7415 agSMPFrame->expectedRespLen = 0; 7416 #else 7417 agSMPFrame->expectedRespLen = expectedRspLen; 7418 #endif 7419 // tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 7420 // tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 7421 // tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t)); 7422 } 7423 7424 7425 if (agDevHandle == agNULL) 7426 { 7427 TI_DBG1(("tdSMPStart: !!! agDevHandle is NULL !!! \n")); 7428 return tiError; 7429 } 7430 7431 tdSMPRequestBody->queueNumber = queueNumber; 7432 status = saSMPStart( 7433 agRoot, 7434 agIORequest, 7435 queueNumber, //tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData), 7436 agDevHandle, 7437 agRequestType, 7438 agSASRequestBody, 7439 &ossaSMPCompleted 7440 ); 7441 7442 if (status == AGSA_RC_SUCCESS) 7443 { 7444 /* start SMP timer */ 7445 if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 7446 functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION 7447 ) 7448 { 7449 tdsaDiscoverySMPTimer(tiRoot, onePortContext, functionCode, tdSMPRequestBody); 7450 } 7451 return tiSuccess; 7452 } 7453 else if (status == AGSA_RC_BUSY) 7454 { 7455 /* set timer */ 7456 if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 7457 functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION) 7458 { 7459 /* only for discovery related SMPs*/ 7460 tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody); 7461 return tiSuccess; 7462 } 7463 else if (functionCode == SMP_PHY_CONTROL) 7464 { 7465 ostiFreeMemory( 7466 tiRoot, 7467 osMemHandle, 7468 sizeof(tdssSMPRequestBody_t) 7469 ); 7470 return tiBusy; 7471 } 7472 else 7473 { 7474 ostiFreeMemory( 7475 tiRoot, 7476 osMemHandle, 7477 sizeof(tdssSMPRequestBody_t) 7478 ); 7479 return tiBusy; 7480 } 7481 } 7482 else /* AGSA_RC_FAILURE */ 7483 { 7484 /* discovery failure or task management failure */ 7485 if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 7486 functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION) 7487 { 7488 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 7489 } 7490 ostiFreeMemory( 7491 tiRoot, 7492 osMemHandle, 7493 sizeof(tdssSMPRequestBody_t) 7494 ); 7495 7496 return tiError; 7497 } 7498 } 7499 7500 #ifdef REMOVED 7501 /***************************************************************************** 7502 *! \brief tdsaFindLocalLinkRate 7503 * 7504 * Purpose: This function finds local link rate. 7505 * 7506 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7507 * instance. 7508 * \param tdsaPortStartInfo: Pointer to the port start information. 7509 * 7510 * \return: 7511 * None 7512 * 7513 * \note: 7514 * 7515 *****************************************************************************/ 7516 osGLOBAL bit8 7517 tdsaFindLocalLinkRate( 7518 tiRoot_t *tiRoot, 7519 tdsaPortStartInfo_t *tdsaPortStartInfo 7520 ) 7521 { 7522 bit8 ans = SAS_CONNECTION_RATE_3_0G; /* default */ 7523 bit32 phyProperties; 7524 7525 phyProperties = tdsaPortStartInfo->agPhyConfig.phyProperties; 7526 7527 TI_DBG3(("tdsaFindLocalLinkRate: start\n")); 7528 if (phyProperties & 0x4) 7529 { 7530 ans = SAS_CONNECTION_RATE_6_0G; 7531 } 7532 if (phyProperties & 0x2) 7533 { 7534 ans = SAS_CONNECTION_RATE_3_0G; 7535 } 7536 if (phyProperties & 0x1) 7537 { 7538 ans = SAS_CONNECTION_RATE_1_5G; 7539 } 7540 TI_DBG3(("tdsaFindLocalLinkRate: ans 0x%x\n", ans)); 7541 return ans; 7542 } 7543 #endif 7544 /***************************************************************************** 7545 *! \brief tdsaConfigureRouteTimer 7546 * 7547 * Purpose: This function sets timers for configuring routing of discovery and 7548 * its callback function. 7549 * 7550 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7551 * instance. 7552 * \param onePortContext: Pointer to the portal context instance. 7553 * \param oneExpander: Pointer to the expander. 7554 * \param ptdSMPDiscoverResp: Pointer to SMP discover repsonse data. 7555 * 7556 * \return: 7557 * None 7558 * 7559 * \note: called by tdsaDiscoverRespRcvd() 7560 * 7561 *****************************************************************************/ 7562 osGLOBAL void 7563 tdsaConfigureRouteTimer(tiRoot_t *tiRoot, 7564 tdsaPortContext_t *onePortContext, 7565 tdsaExpander_t *oneExpander, 7566 smpRespDiscover_t *ptdSMPDiscoverResp 7567 ) 7568 { 7569 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7570 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 7571 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 7572 tdsaDiscovery_t *discovery; 7573 7574 TI_DBG1(("tdsaConfigureRouteTimer: start\n")); 7575 TI_DBG1(("tdsaConfigureRouteTimer: pid %d\n", onePortContext->id)); 7576 7577 discovery = &(onePortContext->discovery); 7578 7579 TI_DBG1(("tdsaConfigureRouteTimer: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp)); 7580 7581 TI_DBG1(("tdsaConfigureRouteTimer: discovery %p \n", discovery)); 7582 7583 TI_DBG1(("tdsaConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7584 7585 TI_DBG1(("tdsaConfigureRouteTimer: discovery->status %d\n", discovery->status)); 7586 7587 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7588 { 7589 tdsaKillTimer( 7590 tiRoot, 7591 &discovery->configureRouteTimer 7592 ); 7593 } 7594 7595 TI_DBG1(("tdsaConfigureRouteTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick)); 7596 TI_DBG1(("tdsaConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick)); 7597 7598 tdsaSetTimerRequest( 7599 tiRoot, 7600 &discovery->configureRouteTimer, 7601 CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 7602 tdsaConfigureRouteTimerCB, 7603 (void *)onePortContext, 7604 (void *)oneExpander, 7605 (void *)ptdSMPDiscoverResp 7606 ); 7607 7608 tdsaAddTimer ( 7609 tiRoot, 7610 &Initiator->timerlist, 7611 &discovery->configureRouteTimer 7612 ); 7613 7614 return; 7615 } 7616 7617 /***************************************************************************** 7618 *! \brief tdsaConfigureRouteTimerCB 7619 * 7620 * Purpose: This function is callback function for tdsaConfigureRouteTimer. 7621 * 7622 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7623 * instance. 7624 * \param timerData1: Pointer to timer-related data structure 7625 * \param timerData2: Pointer to timer-related data structure 7626 * \param timerData3: Pointer to timer-related data structure 7627 * 7628 * \return: 7629 * None 7630 * 7631 * \note: 7632 * 7633 *****************************************************************************/ 7634 osGLOBAL void 7635 tdsaConfigureRouteTimerCB( 7636 tiRoot_t * tiRoot, 7637 void * timerData1, 7638 void * timerData2, 7639 void * timerData3 7640 ) 7641 { 7642 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7643 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 7644 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 7645 tdsaPortContext_t *onePortContext; 7646 tdsaExpander_t *oneExpander; 7647 smpRespDiscover_t *ptdSMPDiscoverResp; 7648 tdsaDiscovery_t *discovery; 7649 7650 TI_DBG1(("tdsaConfigureRouteTimerCB: start\n")); 7651 7652 onePortContext = (tdsaPortContext_t *)timerData1; 7653 oneExpander = (tdsaExpander_t *)timerData2; 7654 ptdSMPDiscoverResp = (smpRespDiscover_t *)timerData3; 7655 7656 discovery = &(onePortContext->discovery); 7657 7658 TI_DBG1(("tdsaConfigureRouteTimerCB: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp)); 7659 7660 TI_DBG1(("tdsaConfigureRouteTimerCB: discovery %p\n", discovery)); 7661 7662 TI_DBG1(("tdsaConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries)); 7663 7664 TI_DBG1(("tdsaConfigureRouteTimerCB: discovery.status %d\n", discovery->status)); 7665 7666 discovery->configureRouteRetries++; 7667 if (discovery->configureRouteRetries >= DISCOVERY_RETRIES) 7668 { 7669 TI_DBG1(("tdsaConfigureRouteTimerCB: retries are over\n")); 7670 discovery->configureRouteRetries = 0; 7671 /* failed the discovery */ 7672 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 7673 if (discovery->configureRouteTimer.timerRunning == agTRUE) 7674 { 7675 tdsaKillTimer( 7676 tiRoot, 7677 &discovery->configureRouteTimer 7678 ); 7679 } 7680 return; 7681 } 7682 7683 7684 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 7685 { 7686 TI_DBG1(("tdsaConfigureRouteTimerCB: proceed by calling tdsaSASDownStreamDiscoverExpanderPhy\n")); 7687 tdhexdump("tdsaConfigureRouteTimerCB", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t)); 7688 discovery->configureRouteRetries = 0; 7689 7690 tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp); 7691 } 7692 else 7693 { 7694 TI_DBG1(("tdsaConfigureRouteTimerCB: setting timer again\n")); 7695 /* set the timer again */ 7696 tdsaSetTimerRequest( 7697 tiRoot, 7698 &discovery->configureRouteTimer, 7699 CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 7700 tdsaConfigureRouteTimerCB, 7701 (void *)onePortContext, 7702 (void *)oneExpander, 7703 (void *)ptdSMPDiscoverResp 7704 ); 7705 7706 tdsaAddTimer ( 7707 tiRoot, 7708 &Initiator->timerlist, 7709 &discovery->configureRouteTimer 7710 ); 7711 } 7712 // tdsaReportGeneralSend(tiRoot, oneDeviceData); 7713 return; 7714 } 7715 7716 /***************************************************************************** 7717 *! \brief tdsaDiscoveryTimer 7718 * 7719 * Purpose: This function sets timers for discovery and its callback 7720 * function. 7721 * 7722 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7723 * instance. 7724 * \param onePortContext: Pointer to the portal context instance. 7725 * \param oneDeviceData: Pointer to the device data. 7726 * 7727 * \return: 7728 * None 7729 * 7730 * \note: 7731 * 7732 *****************************************************************************/ 7733 osGLOBAL void 7734 tdsaDiscoveryTimer(tiRoot_t *tiRoot, 7735 tdsaPortContext_t *onePortContext, 7736 tdsaDeviceData_t *oneDeviceData 7737 ) 7738 { 7739 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7740 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 7741 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 7742 tdsaDiscovery_t *discovery; 7743 7744 TI_DBG1(("tdsaDiscoveryTimer: start\n")); 7745 TI_DBG1(("tdsaDiscoveryTimer: pid %d\n", onePortContext->id)); 7746 7747 discovery = &(onePortContext->discovery); 7748 7749 if (discovery->discoveryTimer.timerRunning == agTRUE) 7750 { 7751 tdsaKillTimer( 7752 tiRoot, 7753 &discovery->discoveryTimer 7754 ); 7755 } 7756 7757 TI_DBG1(("tdsaDiscoveryTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick)); 7758 TI_DBG1(("tdsaDiscoveryTimer: Timervalue %d\n", DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick)); 7759 7760 tdsaSetTimerRequest( 7761 tiRoot, 7762 &discovery->discoveryTimer, 7763 DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 7764 tdsaDiscoveryTimerCB, 7765 oneDeviceData, 7766 agNULL, 7767 agNULL 7768 ); 7769 7770 tdsaAddTimer ( 7771 tiRoot, 7772 &Initiator->timerlist, 7773 &discovery->discoveryTimer 7774 ); 7775 7776 return; 7777 } 7778 7779 /***************************************************************************** 7780 *! \brief tdsaDiscoveryTimerCB 7781 * 7782 * Purpose: This function is callback function for discovery timer. 7783 * 7784 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7785 * instance. 7786 * \param timerData1: Pointer to timer-related data structure 7787 * \param timerData2: Pointer to timer-related data structure 7788 * \param timerData3: Pointer to timer-related data structure 7789 * 7790 * \return: 7791 * None 7792 * 7793 * \note: 7794 * 7795 *****************************************************************************/ 7796 osGLOBAL void 7797 tdsaDiscoveryTimerCB( 7798 tiRoot_t * tiRoot, 7799 void * timerData1, 7800 void * timerData2, 7801 void * timerData3 7802 ) 7803 { 7804 tdsaDeviceData_t *oneDeviceData; 7805 oneDeviceData = (tdsaDeviceData_t *)timerData1; 7806 7807 TI_DBG1(("tdsaDiscoveryTimerCB: start\n")); 7808 7809 if (oneDeviceData->registered == agTRUE) 7810 { 7811 TI_DBG1(("tdsaDiscoveryTimerCB: resumes discovery\n")); 7812 tdsaReportGeneralSend(tiRoot, oneDeviceData); 7813 } 7814 7815 return; 7816 } 7817 7818 /***************************************************************************** 7819 *! \brief tdsaDeviceRegistrationTimer 7820 * 7821 * Purpose: This function sets timers for device registration in discovery 7822 * 7823 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7824 * instance. 7825 * \param onePortContext: Pointer to the portal context instance. 7826 * \param oneDeviceData: Pointer to the device data. 7827 * \return: 7828 * None 7829 * 7830 * \note: called by tdsaSASFullDiscover() or tdsaSASIncrementalDiscover() 7831 * or tdsaDeviceRegistrationTimerCB() 7832 * 7833 *****************************************************************************/ 7834 osGLOBAL void 7835 tdsaDeviceRegistrationTimer(tiRoot_t *tiRoot, 7836 tdsaPortContext_t *onePortContext, 7837 tdsaDeviceData_t *oneDeviceData 7838 ) 7839 { 7840 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7841 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 7842 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 7843 tdsaDiscovery_t *discovery; 7844 7845 TI_DBG1(("tdsaDeviceRegistrationTimer: start\n")); 7846 TI_DBG1(("tdsaDeviceRegistrationTimer: pid %d\n", onePortContext->id)); 7847 7848 discovery = &(onePortContext->discovery); 7849 7850 if (discovery->deviceRegistrationTimer.timerRunning == agTRUE) 7851 { 7852 tdsaKillTimer( 7853 tiRoot, 7854 &discovery->deviceRegistrationTimer 7855 ); 7856 } 7857 7858 TI_DBG1(("tdsaDeviceRegistrationTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick)); 7859 TI_DBG1(("tdsaDeviceRegistrationTimer: Timervalue %d\n", DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick)); 7860 7861 tdsaSetTimerRequest( 7862 tiRoot, 7863 &discovery->deviceRegistrationTimer, 7864 DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 7865 tdsaDeviceRegistrationTimerCB, 7866 onePortContext, 7867 oneDeviceData, 7868 agNULL 7869 ); 7870 7871 tdsaAddTimer ( 7872 tiRoot, 7873 &Initiator->timerlist, 7874 &discovery->deviceRegistrationTimer 7875 ); 7876 return; 7877 } 7878 7879 /***************************************************************************** 7880 *! \brief tdsaDeviceRegistrationTimerCB 7881 * 7882 * Purpose: This function is callback function for tdsaDeviceRegistrationTimer. 7883 * 7884 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7885 * instance. 7886 * \param timerData1: Pointer to timer-related data structure 7887 * \param timerData2: Pointer to timer-related data structure 7888 * \param timerData3: Pointer to timer-related data structure 7889 * 7890 * \return: 7891 * None 7892 * 7893 * \note: 7894 * 7895 *****************************************************************************/ 7896 osGLOBAL void 7897 tdsaDeviceRegistrationTimerCB( 7898 tiRoot_t * tiRoot, 7899 void * timerData1, 7900 void * timerData2, 7901 void * timerData3 7902 ) 7903 { 7904 tdsaPortContext_t *onePortContext; 7905 tdsaDeviceData_t *oneDeviceData; 7906 tdsaDiscovery_t *discovery; 7907 7908 TI_DBG1(("tdsaDeviceRegistrationTimerCB: start\n")); 7909 7910 onePortContext = (tdsaPortContext_t *)timerData1; 7911 oneDeviceData = (tdsaDeviceData_t *)timerData2; 7912 discovery = &(onePortContext->discovery); 7913 7914 if (oneDeviceData->registered == agFALSE) 7915 { 7916 discovery->deviceRetistrationRetries++; 7917 if (discovery->deviceRetistrationRetries >= DISCOVERY_RETRIES) 7918 { 7919 TI_DBG1(("tdsaDeviceRegistrationTimerCB: retries are over\n")); 7920 discovery->deviceRetistrationRetries = 0; 7921 /* failed the discovery */ 7922 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 7923 if (discovery->deviceRegistrationTimer.timerRunning == agTRUE) 7924 { 7925 tdsaKillTimer( 7926 tiRoot, 7927 &discovery->deviceRegistrationTimer 7928 ); 7929 } 7930 } 7931 else 7932 { 7933 TI_DBG1(("tdsaDeviceRegistrationTimerCB: keep retrying\n")); 7934 /* start timer for device registration */ 7935 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData); 7936 } 7937 } 7938 else 7939 { 7940 /* go ahead; continue the discovery */ 7941 discovery->deviceRetistrationRetries = 0; 7942 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData); 7943 } 7944 } 7945 7946 /***************************************************************************** 7947 *! \brief tdsaSMPBusyTimer 7948 * 7949 * Purpose: This function sets timers for busy of saSMPStart. 7950 * 7951 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 7952 * instance. 7953 * \param onePortContext: Pointer to the portal context instance. 7954 * \param oneDeviceData: Pointer to the device data. 7955 * \param tdSMPRequestBody: Pointer to the SMP request body. 7956 * 7957 * \return: 7958 * None 7959 * 7960 * \note: 7961 * 7962 *****************************************************************************/ 7963 osGLOBAL void 7964 tdsaSMPBusyTimer(tiRoot_t *tiRoot, 7965 tdsaPortContext_t *onePortContext, 7966 tdsaDeviceData_t *oneDeviceData, 7967 tdssSMPRequestBody_t *tdSMPRequestBody 7968 ) 7969 { 7970 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 7971 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 7972 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 7973 tdsaDiscovery_t *discovery; 7974 7975 TI_DBG1(("tdsaSMPBusyTimer: start\n")); 7976 TI_DBG1(("tdsaSMPBusyTimer: pid %d\n", onePortContext->id)); 7977 7978 discovery = &(onePortContext->discovery); 7979 7980 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 7981 { 7982 tdsaKillTimer( 7983 tiRoot, 7984 &discovery->SMPBusyTimer 7985 ); 7986 } 7987 7988 tdsaSetTimerRequest( 7989 tiRoot, 7990 &discovery->SMPBusyTimer, 7991 SMP_BUSY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 7992 tdsaSMPBusyTimerCB, 7993 onePortContext, 7994 oneDeviceData, 7995 tdSMPRequestBody 7996 ); 7997 7998 tdsaAddTimer ( 7999 tiRoot, 8000 &Initiator->timerlist, 8001 &discovery->SMPBusyTimer 8002 ); 8003 return; 8004 } 8005 8006 /***************************************************************************** 8007 *! \brief tdsaSMPBusyTimerCB 8008 * 8009 * Purpose: This function is callback function for SMP busy timer. 8010 * 8011 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8012 * instance. 8013 * \param timerData1: Pointer to timer-related data structure 8014 * \param timerData2: Pointer to timer-related data structure 8015 * \param timerData3: Pointer to timer-related data structure 8016 * 8017 * \return: 8018 * None 8019 * 8020 * \note: 8021 * 8022 *****************************************************************************/ 8023 osGLOBAL void 8024 tdsaSMPBusyTimerCB( 8025 tiRoot_t * tiRoot, 8026 void * timerData1, 8027 void * timerData2, 8028 void * timerData3 8029 ) 8030 { 8031 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 8032 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared); 8033 agsaRoot_t *agRoot; 8034 tdsaPortContext_t *onePortContext; 8035 tdsaDeviceData_t *oneDeviceData; 8036 tdssSMPRequestBody_t *tdSMPRequestBody; 8037 agsaSASRequestBody_t *agSASRequestBody; 8038 agsaIORequest_t *agIORequest; 8039 agsaDevHandle_t *agDevHandle; 8040 tdsaDiscovery_t *discovery; 8041 bit32 status = AGSA_RC_FAILURE; 8042 8043 TI_DBG1(("tdsaSMPBusyTimerCB: start\n")); 8044 8045 onePortContext = (tdsaPortContext_t *)timerData1; 8046 oneDeviceData = (tdsaDeviceData_t *)timerData2; 8047 tdSMPRequestBody = (tdssSMPRequestBody_t *)timerData3; 8048 agRoot = oneDeviceData->agRoot; 8049 agIORequest = &(tdSMPRequestBody->agIORequest); 8050 agDevHandle = oneDeviceData->agDevHandle; 8051 agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody); 8052 discovery = &(onePortContext->discovery); 8053 8054 discovery->SMPRetries++; 8055 8056 if (discovery->SMPRetries < SMP_BUSY_RETRIES) 8057 { 8058 status = saSMPStart( 8059 agRoot, 8060 agIORequest, 8061 tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData), 8062 agDevHandle, 8063 AGSA_SMP_INIT_REQ, 8064 agSASRequestBody, 8065 &ossaSMPCompleted 8066 ); 8067 } 8068 8069 if (status == AGSA_RC_SUCCESS) 8070 { 8071 discovery->SMPRetries = 0; 8072 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 8073 { 8074 tdsaKillTimer( 8075 tiRoot, 8076 &discovery->SMPBusyTimer 8077 ); 8078 } 8079 } 8080 else if (status == AGSA_RC_FAILURE) 8081 { 8082 discovery->SMPRetries = 0; 8083 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 8084 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 8085 { 8086 tdsaKillTimer( 8087 tiRoot, 8088 &discovery->SMPBusyTimer 8089 ); 8090 } 8091 } 8092 else /* AGSA_RC_BUSY */ 8093 { 8094 if (discovery->SMPRetries >= SMP_BUSY_RETRIES) 8095 { 8096 /* done with retris; give up */ 8097 TI_DBG1(("tdsaSMPBusyTimerCB: retries are over\n")); 8098 discovery->SMPRetries = 0; 8099 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 8100 if (discovery->SMPBusyTimer.timerRunning == agTRUE) 8101 { 8102 tdsaKillTimer( 8103 tiRoot, 8104 &discovery->SMPBusyTimer 8105 ); 8106 } 8107 } 8108 else 8109 { 8110 /* keep retrying */ 8111 tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody); 8112 } 8113 } 8114 8115 return; 8116 } 8117 8118 /***************************************************************************** 8119 *! \brief tdsaBCTimer 8120 * 8121 * Purpose: This function sets timers for sending ID device data only for 8122 * directly attached SATA device. 8123 * 8124 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8125 * instance. 8126 * \param onePortContext: Pointer to the portal context instance. 8127 * \param oneDeviceData: Pointer to the device data. 8128 * \param tdSMPRequestBody: Pointer to the SMP request body. 8129 * 8130 * \return: 8131 * None 8132 * 8133 * \note: 8134 * 8135 *****************************************************************************/ 8136 osGLOBAL void 8137 tdsaBCTimer(tiRoot_t *tiRoot, 8138 tdsaPortContext_t *onePortContext 8139 ) 8140 { 8141 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 8142 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 8143 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 8144 tdsaDiscovery_t *discovery; 8145 8146 8147 TI_DBG1(("tdsaBCTimer: start\n")); 8148 8149 discovery = &(onePortContext->discovery); 8150 8151 if (discovery->BCTimer.timerRunning == agTRUE) 8152 { 8153 tdsaKillTimer( 8154 tiRoot, 8155 &discovery->BCTimer 8156 ); 8157 } 8158 8159 if (onePortContext->valid == agTRUE) 8160 { 8161 tdsaSetTimerRequest( 8162 tiRoot, 8163 &discovery->BCTimer, 8164 BC_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 8165 tdsaBCTimerCB, 8166 onePortContext, 8167 agNULL, 8168 agNULL 8169 ); 8170 8171 tdsaAddTimer( 8172 tiRoot, 8173 &Initiator->timerlist, 8174 &discovery->BCTimer 8175 ); 8176 8177 } 8178 8179 return; 8180 } 8181 8182 /***************************************************************************** 8183 *! \brief tdsaBCTimerCB 8184 * 8185 * Purpose: This function is callback function for SATA ID device data. 8186 * 8187 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8188 * instance. 8189 * \param timerData1: Pointer to timer-related data structure 8190 * \param timerData2: Pointer to timer-related data structure 8191 * \param timerData3: Pointer to timer-related data structure 8192 * 8193 * \return: 8194 * None 8195 * 8196 * \note: 8197 * 8198 *****************************************************************************/ 8199 osGLOBAL void 8200 tdsaBCTimerCB( 8201 tiRoot_t * tiRoot, 8202 void * timerData1, 8203 void * timerData2, 8204 void * timerData3 8205 ) 8206 { 8207 tdsaPortContext_t *onePortContext; 8208 tdsaDiscovery_t *discovery; 8209 8210 TI_DBG1(("tdsaBCTimerCB: start\n")); 8211 8212 onePortContext = (tdsaPortContext_t *)timerData1; 8213 discovery = &(onePortContext->discovery); 8214 8215 discovery->ResetTriggerred = agFALSE; 8216 8217 if (onePortContext->valid == agTRUE) 8218 { 8219 tdsaDiscover( 8220 tiRoot, 8221 onePortContext, 8222 TDSA_DISCOVERY_TYPE_SAS, 8223 TDSA_DISCOVERY_OPTION_INCREMENTAL_START 8224 ); 8225 } 8226 if (discovery->BCTimer.timerRunning == agTRUE) 8227 { 8228 tdsaKillTimer( 8229 tiRoot, 8230 &discovery->BCTimer 8231 ); 8232 } 8233 8234 return; 8235 } 8236 8237 /***************************************************************************** 8238 *! \brief tdsaDiscoverySMPTimer 8239 * 8240 * Purpose: This function sets timers for sending discovery-related SMP 8241 * 8242 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8243 * instance. 8244 * \param onePortContext: Pointer to the portal context instance. 8245 * \param functionCode: SMP function. 8246 * \param tdSMPRequestBody: Pointer to the SMP request body. 8247 * 8248 * \return: 8249 * None 8250 * 8251 * \note: 8252 * 8253 *****************************************************************************/ 8254 osGLOBAL void 8255 tdsaDiscoverySMPTimer(tiRoot_t *tiRoot, 8256 tdsaPortContext_t *onePortContext, 8257 bit32 functionCode, /* smp function code */ 8258 tdssSMPRequestBody_t *tdSMPRequestBody 8259 ) 8260 { 8261 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 8262 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 8263 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 8264 tdsaDiscovery_t *discovery; 8265 8266 TI_DBG3(("tdsaDiscoverySMPTimer: start\n")); 8267 TI_DBG3(("tdsaDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode)); 8268 8269 /* start the SMP timer which works as SMP application timer */ 8270 discovery = &(onePortContext->discovery); 8271 8272 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 8273 { 8274 tdsaKillTimer( 8275 tiRoot, 8276 &discovery->DiscoverySMPTimer 8277 ); 8278 } 8279 tdsaSetTimerRequest( 8280 tiRoot, 8281 &discovery->DiscoverySMPTimer, 8282 SMP_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 8283 tdsaDiscoverySMPTimerCB, 8284 onePortContext, 8285 tdSMPRequestBody, 8286 agNULL 8287 ); 8288 8289 tdsaAddTimer ( 8290 tiRoot, 8291 &Initiator->timerlist, 8292 &discovery->DiscoverySMPTimer 8293 ); 8294 8295 return; 8296 } 8297 8298 /***************************************************************************** 8299 *! \brief tdsaDiscoverySMPTimerCB 8300 * 8301 * Purpose: This function is callback function for tdsaDiscoverySMPTimer. 8302 * 8303 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8304 * instance. 8305 * \param timerData1: Pointer to timer-related data structure 8306 * \param timerData2: Pointer to timer-related data structure 8307 * \param timerData3: Pointer to timer-related data structure 8308 * 8309 * \return: 8310 * None 8311 * 8312 * \note: 8313 * 8314 *****************************************************************************/ 8315 osGLOBAL void 8316 tdsaDiscoverySMPTimerCB( 8317 tiRoot_t * tiRoot, 8318 void * timerData1, 8319 void * timerData2, 8320 void * timerData3 8321 ) 8322 { 8323 agsaRoot_t *agRoot; 8324 tdsaPortContext_t *onePortContext; 8325 bit8 SMPFunction; 8326 #ifndef DIRECT_SMP 8327 tdssSMPFrameHeader_t *tdSMPFrameHeader; 8328 bit8 smpHeader[4]; 8329 #endif 8330 tdssSMPRequestBody_t *tdSMPRequestBody; 8331 tdsaDiscovery_t *discovery; 8332 tdsaDeviceData_t *oneDeviceData; 8333 agsaIORequest_t *agAbortIORequest = agNULL; 8334 tdIORequestBody_t *tdAbortIORequestBody = agNULL; 8335 bit32 PhysUpper32; 8336 bit32 PhysLower32; 8337 bit32 memAllocStatus; 8338 void *osMemHandle; 8339 agsaIORequest_t *agToBeAbortIORequest = agNULL; 8340 8341 TI_DBG1(("tdsaDiscoverySMPTimerCB: start\n")); 8342 8343 /* no retry 8344 if discovery related SMP, fail the discovery 8345 else .... 8346 be sure to abort SMP 8347 */ 8348 onePortContext = (tdsaPortContext_t *)timerData1; 8349 tdSMPRequestBody = (tdssSMPRequestBody_t *)timerData2; 8350 8351 discovery = &(onePortContext->discovery); 8352 oneDeviceData = tdSMPRequestBody->tdDevice; 8353 agToBeAbortIORequest = &(tdSMPRequestBody->agIORequest); 8354 agRoot = oneDeviceData->agRoot; 8355 8356 #ifdef DIRECT_SMP 8357 SMPFunction = tdSMPRequestBody->smpPayload[1]; 8358 #else 8359 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 0, smpHeader, 4); 8360 tdSMPFrameHeader = (tdssSMPFrameHeader_t *)smpHeader; 8361 SMPFunction = tdSMPFrameHeader->smpFunction; 8362 #endif 8363 8364 TI_DBG1(("tdsaDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction)); 8365 8366 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE) 8367 { 8368 tdsaKillTimer( 8369 tiRoot, 8370 &discovery->DiscoverySMPTimer 8371 ); 8372 } 8373 switch (SMPFunction) 8374 { 8375 case SMP_REPORT_GENERAL: /* fall through */ 8376 case SMP_DISCOVER: /* fall through */ 8377 case SMP_CONFIGURE_ROUTING_INFORMATION: /* fall through */ 8378 TI_DBG1(("tdsaDiscoverySMPTimerCB: failing discovery, SMP function 0x%x\n", SMPFunction)); 8379 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); 8380 return; 8381 case SMP_REPORT_PHY_SATA: 8382 TI_DBG1(("tdsaDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA\n")); 8383 tdsaSATADiscoverDone(tiRoot, onePortContext, tiError); 8384 break; 8385 default: 8386 /* do nothing */ 8387 TI_DBG1(("tdsaDiscoverySMPTimerCB: Error!!!! not allowed case\n")); 8388 break; 8389 } 8390 8391 if (onePortContext->discovery.SeenBC == agTRUE) 8392 { 8393 /* allocating agIORequest for abort itself */ 8394 memAllocStatus = ostiAllocMemory( 8395 tiRoot, 8396 &osMemHandle, 8397 (void **)&tdAbortIORequestBody, 8398 &PhysUpper32, 8399 &PhysLower32, 8400 8, 8401 sizeof(tdIORequestBody_t), 8402 agTRUE 8403 ); 8404 if (memAllocStatus != tiSuccess) 8405 { 8406 /* let os process IO */ 8407 TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory failed...\n")); 8408 return; 8409 } 8410 8411 if (tdAbortIORequestBody == agNULL) 8412 { 8413 /* let os process IO */ 8414 TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 8415 return; 8416 } 8417 8418 /* setup task management structure */ 8419 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 8420 /* setting callback */ 8421 tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler; 8422 8423 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle); 8424 8425 /* initialize agIORequest */ 8426 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 8427 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 8428 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 8429 8430 /* SMPAbort - abort one */ 8431 saSMPAbort(agRoot, 8432 agAbortIORequest, 8433 0, 8434 oneDeviceData->agDevHandle, 8435 0, /* abort one */ 8436 agToBeAbortIORequest, 8437 agNULL 8438 ); 8439 8440 } 8441 return; 8442 } 8443 8444 8445 /***************************************************************************** 8446 *! \brief tdsaSATAIDDeviceTimer 8447 * 8448 * Purpose: This function sets timers for sending ID device data only for 8449 * directly attached SATA device. 8450 * 8451 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8452 * instance. 8453 * \param onePortContext: Pointer to the portal context instance. 8454 * \param oneDeviceData: Pointer to the device data. 8455 * \param tdSMPRequestBody: Pointer to the SMP request body. 8456 * 8457 * \return: 8458 * None 8459 * 8460 * \note: 8461 * 8462 *****************************************************************************/ 8463 osGLOBAL void 8464 tdsaSATAIDDeviceTimer(tiRoot_t *tiRoot, 8465 tdsaDeviceData_t *oneDeviceData 8466 ) 8467 { 8468 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 8469 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 8470 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 8471 8472 TI_DBG1(("tdsaSATAIDDeviceTimer: start\n")); 8473 8474 if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE) 8475 { 8476 tdsaKillTimer( 8477 tiRoot, 8478 &oneDeviceData->SATAIDDeviceTimer 8479 ); 8480 } 8481 8482 tdsaSetTimerRequest( 8483 tiRoot, 8484 &oneDeviceData->SATAIDDeviceTimer, 8485 SATA_ID_DEVICE_DATA_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick, 8486 tdsaSATAIDDeviceTimerCB, 8487 oneDeviceData, 8488 agNULL, 8489 agNULL 8490 ); 8491 8492 tdsaAddTimer ( 8493 tiRoot, 8494 &Initiator->timerlist, 8495 &oneDeviceData->SATAIDDeviceTimer 8496 ); 8497 8498 return; 8499 } 8500 8501 /***************************************************************************** 8502 *! \brief tdsaSATAIDDeviceTimerCB 8503 * 8504 * Purpose: This function is callback function for SATA ID device data. 8505 * 8506 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 8507 * instance. 8508 * \param timerData1: Pointer to timer-related data structure 8509 * \param timerData2: Pointer to timer-related data structure 8510 * \param timerData3: Pointer to timer-related data structure 8511 * 8512 * \return: 8513 * None 8514 * 8515 * \note: 8516 * 8517 *****************************************************************************/ 8518 osGLOBAL void 8519 tdsaSATAIDDeviceTimerCB( 8520 tiRoot_t * tiRoot, 8521 void * timerData1, 8522 void * timerData2, 8523 void * timerData3 8524 ) 8525 { 8526 tdsaDeviceData_t *oneDeviceData; 8527 8528 TI_DBG1(("tdsaSATAIDDeviceTimerCB: start\n")); 8529 8530 oneDeviceData = (tdsaDeviceData_t *)timerData1; 8531 8532 /* send identify device data */ 8533 tdssSubAddSATAToSharedcontext(tiRoot, oneDeviceData); 8534 8535 if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE) 8536 { 8537 tdsaKillTimer( 8538 tiRoot, 8539 &oneDeviceData->SATAIDDeviceTimer 8540 ); 8541 } 8542 8543 return; 8544 } 8545 8546 #endif /* TD_DISCOVER */ 8547