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