1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ********************************************************************************/
22 /*******************************************************************************/
25 * This file contains initiator discover related functions
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 #include <dev/pms/config.h>
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>
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>
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>
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>
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>
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>
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>
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>
73 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
74 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
76 /*****************************************************************************
77 *! \brief tiINIDiscoverTargets
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.
83 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
89 * tiSuccess Discovery initiated.
90 * tiBusy Discovery could not be initiated at this time.
94 *****************************************************************************/
98 tiPortalContext_t *portalContext,
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;
109 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
110 dmPortContext_t *dmPortContext = agNULL;
113 this function is called after LINK_UP by ossaHWCB()
114 Therefore, tdsaportcontext is ready at this point
117 TI_DBG3(("tiINIDiscoverTargets: start\n"));
119 /* find a right tdsaPortContext using tiPortalContext
120 then, check the status of tdsaPortContext
121 then, if status is right, start the discovery
124 TI_DBG6(("tiINIDiscoverTargets: portalContext %p\n", portalContext));
125 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
126 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
128 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
129 TI_DBG1(("tiINIDiscoverTargets: No tdsaPortContext\n"));
134 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
137 /* find a right portcontext */
138 PortContextList = tdsaAllShared->MainPortContextList.flink;
139 if (PortContextList == agNULL)
141 TI_DBG1(("tiINIDiscoverTargets: PortContextList is NULL\n"));
144 while (PortContextList != &(tdsaAllShared->MainPortContextList))
146 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
147 if (onePortContext == agNULL)
149 TI_DBG1(("tiINIDiscoverTargets: onePortContext is NULL, PortContextList = %p\n", PortContextList));
152 if (onePortContext->tiPortalContext == portalContext && onePortContext->valid == agTRUE)
154 TI_DBG6(("tiINIDiscoverTargets: found; oneportContext ID %d\n", onePortContext->id));
158 PortContextList = PortContextList->flink;
161 if (found == agFALSE)
163 TI_DBG1(("tiINIDiscoverTargets: No corresponding tdsaPortContext\n"));
167 TI_DBG2(("tiINIDiscoverTargets: pid %d\n", onePortContext->id));
168 if (onePortContext->DiscoveryState == ITD_DSTATE_NOT_STARTED)
170 TI_DBG6(("tiINIDiscoverTargets: calling Discovery\n"));
171 /* start SAS discovery */
173 if (onePortContext->UseDM == agTRUE)
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);
182 /* complete discovery */
183 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
188 tiIntrEventTypeDiscovery,
202 AG_SA_DISCOVERY_TYPE_SAS,
203 TDSA_DISCOVERY_OPTION_FULL_START
206 saDiscover(onePortContext->agRoot, onePortContext->agPortContext, AG_SA_DISCOVERY_TYPE_SAS, onePortContext->discoveryOptions);
215 TI_DBG1(("tiINIDiscoverTargets: Discovery has started or incorrect initialization; state %d pid 0x%x\n",
216 onePortContext->DiscoveryState,
217 onePortContext->id));
224 /*****************************************************************************
225 *! \brief tiINIGetDeviceHandles
227 * Purpose: This routine is called to to return the device handles for each
228 * device currently available.
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
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
243 *****************************************************************************/
245 tiINIGetDeviceHandles(
247 tiPortalContext_t * tiPortalContext,
248 tiDeviceHandle_t * tiDev[],
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;
259 bit32 FoundDevices = 0;
260 bit32 DeviceIndex = 0;
261 bit32 found = agFALSE;
262 #ifdef TD_DEBUG_ENABLE
263 satDeviceData_t *pSatDevData;
266 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
269 TI_DBG2(("tiINIGetDeviceHandles: start\n"));
270 TI_DBG2(("tiINIGetDeviceHandles: tiPortalContext %p\n", tiPortalContext));
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++)
285 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
286 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
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++)
300 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
302 /* find a corresponding portcontext */
303 PortContextList = tdsaAllShared->MainPortContextList.flink;
304 while (PortContextList != &(tdsaAllShared->MainPortContextList))
306 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
307 if(onePortContext == agNULL) continue;
309 TI_DBG3(("tiINIGetDeviceHandles: oneportContext pid %d\n", onePortContext->id));
310 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
312 TI_DBG3(("tiINIGetDeviceHandles: found; oneportContext pid %d\n", onePortContext->id));
316 PortContextList = PortContextList->flink;
319 if (found == agFALSE)
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++)
331 if (onePortContext == agNULL)
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++)
343 if (onePortContext->valid == agFALSE)
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++)
355 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed)
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++)
367 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
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;
375 TI_DBG2(("tiINIGetDeviceHandles: pid %d\n", onePortContext->id));
378 tdsaUpdateMCN(dmRoot, onePortContext);
381 /* nullify all device handles */
382 for (i = 0 ; i < maxDevs ; i++)
388 From the device list, returns only valid devices
390 DeviceListList = tdsaAllShared->MainDeviceList.flink;
392 TD_ASSERT(DeviceListList, "DeviceListList NULL");
393 if (DeviceListList == agNULL )
395 TI_DBG1(("tiINIGetDeviceHandles: DeviceListList == agNULL\n"));
396 TI_DBG1(("tiINIGetDeviceHandles: seventh, returning not found, pid %d\n", onePortContext->id));
400 while ((DeviceIndex < maxDevs) &&
401 DeviceListList != &(tdsaAllShared->MainDeviceList))
403 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
404 #ifdef TD_DEBUG_ENABLE
405 pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData);
406 if (pSatDevData != agNULL)
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));
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));
415 TI_DBG6(("tiINIGetDeviceHandles: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
416 if (oneDeviceData->tdPortContext != onePortContext)
418 TI_DBG3(("tiINIGetDeviceHandles: different port\n"));
419 DeviceListList = DeviceListList->flink;
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) )
431 if ((oneDeviceData->valid == agTRUE) &&
432 (oneDeviceData->registered == agTRUE) &&
433 (oneDeviceData->tdPortContext == onePortContext) &&
434 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData) )
438 if (DEVICE_IS_SSP_TARGET(oneDeviceData))
440 TI_DBG2(("tiINIGetDeviceHandles: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
441 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
444 else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
446 oneDeviceData->satDevData.IDDeviceValid == agTRUE )
448 TI_DBG2(("tiINIGetDeviceHandles: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
449 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
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));
460 TI_DBG3(("tiINIGetDeviceHandles: valid FoundDevices %d\n", FoundDevices));
461 TI_DBG3(("tiINIGetDeviceHandles: agDevHandle %p\n", oneDeviceData->agDevHandle));
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));
470 DeviceListList = DeviceListList->flink;
474 if (DeviceIndex > maxDevs)
476 TI_DBG1(("tiINIGetDeviceHandles: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs));
477 FoundDevices = maxDevs;
480 TI_DBG1(("tiINIGetDeviceHandles: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id));
485 /*****************************************************************************
486 *! \brief tiINIGetDeviceHandlesForWinIOCTL
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.
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
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
504 *****************************************************************************/
506 tiINIGetDeviceHandlesForWinIOCTL(
508 tiPortalContext_t * tiPortalContext,
509 tiDeviceHandle_t * tiDev[],
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;
520 bit32 FoundDevices = 0;
521 bit32 DeviceIndex = 0;
522 bit32 found = agFALSE;
523 #ifdef TD_DEBUG_ENABLE
524 satDeviceData_t *pSatDevData;
527 dmRoot_t *dmRoot = &(tdsaAllShared->dmRoot);
530 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: start\n"));
531 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: tiPortalContext %p\n", tiPortalContext));
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++)
546 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
547 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
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++)
561 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
563 /* find a corresponding portcontext */
564 PortContextList = tdsaAllShared->MainPortContextList.flink;
565 while (PortContextList != &(tdsaAllShared->MainPortContextList))
567 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
568 if(onePortContext == agNULL) continue;
570 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: oneportContext pid %d\n", onePortContext->id));
571 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
573 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: found; oneportContext pid %d\n", onePortContext->id));
577 PortContextList = PortContextList->flink;
580 if (found == agFALSE)
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++)
592 if (onePortContext == agNULL)
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++)
604 if (onePortContext->valid == agFALSE)
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++)
616 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED && onePortContext->DMDiscoveryState == dmDiscFailed)
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++)
628 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
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;
636 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: pid %d\n", onePortContext->id));
639 tdsaUpdateMCN(dmRoot, onePortContext);
642 /* nullify all device handles */
643 for (i = 0 ; i < maxDevs ; i++)
649 From the device list, returns only valid devices
651 DeviceListList = tdsaAllShared->MainDeviceList.flink;
653 TD_ASSERT(DeviceListList, "DeviceListList NULL");
654 if (DeviceListList == agNULL )
656 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceListList == agNULL\n"));
657 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: seventh, returning not found, pid %d\n", onePortContext->id));
661 while ((DeviceIndex < maxDevs) &&
662 DeviceListList != &(tdsaAllShared->MainDeviceList))
664 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
665 if(oneDeviceData == agNULL)
667 TI_DBG3(("tiINIGetDeviceHandles: OneDeviceData is NULL\n"));
670 #ifdef TD_DEBUG_ENABLE
671 pSatDevData = (satDeviceData_t *)&(oneDeviceData->satDevData);
672 if (pSatDevData != agNULL)
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));
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));
681 TI_DBG6(("tiINIGetDeviceHandlesForWinIOCTL: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
682 if (oneDeviceData->tdPortContext != onePortContext)
684 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: different port\n"));
685 DeviceListList = DeviceListList->flink;
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))
697 if ((oneDeviceData->valid == agTRUE) &&
698 (oneDeviceData->registered == agTRUE) &&
699 (oneDeviceData->tdPortContext == onePortContext) &&
700 ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
704 if (DEVICE_IS_SSP_TARGET(oneDeviceData))
706 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SSP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
707 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
711 else if ( (DEVICE_IS_SATA_DEVICE(oneDeviceData) || DEVICE_IS_STP_TARGET(oneDeviceData))
713 oneDeviceData->satDevData.IDDeviceValid == agTRUE )
715 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SATA DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
716 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
720 else if (DEVICE_IS_SMP_TARGET(oneDeviceData))
722 TI_DBG2(("tiINIGetDeviceHandlesForWinIOCTL: SMP DeviceIndex %d tiDeviceHandle %p\n", DeviceIndex, &(oneDeviceData->tiDeviceHandle)));
723 tiDev[DeviceIndex] = &(oneDeviceData->tiDeviceHandle);
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));
735 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: valid FoundDevices %d\n", FoundDevices));
736 TI_DBG3(("tiINIGetDeviceHandlesForWinIOCTL: agDevHandle %p\n", oneDeviceData->agDevHandle));
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));
745 DeviceListList = DeviceListList->flink;
749 if (DeviceIndex > maxDevs)
751 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: DeviceIndex(%d) >= maxDevs(%d)\n", DeviceIndex, maxDevs));
752 FoundDevices = maxDevs;
755 TI_DBG1(("tiINIGetDeviceHandlesForWinIOCTL: returning %d found devices, pid %d\n", FoundDevices, onePortContext->id));
761 /*****************************************************************************
762 *! \brief tiINIGetDeviceInfo
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).
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.
773 * tiSuccess - successful
774 * tiInvalidHandle - device handle passed is not a valid handle.
778 *****************************************************************************/
782 tiDeviceHandle_t *tiDeviceHandle,
783 tiDeviceInfo_t *tiDeviceInfo)
785 tdsaDeviceData_t *oneDeviceData = agNULL;
786 satDeviceData_t *pSatDevData = agNULL;
788 bit8 SN_id_limit[25];
789 agsaRoot_t *agRoot = agNULL;
791 TI_DBG6(("tiINIGetDeviceInfo: start \n"));
793 if (tiDeviceHandle == agNULL)
795 TI_DBG6(("tiINIGetDeviceInfo: tiDeviceHandle NULL\n"));
796 return tiInvalidHandle;
799 if (tiDeviceHandle->tdData == agNULL)
801 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NULL\n"));
802 return tiInvalidHandle;
807 oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData);
808 agRoot = oneDeviceData->agRoot;
809 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ tiDeviceHandle->tdData NOT NULL\n"));
811 if (oneDeviceData == agNULL)
813 TI_DBG6(("tiINIGetDeviceInfo: ^^^^^^^^^ oneDeviceData NULL\n"));
814 return tiInvalidHandle;
818 /* filling in the link rate */
819 if (oneDeviceData->registered == agTRUE)
821 tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
825 tiDeviceInfo->info.devType_S_Rate = (bit8)(oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f);
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))
831 osti_memset(&id_limit, 0, sizeof(id_limit));
832 osti_memset(&SN_id_limit, 0, sizeof(SN_id_limit));
834 /* SATA signature 0xABCD */
840 pSatDevData = &(oneDeviceData->satDevData);
841 if (pSatDevData->satNCQ == agTRUE)
843 id_limit[4] = (bit8)pSatDevData->satNCQMaxIO;
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;
866 else if (DEVICE_IS_STP_TARGET(oneDeviceData))
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;
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;
886 tiDeviceInfo->localName = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi);
887 tiDeviceInfo->localAddress = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo);
889 TI_DBG6(("tiINIGetDeviceInfo: local hi 0x%08x lo 0x%08x\n", oneDeviceData->tdPortContext->sasLocalAddressHi, oneDeviceData->tdPortContext->sasLocalAddressLo));
891 if (oneDeviceData->agDevHandle == agNULL)
893 TI_DBG1(("tiINIGetDeviceInfo: Error! oneDeviceData->agDevHandle is NULL"));
898 saGetDeviceInfo(agRoot, agNULL, 0, 0,oneDeviceData->agDevHandle);
905 /*****************************************************************************
908 * Purpose: This function is called to request that the Transport Dependent
909 * Layer initiates login for a specific target.
911 * \param tiRoot: Pointer to driver Instance.
912 * \param tiDeviceHandle: Pointer to a target device handle discovered
913 * following the discovery.
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
923 *****************************************************************************/
927 tiDeviceHandle_t *tiDeviceHandle
930 TI_DBG6(("tiINILogin: start\n"));
931 return tiNotSupported;
934 /*****************************************************************************
935 *! \brief tiINILogout
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.
941 * \param tiRoot : Pointer to the OS Specific module allocated tiRoot_t
943 * \param tiDeviceHandle: Pointer to a target device handle.
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
953 *****************************************************************************/
957 tiDeviceHandle_t *tiDeviceHandle
960 TI_DBG6(("tiINILogout: start\n"));
961 return tiNotSupported;
963 /*****************************************************************************
964 *! \brief tiINIGetExpander
969 *****************************************************************************/
973 tiPortalContext_t * tiPortalContext,
974 tiDeviceHandle_t * tiDev,
975 tiDeviceHandle_t ** tiExp
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)
990 TI_DBG1(("tiINIGetExpander: oneTargetDeviceData is NULL\n"));
993 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
994 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
996 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
997 TI_DBG1(("tiINIGetExpander: No available tdsaPortContext\n"));
998 TI_DBG1(("tiINIGetExpander: second, returning 0\n"));
1003 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
1005 /* find a corresponding portcontext */
1006 PortContextList = tdsaAllShared->MainPortContextList.flink;
1007 while (PortContextList != &(tdsaAllShared->MainPortContextList))
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)
1013 TI_DBG3(("tiINIGetExpander: found; oneportContext pid %d\n", onePortContext->id));
1017 PortContextList = PortContextList->flink;
1019 if (found == agFALSE)
1021 TI_DBG1(("tiINIGetExpander: First, No corresponding tdsaPortContext\n"));
1022 TI_DBG1(("tiINIGetExpander: third, returning 0\n"));
1025 if (onePortContext == agNULL)
1027 TI_DBG1(("tiINIGetExpander: Second, No corressponding tdsaPortContext\n"));
1028 TI_DBG1(("tiINIGetExpander: fourth, returning 0\n"));
1031 if (onePortContext->valid == agFALSE)
1033 TI_DBG1(("tiINIGetExpander: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
1034 TI_DBG1(("tiINIGetExpander: fifth, returning 0\n"));
1037 DeviceListList = tdsaAllShared->MainDeviceList.flink;
1038 while ( DeviceListList != &(tdsaAllShared->MainDeviceList) )
1040 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
1041 if (oneDeviceData->tdPortContext != onePortContext)
1043 TI_DBG3(("tiINIGetExpander: different port\n"));
1044 DeviceListList = DeviceListList->flink;
1048 if (oneDeviceData == oneTargetDeviceData)
1050 oneExpanderDeviceData = oneDeviceData->ExpDevice;
1051 if (oneExpanderDeviceData == agNULL)
1053 TI_DBG1(("tiINIGetExpander: oneExpanderDeviceData is NULL\n"));
1056 *tiExp = &(oneExpanderDeviceData->tiDeviceHandle);
1059 DeviceListList = DeviceListList->flink;
1066 osGLOBAL void tiIniGetDirectSataSasAddr(tiRoot_t * tiRoot, bit32 phyId, bit8 **sasAddressHi, bit8 **sasAddressLo)
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;
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))
1083 status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev);
1088 status = tdsaNVMDGetIoctl(tiRoot, (tiIOCTLPayload_t *)&agIoctlPayload, agNULL, agNULL, &nvmDev);
1090 if(status == IOCTL_CALL_FAIL)
1092 #if !(defined(__FreeBSD__))
1093 printk("Error getting Adapter WWN\n");
1095 printf("Error getting Adapter WWN\n");
1099 for(i=0; i< TD_MAX_NUM_PHYS; i++)
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)));
1106 *sasAddressHi = tdsaAllShared->Ports[phyId].SASID.sasAddressHi;
1107 *sasAddressLo = tdsaAllShared->Ports[phyId].SASID.sasAddressLo;
1109 osGLOBAL tiDeviceHandle_t *
1110 tiINIGetExpDeviceHandleBySasAddress(
1112 tiPortalContext_t * tiPortalContext,
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;
1126 //bit32 FoundDevices = 0;
1127 bit32 DeviceIndex = 0;
1128 bit32 found = agFALSE;
1131 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: start\n"));
1132 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: tiPortalContext %p\n", tiPortalContext));
1137 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: maxDevs is 0\n"));
1142 tdsaSingleThreadedEnter(tiRoot, TD_PORT_LOCK);
1143 if (TDLIST_EMPTY(&(tdsaAllShared->MainPortContextList)))
1145 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
1146 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: No available tdsaPortContext\n"));
1147 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: second, returning 0\n"));
1152 tdsaSingleThreadedLeave(tiRoot, TD_PORT_LOCK);
1154 /* find a corresponding portcontext */
1155 PortContextList = tdsaAllShared->MainPortContextList.flink;
1157 if(PortContextList == agNULL)
1159 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: PortContextList is NULL!!\n"));
1163 while (PortContextList != &(tdsaAllShared->MainPortContextList))
1165 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
1167 if(onePortContext == agNULL)
1169 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: onePortContext is NULL!!\n"));
1173 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneportContext pid %d\n", onePortContext->id));
1174 if (onePortContext->tiPortalContext == tiPortalContext && onePortContext->valid == agTRUE)
1176 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: found; oneportContext pid %d\n", onePortContext->id));
1181 if(PortContextList != agNULL)
1183 PortContextList = PortContextList->flink;
1188 if (found == agFALSE)
1190 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: First, No corresponding tdsaPortContext\n"));
1191 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: third, returning 0\n"));
1192 /* nullify all device handles */
1196 if (onePortContext == agNULL)
1198 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Second, No corressponding tdsaPortContext\n"));
1199 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fourth, returning 0\n"));
1200 /* nullify all device handles */
1204 if (onePortContext->valid == agFALSE)
1206 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: Third, tdsaPortContext is invalid, pid %d\n", onePortContext->id));
1207 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: fifth, returning 0\n"));
1212 TI_DBG2(("tiINIGetExpDeviceHandleBySasAddress: pid %d\n", onePortContext->id));
1215 /* to do: check maxdev and length of Mainlink */
1217 From the device list, returns only valid devices
1219 DeviceListList = tdsaAllShared->MainDeviceList.flink;
1221 if(DeviceListList == agNULL)
1223 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: DeviceListList == agNULL\n"));
1224 TI_DBG1(("tiINIGetExpDeviceHandleBySasAddress: seventh, returning not found, pid %d\n", onePortContext->id));
1228 while ((DeviceIndex < maxDevs) &&
1229 DeviceListList != &(tdsaAllShared->MainDeviceList))
1231 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
1233 if(oneDeviceData == agNULL)
1235 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: oneDeviceData is NULL!!\n"));
1240 TI_DBG6(("tiINIGetExpDeviceHandleBySasAddress: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
1241 if (oneDeviceData->tdPortContext != onePortContext)
1243 TI_DBG3(("tiINIGetExpDeviceHandleBySasAddress: different port\n"));
1245 if(DeviceListList != agNULL)
1247 DeviceListList = DeviceListList->flink;
1254 if ((oneDeviceData->valid == agTRUE) &&
1255 (oneDeviceData->registered == agTRUE) &&
1256 (oneDeviceData->tdPortContext == onePortContext) &&
1258 (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE) ||
1259 (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE) ||
1260 DEVICE_IS_SMP_TARGET(oneDeviceData)
1266 if(oneDeviceData->SASAddressID.sasAddressLo == sas_addr_lo && oneDeviceData->SASAddressID.sasAddressHi == sas_addr_hi)
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);
1275 DeviceListList = DeviceListList->flink;
1286 /*****************************************************************************
1287 *! \brief tdsaDiscover
1289 * Purpose: This function is called to trigger topology discovery within a
1292 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
1299 * tiSuccess Discovery initiated.
1300 * tiError Discovery could not be initiated at this time.
1304 *****************************************************************************/
1308 tdsaPortContext_t *onePortContext,
1314 bit32 ret = tiError;
1315 TI_DBG3(("tdsaDiscover: start\n"));
1317 if (onePortContext->valid == agFALSE)
1319 TI_DBG1(("tdsaDiscover: aborting discovery\n"));
1320 tdsaSASDiscoverAbort(tiRoot, onePortContext);
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 )
1331 ret = tdsaSASFullDiscover(tiRoot, onePortContext);
1334 else if ( type == TDSA_DISCOVERY_TYPE_SATA )
1336 if (onePortContext->discovery.status == DISCOVERY_SAS_DONE)
1338 ret = tdsaSATAFullDiscover(tiRoot, onePortContext);
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 )
1348 TI_DBG3(("tdsaDiscover: incremental SAS\n"));
1349 ret = tdsaSASIncrementalDiscover(tiRoot, onePortContext);
1352 else if ( type == TDSA_DISCOVERY_TYPE_SATA )
1354 if (onePortContext->discovery.status == DISCOVERY_SAS_DONE)
1356 TI_DBG3(("tdsaDiscover: incremental SATA\n"));
1357 ret = tdsaSATAIncrementalDiscover(tiRoot, onePortContext);
1362 case TDSA_DISCOVERY_OPTION_ABORT:
1363 TI_DBG1(("tdsaDiscover: abort\n"));
1369 if (ret != tiSuccess)
1371 TI_DBG1(("tdsaDiscover: fail, error 0x%x\n", ret));
1376 /*****************************************************************************
1377 *! \brief tdsaSASFullDiscover
1379 * Purpose: This function is called to trigger full SAS topology discovery
1380 * within a portcontext.
1382 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1384 * \param onePortContext: Pointer to the portal context instance.
1387 * tiSuccess Discovery initiated.
1388 * tiError Discovery could not be initiated at this time.
1392 *****************************************************************************/
1394 tdsaSASFullDiscover(
1396 tdsaPortContext_t *onePortContext
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;
1405 TI_DBG3(("tdsaSASFullDiscover: start\n"));
1406 if (onePortContext->valid == agFALSE)
1408 TI_DBG1(("tdsaSASFullDiscover: aborting discovery\n"));
1409 tdsaSASDiscoverAbort(tiRoot, onePortContext);
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)
1420 invalidate all devices belonging to the portcontext except direct attached SAS/SATA
1422 DeviceListList = tdsaAllShared->MainDeviceList.flink;
1423 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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) )
1433 TI_DBG3(("tdsaSASFullDiscover: invalidate\n"));
1434 oneDeviceData->valid = agFALSE;
1435 oneDeviceData->processed = agFALSE;
1439 TI_DBG3(("tdsaSASFullDiscover: not invalidate\n"));
1442 DeviceListList = DeviceListList->flink;
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 */
1449 if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE &&
1450 SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) )
1452 for(i=0;i<TD_MAX_NUM_PHYS;i++)
1454 if (onePortContext->PhyIDList[i] == agTRUE)
1457 for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++)
1459 saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL);
1467 1. add device in TD layer
1468 2. call saRegisterNewDevice
1469 3. update agDevHandle in ossaDeviceRegistrationCB()
1471 portMaxRate = onePortContext->LinkRate;
1472 oneDeviceData = tdsaPortSASDeviceAdd(
1475 onePortContext->sasIDframe,
1486 if (oneDeviceData->registered == agFALSE)
1489 set the timer and wait till the device(directly attached. eg Expander) to be registered.
1490 Then, in tdsaDeviceRegistrationTimerCB(), tdsaSASUpStreamDiscoverStart() is called
1492 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
1496 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
1500 // temp testing code
1501 tdsaReportManInfoSend(tiRoot, oneDeviceData);
1502 //end temp testing code
1505 else /* SATAOnlyMode*/
1507 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
1513 /*****************************************************************************
1514 *! \brief tdsaSASUpStreamDiscoverStart
1516 * Purpose: This function is called to trigger upstream traverse in topology
1517 * within a portcontext.
1519 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1521 * \param onePortContext: Pointer to the portal context instance.
1522 * \param oneDeviceData: Pointer to the device data.
1529 *****************************************************************************/
1531 tdsaSASUpStreamDiscoverStart(
1533 tdsaPortContext_t *onePortContext,
1534 tdsaDeviceData_t *oneDeviceData
1537 tdsaExpander_t *oneExpander;
1539 TI_DBG3(("tdsaSASUpStreamDiscoverStart: start\n"));
1541 if (onePortContext->valid == agFALSE)
1543 TI_DBG1(("tdsaSASUpStreamDiscoverStart: aborting discovery\n"));
1544 tdsaSASDiscoverAbort(tiRoot, onePortContext);
1549 1. update discovery state to UP_STREAM
1550 2. if (expander) add it
1551 3. tdsaSASUpStreamDiscovering
1554 onePortContext->discovery.status = DISCOVERY_UP_STREAM;
1556 (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE)
1558 (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE)
1561 oneExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, oneDeviceData);
1562 if ( oneExpander != agNULL)
1564 /* (2.2.1) Add to discovering list */
1565 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
1569 TI_DBG1(("tdsaSASUpStreamDiscoverStart: failed to allocate expander or discovey aborted\n"));
1574 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
1579 /*****************************************************************************
1580 *! \brief tdsaSASUpStreamDiscovering
1582 * Purpose: For each expander in the expander list, this function sends SMP to
1583 * find information for discovery and calls
1584 * tdsaSASDownStreamDiscoverStart() function.
1586 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1588 * \param onePortContext: Pointer to the portal context instance.
1589 * \param oneDeviceData: Pointer to the device data.
1596 *****************************************************************************/
1598 tdsaSASUpStreamDiscovering(
1600 tdsaPortContext_t *onePortContext,
1601 tdsaDeviceData_t *oneDeviceData
1604 tdList_t *ExpanderList;
1605 tdsaExpander_t *oneNextExpander = agNULL;
1607 TI_DBG3(("tdsaSASUpStreamDiscovering: start\n"));
1608 if (onePortContext->valid == agFALSE)
1610 TI_DBG1(("tdsaSASUpStreamDiscovering: aborting discovery\n"));
1611 tdsaSASDiscoverAbort(tiRoot, onePortContext);
1615 1. find the next expander
1616 2. if (there is next expander) send report general with saSMPStart
1617 else tdsaSASDownStreamDiscoverStart
1620 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
1621 if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList)))
1623 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1624 TI_DBG3(("tdsaSASUpStreamDiscovering: should be the end\n"));
1625 oneNextExpander = agNULL;
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);
1634 TI_DBG3(("tdssSASDiscoveringExpander tdsaSASUpStreamDiscovering: dequeue head\n"));
1635 TI_DBG3(("tdsaSASUpStreamDiscovering: expander id %d\n", oneNextExpander->id));
1638 if (oneNextExpander != agNULL)
1640 tdsaReportGeneralSend(tiRoot, oneNextExpander->tdDevice);
1644 TI_DBG3(("tdsaSASUpStreamDiscovering: No more expander list\n"));
1645 tdsaSASDownStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
1651 /*****************************************************************************
1652 *! \brief tdsaSASDownStreamDiscoverStart
1654 * Purpose: This function is called to trigger downstream traverse in topology
1655 * within a portcontext.
1657 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1659 * \param onePortContext: Pointer to the portal context instance.
1660 * \param oneDeviceData: Pointer to the device data.
1667 *****************************************************************************/
1669 tdsaSASDownStreamDiscoverStart(
1671 tdsaPortContext_t *onePortContext,
1672 tdsaDeviceData_t *oneDeviceData
1675 tdsaExpander_t *oneExpander;
1676 tdsaExpander_t *UpStreamExpander;
1677 TI_DBG3(("tdsaSASDownStreamDiscoverStart: start\n"));
1679 if (onePortContext->valid == agFALSE)
1681 TI_DBG1(("tdsaSASDownStreamDiscoverStart: aborting discovery\n"));
1682 tdsaSASDiscoverAbort(tiRoot, onePortContext);
1686 1. update discover state
1687 2. if (expander is root) add it
1689 3. tdsaSASDownStreamDiscovering
1692 /* set discovery status */
1693 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
1695 TI_DBG3(("tdsaSASDownStreamDiscoverStart: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData));
1697 /* If it's an expander */
1698 if ( (oneDeviceData->SASSpecDeviceType == SAS_EDGE_EXPANDER_DEVICE)
1699 || (oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE))
1701 oneExpander = oneDeviceData->tdExpander;
1702 UpStreamExpander = oneExpander->tdUpStreamExpander;
1704 /* If the two expanders are the root of two edge sets; sub-to-sub */
1705 if ( (UpStreamExpander != agNULL) && ( UpStreamExpander->tdUpStreamExpander == oneExpander ) )
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));
1714 /* reset up stream inform for pExpander */
1715 oneExpander->tdUpStreamExpander = agNULL;
1716 /* Add the pExpander to discovering list */
1717 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
1719 /* reset up stream inform for oneExpander */
1720 UpStreamExpander->tdUpStreamExpander = agNULL;
1721 /* Add the UpStreamExpander to discovering list */
1722 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, UpStreamExpander);
1724 /* If the two expanders are not the root of two edge sets. eg) one root */
1727 //Saves the root expander
1728 onePortContext->discovery.RootExp = oneExpander;
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));
1734 /* (2.2.2.1) Add the pExpander to discovering list */
1735 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, oneExpander);
1739 /* Continue down stream discovering */
1740 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
1745 /*****************************************************************************
1746 *! \brief tdsaSASDownStreamDiscovering
1748 * Purpose: For each expander in the expander list, this function sends SMP to
1749 * find information for discovery and calls
1750 * tdsaSASDownStreamDiscoverStart() function.
1752 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1754 * \param onePortContext: Pointer to the portal context instance.
1755 * \param oneDeviceData: Pointer to the device data.
1762 *****************************************************************************/
1764 tdsaSASDownStreamDiscovering(
1766 tdsaPortContext_t *onePortContext,
1767 tdsaDeviceData_t *oneDeviceData
1770 tdsaExpander_t *NextExpander = agNULL;
1771 tdList_t *ExpanderList;
1773 TI_DBG3(("tdsaSASDownStreamDiscovering: start\n"));
1775 TI_DBG3(("tdsaSASDownStreamDiscovering: pPort=%p pDevice=%p\n", onePortContext, oneDeviceData));
1777 if (onePortContext->valid == agFALSE)
1779 TI_DBG1(("tdsaSASDownStreamDiscovering: aborting discovery\n"));
1780 tdsaSASDiscoverAbort(tiRoot, onePortContext);
1784 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
1785 if (TDLIST_EMPTY(&(onePortContext->discovery.discoveringExpanderList)))
1787 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1788 TI_DBG3(("tdsaSASDownStreamDiscovering: should be the end\n"));
1789 NextExpander = agNULL;
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));
1802 /* If there is an expander for continue discoving */
1803 if ( NextExpander != agNULL)
1805 TI_DBG3(("tdsaSASDownStreamDiscovering: Found pNextExpander=%p\n, discoveryStatus=0x%x",
1806 NextExpander, onePortContext->discovery.status));
1808 switch (onePortContext->discovery.status)
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);
1816 /* If the discovery status is DISCOVERY_CONFIG_ROUTING */
1817 case DISCOVERY_CONFIG_ROUTING:
1818 case DISCOVERY_REPORT_PHY_SATA:
1820 /* set discovery status */
1821 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
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 )
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);
1832 /* If it's the last phy */
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);
1843 TI_DBG3(("tdsaSASDownStreamDiscovering: *** Unknown pPort->discovery.status=0x%x\n", onePortContext->discovery.status));
1846 /* If no expander for continue discoving */
1849 TI_DBG3(("tdsaSASDownStreamDiscovering: No more expander DONE\n"));
1851 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
1857 /*****************************************************************************
1858 *! \brief tdsaCleanAllExp
1860 * Purpose: This function cleans up expander data structures after discovery
1863 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1865 * \param onePortContext: Pointer to the portal context instance.
1872 *****************************************************************************/
1876 tdsaPortContext_t *onePortContext
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;
1885 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: start\n"));
1887 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: before all clean up\n"));
1888 tdsaDumpAllFreeExp(tiRoot);
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)))
1895 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1896 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
1897 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
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));
1907 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
1909 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1914 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1916 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
1918 // ExpanderList = ExpanderList->flink;
1923 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1924 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: empty discoveringExpanderList\n"));
1927 /* reset UpdiscoveringExpanderList */
1928 TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList));
1930 TI_DBG3(("tdssSASDiscoveringExpander tdsaCleanAllExp: after all clean up\n"));
1931 tdsaDumpAllFreeExp(tiRoot);
1936 /*****************************************************************************
1937 *! \brief tdsaFreeAllExp
1939 * Purpose: This function frees up expander data structures as a part of
1942 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
1944 * \param onePortContext: Pointer to the portal context instance.
1951 *****************************************************************************/
1955 tdsaPortContext_t *onePortContext
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;
1964 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: start\n"));
1966 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: before all clean up\n"));
1967 tdsaDumpAllFreeExp(tiRoot);
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)))
1974 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1975 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
1976 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
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));
1986 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
1988 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1993 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
1995 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
1997 // ExpanderList = ExpanderList->flink;
2002 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
2003 TI_DBG3(("tdssSASDiscoveringExpander tdsaFreeAllExp: empty discoveringExpanderList\n"));
2006 /* reset UpdiscoveringExpanderList */
2007 TDLIST_INIT_HDR(&(tmpOnePortContext->discovery.UpdiscoveringExpanderList));
2011 /*****************************************************************************
2012 *! \brief tdsaResetValidDeviceData
2014 * Purpose: This function resets valid and valid2 field for discovered devices
2015 * in the device list. This is used only in incremental discovery.
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.
2026 *****************************************************************************/
2028 tdsaResetValidDeviceData(
2030 tdsaPortContext_t *onePortContext
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;
2040 TI_DBG3(("tdsaResetValidDeviceData: start\n"));
2042 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2043 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2045 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2046 TI_DBG1(("tdsaResetValidDeviceData: empty device list\n"));
2050 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2051 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2052 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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));
2065 /*****************************************************************************
2066 *! \brief tdssReportChanges
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.
2072 * \param agRoot : Pointer to chip/driver Instance.
2073 * \param onePortContext: Pointer to the portal context instance.
2080 *****************************************************************************/
2084 tdsaPortContext_t *onePortContext
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;
2095 TI_DBG1(("tdssReportChanges: start\n"));
2097 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2098 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2100 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2101 TI_DBG1(("tdssReportChanges: empty device list\n"));
2106 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2108 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2109 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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)
2116 TI_DBG3(("tdssReportChanges: right portcontext\n"));
2117 if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agTRUE) )
2119 TI_DBG3(("tdssReportChanges: same\n"));
2120 /* reset valid bit */
2121 oneDeviceData->valid = oneDeviceData->valid2;
2122 oneDeviceData->valid2 = agFALSE;
2124 else if ( (oneDeviceData->valid == agTRUE) && (oneDeviceData->valid2 == agFALSE) )
2126 TI_DBG3(("tdssReportChanges: removed\n"));
2128 /* reset valid bit */
2129 oneDeviceData->valid = oneDeviceData->valid2;
2130 oneDeviceData->valid2 = agFALSE;
2131 /* reset NumOfFCA */
2132 oneDeviceData->satDevData.NumOfFCA = 0;
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) )
2139 tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
2141 else if (oneDeviceData->registered == agTRUE)
2143 TI_DBG1(("tdssReportChanges: calling saDeregisterDeviceHandle, did %d\n", oneDeviceData->id));
2144 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, 0);
2147 oneDeviceData->registered = agFALSE;
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));
2154 else if ( (oneDeviceData->valid == agFALSE) && (oneDeviceData->valid2 == agTRUE) )
2156 TI_DBG3(("tdssReportChanges: added\n"));
2158 /* reset valid bit */
2159 oneDeviceData->valid = oneDeviceData->valid2;
2160 oneDeviceData->valid2 = agFALSE;
2164 TI_DBG6(("tdssReportChanges: else\n"));
2169 TI_DBG1(("tdssReportChanges: different portcontext\n"));
2171 DeviceListList = DeviceListList->flink;
2173 /* arrival or removal at once */
2174 if (added == agTRUE)
2176 TI_DBG3(("tdssReportChanges: added at the end\n"));
2178 if (tdsaAllShared->SASConnectTimeLimit)
2179 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDeviceChange,
2185 onePortContext->tiPortalContext,
2187 tiIntrEventTypeDeviceChange,
2193 if (removed == agTRUE)
2195 TI_DBG3(("tdssReportChanges: removed at the end\n"));
2198 onePortContext->tiPortalContext,
2200 tiIntrEventTypeDeviceChange,
2206 if (onePortContext->discovery.forcedOK == agTRUE && added == agFALSE && removed == agFALSE)
2208 TI_DBG1(("tdssReportChanges: missed chance to report. forced to report OK\n"));
2209 onePortContext->discovery.forcedOK = agFALSE;
2212 onePortContext->tiPortalContext,
2214 tiIntrEventTypeDiscovery,
2220 if (added == agFALSE && removed == agFALSE)
2222 TI_DBG3(("tdssReportChanges: the same\n"));
2226 /*****************************************************************************
2227 *! \brief tdssReportRemovals
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
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.
2243 *****************************************************************************/
2247 tdsaPortContext_t *onePortContext,
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;
2261 agsaDevHandle_t *agDevHandle = agNULL;
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 &&
2271 TI_DBG2(("tdssReportRemovals: calling saHwEventAck\n"));
2272 eventSource = &(tdsaAllShared->eventSource[PhyID].Source);
2273 HwAckSatus = saHwEventAck(
2275 agNULL, /* agContext */
2277 eventSource, /* agsaEventSource_t */
2281 if ( HwAckSatus != AGSA_RC_SUCCESS)
2283 TI_DBG1(("tdssReportRemovals: failing in saHwEventAck; status %d\n", HwAckSatus));
2287 tdsaAllShared->eventSource[PhyID].EventValid = agFALSE;
2288 if (onePortContext->valid == agFALSE)
2290 /* put device belonging to the port to freedevice list */
2291 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2292 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
2294 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
2295 if (oneDeviceData->tdPortContext == onePortContext)
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)))
2303 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2306 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2307 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2311 DeviceListList = DeviceListList->flink;
2315 tdsaPortContextReInit(tiRoot, onePortContext);
2317 put all devices belonging to the onePortContext
2318 back to the free link
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);
2329 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2330 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2332 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2333 TI_DBG1(("tdssReportRemovals: 1st empty device list\n"));
2338 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
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))
2344 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
2345 if (oneDeviceData == agNULL)
2347 TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n"));
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
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)))
2377 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2382 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2387 DeviceListList = DeviceListList->flink;
2392 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2393 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2395 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2396 TI_DBG1(("tdssReportRemovals: 2nd empty device list\n"));
2401 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2403 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2404 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
2406 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
2407 if (oneDeviceData == agNULL)
2409 TI_DBG1(("tdssReportRemovals: oneDeviceData is NULL!!!\n"));
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)
2421 TI_DBG2(("tdssReportRemovals: right portcontext pid %d\n", onePortContext->id));
2422 if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE)
2424 TI_DBG2(("tdssReportRemovals: removing\n"));
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)
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) )
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);
2447 else if (oneDeviceData->registered == agTRUE)
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);
2456 /* reset valid bit */
2457 oneDeviceData->valid = agFALSE;
2458 oneDeviceData->valid2 = agFALSE;
2459 oneDeviceData->registered = agFALSE;
2460 /* reset NumOfFCA */
2461 oneDeviceData->satDevData.NumOfFCA = 0;
2464 /* called by port invalid case */
2467 oneDeviceData->tdPortContext = agNULL;
2468 TI_DBG1(("tdssReportRemovals: nulling-out tdPortContext; oneDeviceData did %d\n", oneDeviceData->id));
2470 #ifdef REMOVED /* removed */
2471 /* directly attached SATA -> always remove it */
2472 if (oneDeviceData->DeviceType == TD_SATA_DEVICE &&
2473 oneDeviceData->directlyAttached == agTRUE)
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)))
2486 DeviceListList = DeviceListList->flink;
2488 #endif /* REMOVED */
2489 DeviceListList = DeviceListList->flink;
2493 if (oneDeviceData->tdPortContext != agNULL)
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));
2500 TI_DBG1(("tdssReportRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d oneDeviceData did %d\n",
2501 onePortContext->id, oneDeviceData->id));
2503 DeviceListList = DeviceListList->flink;
2507 if (removed == agTRUE)
2509 TI_DBG2(("tdssReportRemovals: removed at the end\n"));
2512 onePortContext->tiPortalContext,
2514 tiIntrEventTypeDeviceChange,
2524 changes valid and valid2 based on discovery type
2527 tdssInternalRemovals(
2529 tdsaPortContext_t *onePortContext
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;
2539 TI_DBG2(("tdssInternalRemovals: start\n"));
2541 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2542 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2544 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2545 TI_DBG1(("tdssInternalRemovals: empty device list\n"));
2550 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2552 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2553 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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)
2565 TI_DBG3(("tdssInternalRemovals: right portcontext pid %d\n", onePortContext->id));
2566 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START)
2568 TI_DBG3(("tdssInternalRemovals: incremental discovery\n"));
2569 oneDeviceData->valid2 = agFALSE;
2573 TI_DBG3(("tdssInternalRemovals: full discovery\n"));
2574 oneDeviceData->valid = agFALSE;
2576 DeviceListList = DeviceListList->flink;
2580 if (oneDeviceData->tdPortContext != agNULL)
2582 TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id));
2586 TI_DBG3(("tdssInternalRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id));
2588 DeviceListList = DeviceListList->flink;
2596 /* resets all valid and valid2 */
2598 tdssDiscoveryErrorRemovals(
2600 tdsaPortContext_t *onePortContext
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;
2610 TI_DBG1(("tdssDiscoveryErrorRemovals: start\n"));
2612 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
2613 if (TDLIST_EMPTY(&(tdsaAllShared->MainDeviceList)))
2615 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2616 TI_DBG1(("tdssDiscoveryErrorRemovals: empty device list\n"));
2621 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
2623 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2624 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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)
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;
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) )
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);
2654 else if (oneDeviceData->registered == agTRUE)
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);
2664 oneDeviceData->registered = agFALSE;
2665 DeviceListList = DeviceListList->flink;
2669 if (oneDeviceData->tdPortContext != agNULL)
2671 TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid %d oneportcontext pid %d\n", oneDeviceData->tdPortContext->id, onePortContext->id));
2675 TI_DBG2(("tdssDiscoveryErrorRemovals: different portcontext; oneDeviceData->tdPortContext pid NULL oneportcontext pid %d\n", onePortContext->id));
2677 DeviceListList = DeviceListList->flink;
2685 /*****************************************************************************
2686 *! \brief tdsaSASDiscoverAbort
2688 * Purpose: This function aborts on-going discovery.
2690 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
2692 * \param onePortContext: Pointer to the portal context instance.
2699 *****************************************************************************/
2700 /* this called when discovery is aborted
2704 tdsaSASDiscoverAbort(
2706 tdsaPortContext_t *onePortContext
2710 TI_DBG2(("tdsaSASDiscoverAbort: start\n"));
2711 TI_DBG2(("tdsaSASDiscoverAbort: pPort=%p DONE\n", onePortContext));
2712 TI_DBG2(("tdsaSASDiscoverAbort: DiscoveryState %d\n", onePortContext->DiscoveryState));
2714 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
2715 /* clean up expanders data strucures; move to free exp when device is cleaned */
2716 tdsaCleanAllExp(tiRoot, onePortContext);
2718 /* unregister devices */
2719 tdssReportRemovals(onePortContext->agRoot,
2730 tdsaPortContext_t *onePortContext,
2731 tdIORequest_t *tdIORequest,
2732 tdList_t *DeviceList);
2737 agsaIORequest_t *agIORequest,
2744 tiRoot_t *tiRoot = (tiRoot_t*)
2745 ((tdsaRootOsData_t*)agRoot->osData)->tiRoot;
2746 tdIORequestBody_t *tdIORequestBody;
2747 tdIORequest_t *tdIORequest;
2748 tdsaDeviceData_t *oneDeviceData;
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;
2756 TI_DBG6(("tdsaCTLIOCompleted: stat x%x len %d id %d\n", agIOStatus,
2757 agIOInfoLen, oneDeviceData->id));
2759 //if ((agIOStatus == OSSA_IO_SUCCESS) && (agIOInfoLen == 0))
2760 /* SCSI command was completed OK, this is the normal path. */
2763 TI_DBG6(("tdsaCTLIOCompleted: SASDevAddr 0x%x / 0x%x PhyId 0x%x WARN "
2765 oneDeviceData->SASAddressID.sasAddressHi,
2766 oneDeviceData->SASAddressID.sasAddressLo,
2767 oneDeviceData->SASAddressID.phyIdentifier));
2768 tdhexdump("tdsaCTLIOCompleted: response", (bit8 *)agParam, agIOInfoLen);
2771 tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest,
2772 oneDeviceData->MainLink.flink);
2773 } /* tdsaCTLIOCompleted */
2778 tiDeviceHandle_t *tiDeviceHandle,
2779 tdIORequest_t *tdIORequest)
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;
2792 tdIORequestBody_t *tdIORequestBody;
2793 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
2794 unsigned char *virtAddr;
2796 static unsigned char cdb[6] =
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;
2811 oneDeviceData = (tdsaDeviceData_t*)tiDeviceHandle->tdData;
2812 TI_DBG4(("tdsaCTLModeSelect: id %d\n", oneDeviceData->id));
2814 agRoot = oneDeviceData->agRoot;
2815 agDevHandle = oneDeviceData->agDevHandle;
2816 tiIORequest = &tdIORequest->tiIORequest;
2818 tdIORequestBody = &tdIORequest->tdIORequestBody;
2820 //tdIORequestBody->IOCompletionFunc = tdsaCTLIOCompleted;//itdssIOCompleted;
2821 tdIORequestBody->tiDevHandle = tiDeviceHandle;
2822 tdIORequestBody->IOType.InitiatorRegIO.expDataLength = DR_MODE_PG_SZ;
2824 agIORequest = &tdIORequestBody->agIORequest;
2825 agIORequest->sdkData = agNULL; /* LL takes care of this */
2827 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
2828 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
2830 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, cdb, 6);
2831 agSSPInitiatorRequest->dataLength = DR_MODE_PG_SZ;
2833 agSSPInitiatorRequest->firstBurstSize = 0;
2835 tdIORequestBody->agRequestType = AGSA_SSP_INIT_WRITE;
2836 tdIORequestBody->ioStarted = agTRUE;
2837 tdIORequestBody->ioCompleted = agFALSE;
2839 agSgl.lower = BIT32_TO_LEBIT32(tdIORequest->physLower32);
2840 #if (BITS_PER_LONG > 32)
2841 agSgl.upper = BIT32_TO_LEBIT32(tdIORequest->physUpper32);
2845 agSgl.type = BIT32_TO_LEBIT32(tiSgl);
2846 agSgl.len = BIT32_TO_LEBIT32(DR_MODE_PG_SZ);
2848 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */
2849 tiStatus = itdssIOPrepareSGL(tiRoot, tdIORequestBody, &agSgl,
2850 tdIORequest->virtAddr);
2851 if (tiStatus != tiSuccess)
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));
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)
2865 tiStatus = tiSuccess;
2866 TI_DBG4(("tdsaCTLModeSelect: saSSPStart OK\n"));
2870 tdIORequestBody->ioStarted = agFALSE;
2871 tdIORequestBody->ioCompleted = agTRUE;
2872 if (saStatus == AGSA_RC_BUSY)
2875 TI_DBG4(("tdsaCTLModeSelect: saSSPStart busy\n"));
2880 TI_DBG4(("tdsaCTLModeSelect: saSSPStart Error\n"));
2882 tdsaCTLNextDevice(tiRoot, oneDeviceData->tdPortContext, tdIORequest,
2883 oneDeviceData->MainLink.flink);
2886 } /* tdsaCTLModeSelect */
2891 tdsaPortContext_t *onePortContext,
2892 tdIORequest_t *tdIORequest,
2893 tdList_t *DeviceList)
2895 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
2896 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
2897 tdsaDeviceData_t *oneDeviceData;
2898 tiIntrEventType_t eventType;
2903 * From the device list, returns only valid devices
2905 for (; DeviceList && DeviceList != &(tdsaAllShared->MainDeviceList);
2906 DeviceList = DeviceList->flink)
2908 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceList);
2909 TI_DBG6(("tdsaCTLNextDevice: devHandle %p\n",
2910 &(oneDeviceData->tiDeviceHandle)));
2911 if (oneDeviceData->tdPortContext != onePortContext)
2913 if ((oneDeviceData->discovered == agFALSE) &&
2914 (oneDeviceData->registered == agTRUE) &&
2915 DEVICE_IS_SSP_TARGET(oneDeviceData) &&
2916 !DEVICE_IS_SSP_INITIATOR(oneDeviceData))
2918 oneDeviceData->discovered = agTRUE;
2919 rc = tdsaCTLModeSelect(tiRoot, &oneDeviceData->tiDeviceHandle,
2921 TI_DBG1(("tdsaCTLNextDevice: ModeSelect ret %d\n", rc));
2925 TI_DBG2(("tdsaCTLNextDevice: no more devices found\n"));
2927 eventType = tdIORequest->eventType;
2928 eventStatus = tdIORequest->eventStatus;
2930 /* no more devices, free the memory */
2931 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle2, DR_MODE_PG_SZ);
2932 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest));
2934 /* send Discovery Done event */
2935 ostiInitiatorEvent(tiRoot, onePortContext->tiPortalContext, agNULL,
2936 eventType, eventStatus, agNULL);
2937 } /* tdsaCTLNextDevice */
2942 tdsaPortContext_t *onePortContext,
2943 tiIntrEventType_t eventType,
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;
2956 TI_DBG2(("tdsaCTLSet: tiPortalContext pid %d etyp %x stat %x\n",
2957 onePortContext->id, eventType, eventStatus));
2959 if (onePortContext->DiscoveryState != ITD_DSTATE_COMPLETED)
2961 TI_DBG1(("tdsaCTLSet: discovery not completed\n"));
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)
2971 TI_DBG1(("tdsaCTLSet: ostiAllocMemory failed\n"));
2974 osti_memset(tdIORequest, 0, sizeof(*tdIORequest));
2976 tdIORequest->osMemHandle = osMemHandle;
2977 tdIORequest->eventType = eventType;
2978 tdIORequest->eventStatus = eventStatus;
2980 tiIORequest = &tdIORequest->tiIORequest;
2981 tdIORequestBody = &tdIORequest->tdIORequestBody;
2982 /* save context if we need to abort later */
2983 tiIORequest->tdData = tdIORequestBody;
2985 tdIORequestBody->IOCompletionFunc = NULL;//itdssIOCompleted;
2986 tdIORequestBody->tiIORequest = tiIORequest;
2987 tdIORequestBody->IOType.InitiatorRegIO.expDataLength = 16;
2989 tdIORequestBody->agIORequest.osData = (void *)tdIORequest; //tdIORequestBody;
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)
2998 TI_DBG1(("tdsaCTLSet: ostiAllocMemory noncached failed\n"));
2999 ostiFreeMemory(tiRoot, tdIORequest->osMemHandle, sizeof(*tdIORequest));
3003 osti_memset(tdIORequest->virtAddr, 0, DR_MODE_PG_SZ);
3004 tdsaCTLNextDevice(tiRoot, onePortContext, tdIORequest,
3005 tdsaAllShared->MainDeviceList.flink);
3009 /*****************************************************************************
3010 *! \brief tdsaSASDiscoverDone
3012 * Purpose: This function called to finish up SAS discovery.
3014 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
3016 * \param onePortContext: Pointer to the portal context instance.
3023 *****************************************************************************/
3025 tdsaSASDiscoverDone(
3027 tdsaPortContext_t *onePortContext,
3032 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
3033 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
3036 TI_DBG3(("tdsaSASDiscoverDone: start\n"));
3037 TI_DBG3(("tdsaSASDiscoverDone: pPort=%p DONE\n", onePortContext));
3038 TI_DBG3(("tdsaSASDiscoverDone: pid %d\n", onePortContext->id));
3040 /* Set discovery status */
3041 onePortContext->discovery.status = DISCOVERY_SAS_DONE;
3043 #ifdef TD_INTERNAL_DEBUG /* debugging only */
3044 TI_DBG3(("tdsaSASDiscoverDone: BEFORE\n"));
3045 tdsaDumpAllExp(tiRoot, onePortContext, agNULL);
3046 tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL);
3049 /* clean up expanders data strucures; move to free exp when device is cleaned */
3050 tdsaCleanAllExp(tiRoot, onePortContext);
3052 #ifdef TD_INTERNAL_DEBUG /* debugging only */
3053 TI_DBG3(("tdsaSASDiscoverDone: AFTER\n"));
3054 tdsaDumpAllExp(tiRoot, onePortContext, agNULL);
3055 tdsaDumpAllUpExp(tiRoot, onePortContext, agNULL);
3059 /* call back to notify discovery is done */
3060 /* SATA is NOT enbled */
3062 if (onePortContext->discovery.SeenBC == agTRUE)
3064 TI_DBG3(("tdsaSASDiscoverDone: broadcast change; discover again\n"));
3065 tdssInternalRemovals(onePortContext->agRoot,
3069 /* processed broadcast change */
3070 onePortContext->discovery.SeenBC = agFALSE;
3071 if (tdsaAllShared->ResetInDiscovery != 0 &&
3072 onePortContext->discovery.ResetTriggerred == agTRUE)
3074 TI_DBG2(("tdsaSASDiscoverDone: tdsaBCTimer\n"));
3075 tdsaBCTimer(tiRoot, onePortContext);
3082 TDSA_DISCOVERY_TYPE_SAS,
3083 TDSA_DISCOVERY_OPTION_INCREMENTAL_START
3089 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
3091 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
3093 if (flag == tiSuccess)
3096 if (tdsaAllShared->SASConnectTimeLimit)
3097 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery,
3103 onePortContext->tiPortalContext,
3105 tiIntrEventTypeDiscovery,
3112 TI_DBG1(("tdsaSASDiscoverDone: discovery failed\n"));
3113 tdssDiscoveryErrorRemovals(onePortContext->agRoot,
3119 onePortContext->tiPortalContext,
3121 tiIntrEventTypeDiscovery,
3129 if (flag == tiSuccess)
3131 tdssReportChanges(onePortContext->agRoot,
3137 tdssReportRemovals(onePortContext->agRoot,
3146 tdsaAckBC(tiRoot, onePortContext);
3153 if (flag == tiSuccess)
3155 TI_DBG3(("tdsaSASDiscoverDone: calling SATA discovery\n"));
3157 tdsaSATAFullDiscover() or tdsaincrementalDiscover()
3159 when sata discover is done, call ostiInitiatorEvent
3161 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
3163 TI_DBG3(("tdsaSASDiscoverDone: calling FULL SATA discovery\n"));
3167 AG_SA_DISCOVERY_TYPE_SATA,
3168 TDSA_DISCOVERY_OPTION_FULL_START
3173 TI_DBG3(("tdsaSASDiscoverDone: calling INCREMENTAL SATA discovery\n"));
3177 AG_SA_DISCOVERY_TYPE_SATA,
3178 TDSA_DISCOVERY_OPTION_INCREMENTAL_START
3185 TI_DBG1(("tdsaSASDiscoverDone: Error; clean up\n"));
3186 tdssDiscoveryErrorRemovals(onePortContext->agRoot,
3190 onePortContext->discovery.SeenBC = agFALSE;
3191 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
3194 onePortContext->tiPortalContext,
3196 tiIntrEventTypeDiscovery,
3205 //temp only for testing
3207 tdsaReportManInfoSend(
3209 tdsaDeviceData_t *oneDeviceData
3214 agRoot = oneDeviceData->agRoot;
3216 TI_DBG2(("tdsaReportManInfoSend: start\n"));
3222 SMP_REPORT_MANUFACTURE_INFORMATION,
3235 tdsaReportManInfoRespRcvd(
3238 tdsaDeviceData_t *oneDeviceData,
3239 tdssSMPFrameHeader_t *frameHeader,
3240 agsaFrameHandle_t frameHandle
3243 tdsaPortContext_t *onePortContext;
3244 tdsaDiscovery_t *discovery;
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));
3250 onePortContext = oneDeviceData->tdPortContext;
3251 discovery = &(onePortContext->discovery);
3253 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
3255 TI_DBG2(("tdsaReportManInfoRespRcvd: SMP accepted\n"));
3259 TI_DBG1(("tdsaReportManInfoRespRcvd: SMP NOT accepted; fn result 0x%x\n", frameHeader->smpFunctionResult));
3262 TI_DBG2(("tdsaReportManInfoRespRcvd: discovery retries %d\n", discovery->retries));
3263 discovery->retries++;
3265 if (discovery->retries >= DISCOVERY_RETRIES)
3267 TI_DBG1(("tdsaReportManInfoRespRcvd: retries are over\n"));
3268 discovery->retries = 0;
3269 /* failed the discovery */
3273 TI_DBG1(("tdsaReportManInfoRespRcvd: keep retrying\n"));
3275 tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData);
3281 //end temp only for testing
3283 /*****************************************************************************
3284 *! \brief tdsaReportGeneralSend
3286 * Purpose: This function sends Report General SMP to a device.
3288 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
3290 * \param oneDeviceData: Pointer to the device data.
3297 *****************************************************************************/
3299 tdsaReportGeneralSend(
3301 tdsaDeviceData_t *oneDeviceData
3306 agRoot = oneDeviceData->agRoot;
3308 TI_DBG3(("tdsaReportGeneralSend: start\n"));
3325 /*****************************************************************************
3326 *! \brief tdsaReportGeneralRespRcvd
3328 * Purpose: This function processes Report General response.
3330 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
3342 *****************************************************************************/
3344 tdsaReportGeneralRespRcvd(
3347 agsaIORequest_t *agIORequest,
3348 tdsaDeviceData_t *oneDeviceData,
3349 tdssSMPFrameHeader_t *frameHeader,
3350 agsaFrameHandle_t frameHandle
3353 smpRespReportGeneral_t tdSMPReportGeneralResp;
3354 smpRespReportGeneral_t *ptdSMPReportGeneralResp;
3355 tdsaExpander_t *oneExpander;
3356 tdsaPortContext_t *onePortContext;
3357 tdsaDiscovery_t *discovery;
3362 tdssSMPRequestBody_t *tdSMPRequestBody;
3363 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
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));
3372 saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
3374 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
3377 //tdhexdump("tdsaReportGeneralRespRcvd", (bit8 *)ptdSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
3381 tdSMPRequestBody->IndirectSMPReqosMemHandle,
3382 tdSMPRequestBody->IndirectSMPReqLen
3386 tdSMPRequestBody->IndirectSMPResposMemHandle,
3387 tdSMPRequestBody->IndirectSMPRespLen
3391 onePortContext = oneDeviceData->tdPortContext;
3392 discovery = &(onePortContext->discovery);
3394 if (onePortContext->valid == agFALSE)
3396 TI_DBG1(("tdsaReportGeneralRespRcvd: aborting discovery\n"));
3397 tdsaSASDiscoverAbort(tiRoot, onePortContext);
3400 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
3402 oneDeviceData->numOfPhys = (bit8) ptdSMPReportGeneralResp->numOfPhys;
3403 oneExpander = oneDeviceData->tdExpander;
3404 oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(ptdSMPReportGeneralResp);
3406 for ( i = 0; i < oneDeviceData->numOfPhys; i++ )
3408 oneExpander->currentIndex[i] = 0;
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)
3420 discovery->retries++;
3421 if (discovery->retries >= DISCOVERY_RETRIES)
3423 TI_DBG1(("tdsaReportGeneralRespRcvd: retries are over\n"));
3424 discovery->retries = 0;
3425 /* failed the discovery */
3426 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
3430 TI_DBG1(("tdsaReportGeneralRespRcvd: keep retrying\n"));
3431 // start timer for sending ReportGeneral
3432 tdsaDiscoveryTimer(tiRoot, onePortContext, oneDeviceData);
3437 discovery->retries = 0;
3438 tdsaDiscoverSend(tiRoot, oneDeviceData);
3443 TI_DBG1(("tdsaReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery\n", frameHeader->smpFunctionResult));
3444 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
3450 /*****************************************************************************
3451 *! \brief tdsaDiscoverSend
3453 * Purpose: This function sends Discovery SMP to a device.
3455 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
3457 * \param oneDeviceData: Pointer to the device data.
3464 *****************************************************************************/
3468 tdsaDeviceData_t *oneDeviceData
3472 tdsaExpander_t *oneExpander;
3473 smpReqDiscover_t smpDiscoverReq;
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));
3482 osti_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t));
3484 smpDiscoverReq.reserved1 = 0;
3485 smpDiscoverReq.reserved2 = 0;
3486 smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId;
3487 smpDiscoverReq.reserved3 = 0;
3495 (bit8 *)&smpDiscoverReq,
3496 sizeof(smpReqDiscover_t),
3505 /*****************************************************************************
3506 *! \brief tdsaDiscoverRespRcvd
3508 * Purpose: This function processes Discovery response.
3510 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
3522 *****************************************************************************/
3524 tdsaDiscoverRespRcvd(
3527 agsaIORequest_t *agIORequest,
3528 tdsaDeviceData_t *oneDeviceData,
3529 tdssSMPFrameHeader_t *frameHeader,
3530 agsaFrameHandle_t frameHandle
3533 smpRespDiscover_t *ptdSMPDiscoverResp;
3534 tdsaPortContext_t *onePortContext;
3535 tdsaExpander_t *oneExpander;
3536 tdsaDiscovery_t *discovery;
3538 tdssSMPRequestBody_t *tdSMPRequestBody;
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));
3546 onePortContext = oneDeviceData->tdPortContext;
3547 oneExpander = oneDeviceData->tdExpander;
3548 discovery = &(onePortContext->discovery);
3550 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
3553 if (onePortContext->valid == agFALSE)
3555 TI_DBG1(("tdsaDiscoverRespRcvd: aborting discovery\n"));
3556 tdsaSASDiscoverAbort(tiRoot, onePortContext);
3559 ptdSMPDiscoverResp = &(discovery->SMPDiscoverResp);
3561 saFrameReadBlock(agRoot, frameHandle, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
3563 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
3565 //tdhexdump("tdsaDiscoverRespRcvd", (bit8 *)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
3570 tdSMPRequestBody->IndirectSMPReqosMemHandle,
3571 tdSMPRequestBody->IndirectSMPReqLen
3575 tdSMPRequestBody->IndirectSMPResposMemHandle,
3576 tdSMPRequestBody->IndirectSMPRespLen
3580 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
3582 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
3584 tdsaSASUpStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
3586 else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
3588 tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
3590 else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
3592 /* not done with configuring routing
3594 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
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));
3600 tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
3607 else if (frameHeader->smpFunctionResult == PHY_VACANT)
3609 TI_DBG3(("tdsaDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n",
3610 oneExpander->discoveringPhyId));
3611 if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
3613 tdsaSASUpStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander);
3615 else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
3617 tdsaSASDownStreamDiscoverExpanderPhySkip(tiRoot, onePortContext, oneExpander);
3619 else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
3621 /* not done with configuring routing
3623 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
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));
3629 tdsaConfigureRouteTimer(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
3634 TI_DBG1(("tdsaDiscoverRespRcvd: Discovery Error SMP function return result error=%x\n",
3635 frameHeader->smpFunctionResult));
3636 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
3641 /*****************************************************************************
3642 *! \brief tdsaSASUpStreamDiscoverExpanderPhy
3644 * Purpose: This function actully does upstream traverse and finds out detailed
3645 * information about topology.
3647 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
3658 *****************************************************************************/
3660 tdsaSASUpStreamDiscoverExpanderPhy(
3662 tdsaPortContext_t *onePortContext,
3663 tdsaExpander_t *oneExpander,
3664 smpRespDiscover_t *pDiscoverResp
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;
3675 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: start\n"));
3676 if (onePortContext->valid == agFALSE)
3678 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: aborting discovery\n"));
3679 tdsaSASDiscoverAbort(tiRoot, onePortContext);
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")))));
3693 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
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));
3708 /* end for debugging */
3711 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier)
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);
3720 /* saving routing attribute for non self-configuring expanders */
3721 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp);
3724 // dumpRoutingAttributes(tiRoot, oneExpander, pDiscoverResp->phyIdentifier);
3726 if ( oneDeviceData->SASSpecDeviceType == SAS_FANOUT_EXPANDER_DEVICE )
3728 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_FANOUT_EXPANDER\n"));
3729 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
3731 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy: **** Topology Error subtractive routing on fanout expander device\n"));
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;
3740 /* (2.1.3) discovery done */
3741 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
3747 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: SA_SAS_DEV_TYPE_EDGE_EXPANDER\n"));
3749 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
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;
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;
3765 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp);
3766 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp);
3768 /* If the phy has subtractive routing attribute */
3769 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
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)
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)
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);
3798 /* Setup SAS address for up stream device */
3799 oneExpander->hasUpStreamDevice = agTRUE;
3800 oneExpander->upStreamSASAddressHi = attachedSasHi;
3801 oneExpander->upStreamSASAddressLo = attachedSasLo;
3803 if ( (onePortContext->sasLocalAddressHi != attachedSasHi)
3804 || (onePortContext->sasLocalAddressLo != attachedSasLo) )
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)
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)
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)) )
3823 /* Setup upstream expander for the pExpander */
3824 oneExpander->tdUpStreamExpander = AttachedExpander;
3826 /* If the two expanders are not the root of the two edge expander sets */
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);
3840 /* If attached device is not an edge expander */
3843 /*TODO: should not happen, ASSERT */
3844 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy, *** Attached Device is not Edge. Confused!!\n"));
3847 /* If the device has not been discovered before */
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
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));
3860 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
3862 /* incremental discovery */
3863 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
3865 AttachedDevice = tdsaPortSASDeviceAdd(
3875 pDiscoverResp->phyIdentifier
3880 /* incremental discovery */
3881 AttachedDevice = tdsaFindRegNValid(
3882 onePortContext->agRoot,
3886 /* not registered and not valid; add this*/
3887 if (AttachedDevice == agNULL)
3889 AttachedDevice = tdsaPortSASDeviceAdd(
3899 pDiscoverResp->phyIdentifier
3906 /* incremental discovery */
3907 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
3909 AttachedDevice = tdsaPortSASDeviceAdd(
3919 pDiscoverResp->phyIdentifier
3924 /* incremental discovery */
3925 AttachedDevice = tdsaFindRegNValid(
3926 onePortContext->agRoot,
3930 /* not registered and not valid; add this*/
3931 if (AttachedDevice == agNULL)
3933 AttachedDevice = tdsaPortSASDeviceAdd(
3943 pDiscoverResp->phyIdentifier
3948 /* If the device is added successfully */
3949 if ( AttachedDevice != agNULL)
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) )
3958 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found SSP/SMP SAS %08x-%08x\n",
3959 attachedSasHi, attachedSasLo));
3963 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found a SAS STP device.\n"));
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) )
3969 /* Allocate an expander data structure */
3970 AttachedExpander = tdssSASDiscoveringExpanderAlloc(
3976 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: Found expander=%p\n", AttachedExpander));
3977 /* If allocate successfully */
3978 if ( AttachedExpander != agNULL)
3980 /* Add the pAttachedExpander to discovering list */
3981 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander);
3982 /* Setup upstream expander for the pExpander */
3983 oneExpander->tdUpStreamExpander = AttachedExpander;
3985 /* If failed to allocate */
3988 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n"));
3989 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
3992 /* If the attached device is an end device */
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;
4003 TI_DBG1(("tdsaSASUpStreamDiscoverExpanderPhy, Failed to add a device\n"));
4004 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
4009 } /* substractive routing */
4014 oneExpander->discoveringPhyId ++;
4015 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM)
4017 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
4019 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM find more ...\n"));
4020 /* continue discovery for the next phy */
4021 tdsaDiscoverSend(tiRoot, oneDeviceData);
4025 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: DISCOVERY_UP_STREAM last phy continue upstream..\n"));
4027 /* remove the expander from the discovering list */
4028 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
4029 /* continue upstream discovering */
4030 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
4035 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status));
4039 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
4044 // for debugging only
4045 osGLOBAL tdsaExpander_t *
4046 tdsaFindUpStreamConfigurableExp(tiRoot_t *tiRoot,
4047 tdsaExpander_t *oneExpander)
4049 tdsaExpander_t *ret=agNULL;
4050 tdsaExpander_t *UpsreamExpander = oneExpander->tdUpStreamExpander;
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));
4057 if (UpsreamExpander)
4059 TI_DBG3(("tdsaFindUpStreamConfigurableExp: NO upsream expander\n"));
4063 while (UpsreamExpander)
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));
4068 UpsreamExpander = UpsreamExpander->tdUpStreamExpander;
4074 /*****************************************************************************
4075 *! \brief tdsaSASUpStreamDiscoverExpanderPhySkip
4077 * Purpose: This function skips a phy which returned PHY_VACANT in SMP
4078 * response in upstream
4080 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
4082 * \param onePortContext: Pointer to the portal context instance.
4083 * \param oneExpander: Pointer to the expander data.
4090 *****************************************************************************/
4092 tdsaSASUpStreamDiscoverExpanderPhySkip(
4094 tdsaPortContext_t *onePortContext,
4095 tdsaExpander_t *oneExpander
4098 tdsaDeviceData_t *oneDeviceData;
4099 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: start\n"));
4100 oneDeviceData = oneExpander->tdDevice;
4102 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
4103 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
4105 oneExpander->discoveringPhyId ++;
4106 if (onePortContext->discovery.status == DISCOVERY_UP_STREAM)
4108 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
4110 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: More Phys to discover\n"));
4111 /* continue discovery for the next phy */
4112 tdsaDiscoverSend(tiRoot, oneDeviceData);
4116 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: No More Phys\n"));
4118 /* remove the expander from the discovering list */
4119 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
4120 /* continue upstream discovering */
4121 tdsaSASUpStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
4126 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_UP_STREAM; status %d\n", onePortContext->discovery.status));
4130 TI_DBG3(("tdsaSASUpStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
4137 // for debugging only
4138 osGLOBAL tdsaExpander_t *
4139 tdsaFindDownStreamConfigurableExp(tiRoot_t *tiRoot,
4140 tdsaExpander_t *oneExpander)
4142 tdsaExpander_t *ret=agNULL;
4143 tdsaExpander_t *DownsreamExpander = oneExpander->tdCurrentDownStreamExpander;
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));
4150 if (DownsreamExpander)
4152 TI_DBG3(("tdsaFindDownStreamConfigurableExp: NO downsream expander\n"));
4156 while (DownsreamExpander)
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));
4161 DownsreamExpander = DownsreamExpander->tdCurrentDownStreamExpander;
4167 // for debugging only
4169 dumpRoutingAttributes(
4171 tdsaExpander_t *oneExpander,
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));
4182 for(i=0;i <= ((bit32)phyID + 1); i++)
4184 TI_DBG3(("dumpRoutingAttributes: index %d routing attribute %d\n", i, oneExpander->routingAttribute[i]));
4189 /*****************************************************************************
4190 *! \brief tdsaDumpAllExp
4192 * Purpose: This function prints out all expanders seen by discovery.
4194 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
4196 * \param onePortContext: Pointer to the portal context instance.
4197 * \param oneExpander: Pointer to the expander data.
4202 * \note: For debugging only
4204 *****************************************************************************/
4208 tdsaPortContext_t *onePortContext,
4209 tdsaExpander_t *oneExpander
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;
4219 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: start\n"));
4220 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: onePortcontext %p oneExpander %p\n", onePortContext, oneExpander));
4223 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
4224 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
4226 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
4227 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: empty discoveringExpanderList\n"));
4232 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
4234 ExpanderList = tmpOnePortContext->discovery.discoveringExpanderList.flink;
4235 while (ExpanderList != &(tmpOnePortContext->discovery.discoveringExpanderList))
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)
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));
4250 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Upstream expander\n"));
4252 if (DownsreamExpander)
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));
4259 TI_DBG3(("tdssSASDiscoveringExpander tdsaDumpAllExp: No Downstream expander\n"));
4262 ExpanderList = ExpanderList->flink;
4269 /*****************************************************************************
4270 *! \brief tdsaDumpAllUpExp
4272 * Purpose: This function prints out all upstream expanders seen by discovery.
4274 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
4276 * \param onePortContext: Pointer to the portal context instance.
4277 * \param oneExpander: Pointer to the expander data.
4282 * \note: For debugging only
4284 *****************************************************************************/
4288 tdsaPortContext_t *onePortContext,
4289 tdsaExpander_t *oneExpander
4296 /*****************************************************************************
4297 *! \brief tdsaDumpAllFreeExp
4299 * Purpose: This function prints out all free expanders.
4301 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
4306 * \note: For debugging only
4308 *****************************************************************************/
4318 /*****************************************************************************
4319 *! \brief tdsaDuplicateConfigSASAddr
4321 * Purpose: This function finds whether SAS address has added to the routing
4322 * table of expander or not.
4324 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
4331 * agTRUE No need to add configSASAddress.
4332 * agFALSE Need to add configSASAddress.
4336 *****************************************************************************/
4338 tdsaDuplicateConfigSASAddr(
4340 tdsaExpander_t *oneExpander,
4341 bit32 configSASAddressHi,
4342 bit32 configSASAddressLo
4346 bit32 ret = agFALSE;
4347 TI_DBG3(("tdsaDuplicateConfigSASAddr: start\n"));
4349 if (oneExpander == agNULL)
4351 TI_DBG3(("tdsaDuplicateConfigSASAddr: NULL expander\n"));
4355 if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
4356 oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo
4359 TI_DBG3(("tdsaDuplicateConfigSASAddr: unnecessary\n"));
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++)
4370 if (oneExpander->configSASAddressHiTable[i] == configSASAddressHi &&
4371 oneExpander->configSASAddressLoTable[i] == configSASAddressLo
4374 TI_DBG3(("tdsaDuplicateConfigSASAddr: FOUND!!!\n"));
4379 /* new one; let's add it */
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++;
4391 /*****************************************************************************
4392 *! \brief tdsaFindConfigurableExp
4394 * Purpose: This function finds whether there is a configurable expander in
4395 * the upstream expander list.
4397 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
4399 * \param onePortContext: Pointer to the portal context instance.
4400 * \param oneExpander: Pointer to the expander data.
4403 * agTRUE There is configurable expander.
4404 * agFALSE There is not configurable expander.
4408 *****************************************************************************/
4409 osGLOBAL tdsaExpander_t *
4410 tdsaFindConfigurableExp(
4412 tdsaPortContext_t *onePortContext,
4413 tdsaExpander_t *oneExpander
4416 tdsaExpander_t *tempExpander;
4417 tdsaPortContext_t *tmpOnePortContext = onePortContext;
4418 tdsaExpander_t *ret = agNULL;
4420 TI_DBG3(("tdsaFindConfigurableExp: start\n"));
4422 if (oneExpander == agNULL)
4424 TI_DBG3(("tdsaFindConfigurableExp: NULL expander\n"));
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));
4431 tdsaSingleThreadedEnter(tiRoot, TD_DISC_LOCK);
4432 if (TDLIST_EMPTY(&(tmpOnePortContext->discovery.discoveringExpanderList)))
4434 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
4435 TI_DBG3(("tdsaFindConfigurableExp: empty UpdiscoveringExpanderList\n"));
4440 tdsaSingleThreadedLeave(tiRoot, TD_DISC_LOCK);
4442 tempExpander = oneExpander->tdUpStreamExpander;
4443 while (tempExpander)
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)
4449 TI_DBG3(("tdsaFindConfigurableExp: found configurable expander\n"));
4453 tempExpander = tempExpander->tdUpStreamExpander;
4459 /*****************************************************************************
4460 *! \brief tdsaSASDownStreamDiscoverExpanderPhy
4462 * Purpose: This function actully does downstream traverse and finds out detailed
4463 * information about topology.
4465 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
4476 *****************************************************************************/
4478 tdsaSASDownStreamDiscoverExpanderPhy(
4480 tdsaPortContext_t *onePortContext,
4481 tdsaExpander_t *oneExpander,
4482 smpRespDiscover_t *pDiscoverResp
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;
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));
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");
4507 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContxt=%p oneExpander=%p oneDeviceData=%p\n", onePortContext, oneExpander, oneExpander->tdDevice));
4509 if (onePortContext->valid == agFALSE)
4511 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy: aborting discovery\n"));
4512 tdsaSASDiscoverAbort(tiRoot, onePortContext);
4515 #ifdef TD_INTERNAL_DEBUG
4516 tdsaDumpAllExp(tiRoot, onePortContext, oneExpander);
4517 tdsaFindUpStreamConfigurableExp(tiRoot, oneExpander);
4518 tdsaFindDownStreamConfigurableExp(tiRoot, oneExpander);
4520 /* (1) Find the device structure of the expander */
4521 oneDeviceData = oneExpander->tdDevice;
4522 TD_ASSERT(oneDeviceData, "(tdsaSASDownStreamDiscoverExpanderPhy) pDevice NULL");
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")))));
4534 if (oneExpander->discoveringPhyId != pDiscoverResp->phyIdentifier)
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);
4543 #ifdef TD_INTERNAL_DEBUG /* debugging only */
4544 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_NO_DEVICE)
4546 tdhexdump("NO_DEVICE", (bit8*)pDiscoverResp, sizeof(smpRespDiscover_t));
4549 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
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));
4565 /* end for debugging */
4567 /* saving routing attribute for non self-configuring expanders */
4568 oneExpander->routingAttribute[pDiscoverResp->phyIdentifier] = DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp);
4571 // dumpRoutingAttributes(tiRoot, oneExpander, pDiscoverResp->phyIdentifier);
4573 oneExpander->discoverSMPAllowed = agTRUE;
4575 /* If a device is attached */
4576 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) != SAS_NO_DEVICE)
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;
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;
4592 attachedSasHi = DISCRSP_GET_ATTACHED_SAS_ADDRESSHI(pDiscoverResp);
4593 attachedSasLo = DISCRSP_GET_ATTACHED_SAS_ADDRESSLO(pDiscoverResp);
4595 /* If it's a direct routing */
4596 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_DIRECT)
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) )
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;
4610 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
4616 /* If the expander's attached device is not myself */
4617 if ( (attachedSasHi != onePortContext->sasLocalAddressHi)
4618 || (attachedSasLo != onePortContext->sasLocalAddressLo) )
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
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)
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);
4643 /* Add the device */
4644 /* read minimum rate from the configuration
4645 onePortContext->LinkRate is SPC's local link rate
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));
4652 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
4654 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
4656 AttachedDevice = tdsaPortSASDeviceAdd(
4666 pDiscoverResp->phyIdentifier
4671 /* incremental discovery */
4672 AttachedDevice = tdsaFindRegNValid(
4673 onePortContext->agRoot,
4677 /* not registered and not valid; add this*/
4678 if (AttachedDevice == agNULL)
4680 AttachedDevice = tdsaPortSASDeviceAdd(
4690 pDiscoverResp->phyIdentifier
4697 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
4699 AttachedDevice = tdsaPortSASDeviceAdd(
4709 pDiscoverResp->phyIdentifier
4714 /* incremental discovery */
4715 AttachedDevice = tdsaFindRegNValid(
4716 onePortContext->agRoot,
4720 /* not registered and not valid; add this*/
4721 if (AttachedDevice == agNULL)
4723 AttachedDevice = tdsaPortSASDeviceAdd(
4733 pDiscoverResp->phyIdentifier
4738 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: newDevice pDevice=%p\n", AttachedDevice));
4739 /* If the device is added successfully */
4740 if ( AttachedDevice != agNULL)
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) )
4747 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Report a new SAS device !!\n"));
4752 if ( SA_IDFRM_IS_STP_TARGET(&sasIdentify) ||
4753 SA_IDFRM_IS_SATA_DEVICE(&sasIdentify) )
4756 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found an STP or SATA device.\n"));
4760 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Other type of device.\n"));
4764 /* LP2006-05-26 added upstream device to the newly found device */
4765 AttachedDevice->tdExpander = oneExpander;
4767 /* If the phy has table routing attribute */
4768 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE)
4770 /* If the attached device is a fan out expander */
4771 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
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);
4783 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE)
4785 /* Allocate an expander data structure */
4786 AttachedExpander = tdssSASDiscoveringExpanderAlloc(tiRoot, onePortContext, AttachedDevice);
4788 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found a EDGE exp device.%p\n", AttachedExpander));
4789 /* If allocate successfully */
4790 if ( AttachedExpander != agNULL)
4792 /* set up downstream information on configurable expander */
4793 if (oneExpander->configRouteTable)
4795 tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId);
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);
4808 /* If failed to allocate */
4811 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to allocate expander data structure\n"));
4812 /* discovery done */
4813 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
4817 /* If status is still DISCOVERY_DOWN_STREAM */
4818 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
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)
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))
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;
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);
4844 } /* if !ConfigurableExpander */
4845 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
4846 ConfigurableExpander,
4852 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
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],
4868 /* If fail to add the device */
4871 TI_DBG1(("tdsaSASDownStreamDiscoverExpanderPhy, Failed to add a device\n"));
4872 /* discovery done */
4873 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
4877 /* If the device has been discovered before */
4878 else /* haha discovered before */
4880 /* If the phy has subtractive routing attribute */
4881 if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_SUBTRACTIVE)
4883 /* If the expander doesn't have up stream device */
4884 if ( oneExpander->hasUpStreamDevice == agFALSE)
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);
4896 /* If the expander has up stream device */
4899 /* If sas address doesn't match */
4900 if ( (oneExpander->upStreamSASAddressHi != attachedSasHi)
4901 || (oneExpander->upStreamSASAddressLo != attachedSasLo) )
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);
4915 /* If the phy has table routing attribute */
4916 else if ( DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE)
4918 /* If the attached device is a fan out expander */
4919 if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_FANOUT_EXPANDER_DEVICE)
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);
4931 /* If the attached device is an edge expander */
4932 else if ( DISCRSP_GET_ATTACHED_DEVTYPE(pDiscoverResp) == SAS_EDGE_EXPANDER_DEVICE)
4934 /* Setup up stream inform */
4935 AttachedExpander = AttachedDevice->tdExpander;
4936 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found edge expander=%p\n", AttachedExpander));
4938 /* If the attached expander has up stream device */
4939 if ( AttachedExpander->hasUpStreamDevice == agTRUE)
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)))
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);
4959 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Add edge expander=%p\n", AttachedExpander));
4960 /* set up downstream information on configurable expander */
4961 if (oneExpander->configRouteTable)
4963 tdsaSASExpanderDownStreamPhyAdd(tiRoot, oneExpander, (bit8) oneExpander->discoveringPhyId);
4966 tdsaSASExpanderUpStreamPhyAdd(tiRoot, AttachedExpander, (bit8) oneExpander->discoveringPhyId);
4967 /* Add the pAttachedExpander to discovering list */
4968 tdssSASDiscoveringExpanderAdd(tiRoot, onePortContext, AttachedExpander);
4971 /* If the attached expander doesn't have up stream device */
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);
4985 } /* for else if (DISCRSP_GET_ROUTINGATTRIB(pDiscoverResp) == SAS_ROUTING_TABLE) */
4987 /* do this regradless of sub or table */
4988 /* If status is still DISCOVERY_DOWN_STREAM */
4989 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
4991 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 2nd before\n"));
4992 tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander);
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)
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))
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;
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);
5016 } /* if !ConfigurableExpander */
5017 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
5018 ConfigurableExpander,
5023 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
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],
5037 } /* if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) */
5038 /* incremental discovery */
5039 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_INCREMENTAL_START)
5041 connectionRate = (bit8)(MIN(onePortContext->LinkRate, DISCRSP_GET_LINKRATE(pDiscoverResp)));
5043 if (DISCRSP_IS_STP_TARGET(pDiscoverResp) || DISCRSP_IS_SATA_DEVICE(pDiscoverResp))
5045 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SATA_STP\n"));
5047 tdsaPortSASDeviceAdd(
5057 pDiscoverResp->phyIdentifier
5062 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: incremental SAS\n"));
5064 tdsaPortSASDeviceAdd(
5074 pDiscoverResp->phyIdentifier
5081 }/* else; existing devce */
5082 } /* not attached to myself */
5083 /* If the attached device is myself */
5086 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: Found Self\n"));
5087 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: 3rd before\n"));
5088 tdsaDumpAllUpExp(tiRoot, onePortContext, oneExpander);
5090 UpStreamExpander = oneExpander->tdUpStreamExpander;
5091 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
5092 dupConfigSASAddr = tdsaDuplicateConfigSASAddr(tiRoot,
5093 ConfigurableExpander,
5094 onePortContext->sasLocalAddressHi,
5095 onePortContext->sasLocalAddressLo
5098 if ( ConfigurableExpander && dupConfigSASAddr == agFALSE)
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
5114 /* If no device is attached */
5120 /* Increment the discovering phy id */
5121 oneExpander->discoveringPhyId ++;
5123 /* If the discovery status is DISCOVERY_DOWN_STREAM */
5124 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM )
5126 /* If not the last phy */
5127 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
5129 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: More Phys to discover\n"));
5130 /* continue discovery for the next phy */
5131 tdsaDiscoverSend(tiRoot, oneDeviceData);
5133 /* If the last phy */
5136 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: No More Phys\n"));
5138 /* remove the expander from the discovering list */
5139 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
5140 /* continue downstream discovering */
5141 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
5146 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status));
5148 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhy: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
5153 /*****************************************************************************
5154 *! \brief tdsaSASDownStreamDiscoverExpanderPhySkip
5156 * Purpose: This function skips a phy which returned PHY_VACANT in SMP
5157 * response in downstream
5159 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
5161 * \param onePortContext: Pointer to the portal context instance.
5162 * \param oneExpander: Pointer to the expander data.
5169 *****************************************************************************/
5171 tdsaSASDownStreamDiscoverExpanderPhySkip(
5173 tdsaPortContext_t *onePortContext,
5174 tdsaExpander_t *oneExpander
5177 tdsaDeviceData_t *oneDeviceData;
5178 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: start\n"));
5179 oneDeviceData = oneExpander->tdDevice;
5181 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
5182 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
5184 /* Increment the discovering phy id */
5185 oneExpander->discoveringPhyId ++;
5187 /* If the discovery status is DISCOVERY_DOWN_STREAM */
5188 if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM )
5190 /* If not the last phy */
5191 if ( oneExpander->discoveringPhyId < oneDeviceData->numOfPhys )
5193 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: More Phys to discover\n"));
5194 /* continue discovery for the next phy */
5195 tdsaDiscoverSend(tiRoot, oneDeviceData);
5197 /* If the last phy */
5200 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: No More Phys\n"));
5202 /* remove the expander from the discovering list */
5203 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, oneExpander);
5204 /* continue downstream discovering */
5205 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, oneDeviceData);
5210 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: onePortContext->discovery.status not in DISCOVERY_DOWN_STREAM; status %d\n", onePortContext->discovery.status));
5212 TI_DBG3(("tdsaSASDownStreamDiscoverExpanderPhySkip: end return phyID#%d\n", oneExpander->discoveringPhyId - 1));
5217 /*****************************************************************************
5218 *! \brief tdsaSASRoutingEntryAdd
5220 * Purpose: This function adds a routing entry in the configurable expander.
5222 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
5230 * agTRUE Routing entry is added successfully
5231 * agFALSE Routing entry is not added successfully
5235 *****************************************************************************/
5237 tdsaSASRoutingEntryAdd(
5239 tdsaExpander_t *oneExpander,
5241 bit32 configSASAddressHi,
5242 bit32 configSASAddressLo
5246 smpReqConfigureRouteInformation_t confRoutingInfo;
5247 tdsaPortContext_t *onePortContext;
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));
5256 /* needs to compare the location of oneExpander and configSASAddress
5263 if (oneExpander->tdDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
5264 oneExpander->tdDevice->SASAddressID.sasAddressLo == configSASAddressLo
5267 TI_DBG3(("tdsaSASRoutingEntryAdd: unnecessary\n"));
5270 if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE)
5272 TI_DBG3(("tdsaSASRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId]));
5276 agRoot = oneExpander->tdDevice->agRoot;
5277 onePortContext = oneExpander->tdDevice->tdPortContext;
5279 onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING;
5281 /* reset smpReqConfigureRouteInformation_t */
5282 osti_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t));
5283 if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex )
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]));
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 ++ )
5306 confRoutingInfo.reserved6[i] = 0;
5308 tdSMPStart(tiRoot, agRoot, oneExpander->tdDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ, agNULL, 0);
5310 oneExpander->currentIndex[phyId] ++;
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);
5323 /*****************************************************************************
5324 *! \brief tdsaConfigRoutingInfoRespRcvd
5326 * Purpose: This function processes Configure Routing Information response.
5328 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
5340 *****************************************************************************/
5341 /* needs to traverse only upstream not downstream */
5343 tdsaConfigRoutingInfoRespRcvd(
5346 agsaIORequest_t *agIORequest,
5347 tdsaDeviceData_t *oneDeviceData,
5348 tdssSMPFrameHeader_t *frameHeader,
5349 agsaFrameHandle_t frameHandle
5352 tdsaExpander_t *oneExpander = oneDeviceData->tdExpander;
5353 tdsaExpander_t *UpStreamExpander;
5354 tdsaExpander_t *DownStreamExpander;
5355 tdsaExpander_t *ReturningExpander;
5356 tdsaExpander_t *ConfigurableExpander;
5358 tdsaPortContext_t *onePortContext;
5359 tdsaDeviceData_t *ReturningExpanderDeviceData;
5360 bit32 dupConfigSASAddr = agFALSE;
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));
5366 onePortContext = oneDeviceData->tdPortContext;
5368 if (onePortContext->valid == agFALSE)
5370 TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: aborting discovery\n"));
5371 tdsaSASDiscoverAbort(tiRoot, onePortContext);
5375 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
5376 frameHeader->smpFunctionResult == PHY_VACANT
5379 DownStreamExpander = oneExpander->tdCurrentDownStreamExpander;
5380 if (DownStreamExpander != agNULL)
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));
5390 oneExpander->currentDownStreamPhyIndex++;
5391 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
5393 if ( DownStreamExpander != agNULL)
5395 if (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
5397 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: first if\n"));
5398 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
5400 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
5402 tdsaSASRoutingEntryAdd(tiRoot,
5404 DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
5405 oneExpander->configSASAddressHi,
5406 oneExpander->configSASAddressLo
5411 /* traversing up till discovery Root onePortContext->discovery.RootExp */
5412 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else\n"));
5414 UpStreamExpander = oneExpander->tdUpStreamExpander;
5415 ConfigurableExpander = tdsaFindConfigurableExp(tiRoot, onePortContext, oneExpander);
5416 if (UpStreamExpander != agNULL)
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
5426 if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
5428 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: else if\n"));
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));
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));
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
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;
5456 if (ReturningExpander != agNULL)
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));
5461 ReturningExpanderDeviceData = ReturningExpander->tdDevice;
5463 /* No longer in DISCOVERY_CONFIG_ROUTING */
5464 onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
5466 /* If not the last phy */
5467 if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
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)
5474 tdsaDiscoverSend(tiRoot, ReturningExpanderDeviceData);
5476 ReturningExpander->discoverSMPAllowed = agFALSE;
5478 /* If the last phy */
5481 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: No More Phys\n"));
5482 ReturningExpander->discoverSMPAllowed = agTRUE;
5484 /* remove the expander from the discovering list */
5485 tdssSASDiscoveringExpanderRemove(tiRoot, onePortContext, ReturningExpander);
5486 /* continue downstream discovering */
5487 tdsaSASDownStreamDiscovering(tiRoot, onePortContext, ReturningExpanderDeviceData);
5489 //DownStreamExpander
5494 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: ReturningExpander is NULL\n"));
5500 TI_DBG3(("tdsaConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n"));
5507 TI_DBG1(("tdsaConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=%x\n", frameHeader->smpFunctionResult));
5508 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
5513 /*****************************************************************************
5514 *! \brief tdsaReportPhySataSend
5516 * Purpose: This function sends Report Phy SATA to a device.
5518 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
5520 * \param oneDeviceData: Pointer to the device data.
5521 * \param phyId: Phy Identifier.
5528 *****************************************************************************/
5530 tdsaReportPhySataSend(
5532 tdsaDeviceData_t *oneDeviceData,
5537 tdsaExpander_t *oneExpander;
5538 tdsaPortContext_t *onePortContext;
5539 smpReqReportPhySata_t smpReportPhySataReq;
5541 TI_DBG3(("tdsaReportPhySataSend: start\n"));
5543 agRoot = oneDeviceData->agRoot;
5544 onePortContext = oneDeviceData->tdPortContext;
5545 oneExpander = oneDeviceData->tdExpander;
5547 if (onePortContext == agNULL)
5549 TI_DBG1(("tdsaReportPhySataSend: Error!!! portcontext is NULL\n"));
5552 if (oneExpander == agNULL)
5554 TI_DBG1(("tdsaReportPhySataSend: Error!!! expander is NULL\n"));
5557 TI_DBG3(("tdsaReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
5558 TI_DBG3(("tdsaReportPhySataSend: phyid %d\n", phyId));
5560 oneExpander->tdDeviceToProcess = oneDeviceData;
5562 osti_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t));
5564 smpReportPhySataReq.phyIdentifier = phyId;
5570 oneExpander->tdDevice,
5571 SMP_REPORT_PHY_SATA,
5572 (bit8 *)&smpReportPhySataReq,
5573 sizeof(smpReqReportPhySata_t),
5582 /*****************************************************************************
5583 *! \brief tdsaReportPhySataRcvd
5585 * Purpose: This function processes Report Phy SATA response.
5587 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
5599 *****************************************************************************/
5601 tdsaReportPhySataRcvd(
5604 agsaIORequest_t *agIORequest,
5605 tdsaDeviceData_t *oneDeviceData,
5606 tdssSMPFrameHeader_t *frameHeader,
5607 agsaFrameHandle_t frameHandle
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;
5617 tdssSMPRequestBody_t *tdSMPRequestBody;
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));
5624 tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData;
5626 /* get the current sata device hanlde stored in the expander structure */
5627 SataDevice = oneExpander->tdDeviceToProcess;
5628 pSMPReportPhySataResp = &SMPreportPhySataResp;
5630 saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
5632 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
5635 //tdhexdump("tdsaReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
5640 tdSMPRequestBody->IndirectSMPReqosMemHandle,
5641 tdSMPRequestBody->IndirectSMPReqLen
5645 tdSMPRequestBody->IndirectSMPResposMemHandle,
5646 tdSMPRequestBody->IndirectSMPRespLen
5650 onePortContext = oneDeviceData->tdPortContext;
5652 if (onePortContext->valid == agFALSE)
5654 TI_DBG1(("tdsaReportPhySataRcvd: aborting discovery\n"));
5655 tdsaSASDiscoverAbort(tiRoot, onePortContext);
5658 if (SataDevice == agNULL)
5660 TI_DBG1(("tdsaReportPhySataRcvd: SataDevice is NULL, wrong\n"));
5661 tdsaSASDiscoverAbort(tiRoot, onePortContext);
5664 if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
5665 frameHeader->smpFunctionResult == PHY_VACANT
5668 fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
5669 if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
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;
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]));
5690 no longer, discovery sends sata identify device command
5691 tdsaSATAIdentifyDeviceCmdSend(tiRoot, SataDevice);
5693 SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice);
5694 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice);
5698 TI_DBG3(("tdsaReportPhySataRcvd: getting next stp bride\n"));
5699 SataDevice = tdsaFindRightDevice(tiRoot, onePortContext, SataDevice);
5700 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, SataDevice);
5705 TI_DBG3(("tdsaReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n",
5706 frameHeader->smpFunctionResult));
5707 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
5712 /*****************************************************************************
5713 *! \brief tdsaSASExpanderUpStreamPhyAdd
5715 * Purpose: This function adds upstream expander to a specfic phy.
5717 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
5719 * \param oneExpander: Pointer to the expander data.
5720 * \param phyId: Phy Identifier.
5727 *****************************************************************************/
5729 tdsaSASExpanderUpStreamPhyAdd(
5731 tdsaExpander_t *oneExpander,
5736 bit32 hasSet = agFALSE;
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));
5743 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ )
5745 if ( oneExpander->upStreamPhys[i] == phyId )
5752 if ( hasSet == agFALSE )
5754 oneExpander->upStreamPhys[oneExpander->numOfUpStreamPhys ++] = phyId;
5757 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: AFTER phyid %d numOfUpStreamPhys %d\n", phyId, oneExpander->numOfUpStreamPhys));
5760 for ( i = 0; i < oneExpander->numOfUpStreamPhys; i ++ )
5762 TI_DBG3(("tdsaSASExpanderUpStreamPhyAdd: index %d upstream[index] %d\n", i, oneExpander->upStreamPhys[i]));
5768 just add phys in downstream in configurable expnader
5770 /*****************************************************************************
5771 *! \brief tdsaSASExpanderDownStreamPhyAdd
5773 * Purpose: This function adds downstream expander to a specfic phy.
5775 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
5777 * \param oneExpander: Pointer to the expander data.
5778 * \param phyId: Phy Identifier.
5785 *****************************************************************************/
5787 tdsaSASExpanderDownStreamPhyAdd(
5789 tdsaExpander_t *oneExpander,
5794 bit32 hasSet = agFALSE;
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));
5801 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ )
5803 if ( oneExpander->downStreamPhys[i] == phyId )
5810 if ( hasSet == agFALSE )
5812 oneExpander->downStreamPhys[oneExpander->numOfDownStreamPhys ++] = phyId;
5815 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: AFTER phyid %d numOfDownStreamPhys %d\n", phyId, oneExpander->numOfDownStreamPhys));
5818 for ( i = 0; i < oneExpander->numOfDownStreamPhys; i ++ )
5820 TI_DBG3(("tdsaSASExpanderDownStreamPhyAdd: index %d downstream[index] %d\n", i, oneExpander->downStreamPhys[i]));
5825 /* oneExpander is the configurable expander of interest
5826 phyId is the first phyID in upStreamPhys[0] of downExpander
5828 /*****************************************************************************
5829 *! \brief tdsaFindCurrentDownStreamPhyIndex
5831 * Purpose: This function finds CurrentDownStreamPhyIndex from a configurable
5834 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
5836 * \param oneExpander: Pointer to the configuralbe expander data.
5839 * CurrentDownStreamPhyIndex
5842 *****************************************************************************/
5844 tdsaFindCurrentDownStreamPhyIndex(
5846 tdsaExpander_t *oneExpander
5849 tdsaExpander_t *DownStreamExpander;
5854 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: start\n"));
5856 if (oneExpander == agNULL)
5858 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! oneExpander is NULL\n"));
5862 DownStreamExpander = oneExpander->tdCurrentDownStreamExpander;
5864 if (DownStreamExpander == agNULL)
5866 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: wrong!!! DownStreamExpander is NULL\n"));
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));
5876 phyId = DownStreamExpander->upStreamPhys[0];
5878 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: phyId %d\n", phyId));
5880 for (i=0; i<oneExpander->numOfDownStreamPhys;i++)
5882 if (oneExpander->downStreamPhys[i] == phyId)
5888 TI_DBG3(("tdsaFindCurrentDownStreamPhyIndex: index %d\n", index));
5891 /*****************************************************************************
5892 *! \brief tdsaPortSASDeviceFind
5894 * Purpose: Given SAS address, this function finds a device with that SAS address
5895 * in the device list.
5897 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
5904 * agNULL When no device found
5905 * Pointer to device When device is found
5909 *****************************************************************************/
5910 osGLOBAL tdsaDeviceData_t *
5911 tdsaPortSASDeviceFind(
5913 tdsaPortContext_t *onePortContext,
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;
5923 TI_DBG3(("tdsaPortSASDeviceFind: start\n"));
5925 TD_ASSERT((agNULL != tiRoot), "");
5926 TD_ASSERT((agNULL != onePortContext), "");
5928 tdsaSingleThreadedEnter(tiRoot, TD_DEVICE_LOCK);
5930 /* find a device's existence */
5931 DeviceListList = tdsaAllShared->MainDeviceList.flink;
5932 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
5934 TI_DBG3(("tdsaPortSASDeviceFind: Full discovery\n"));
5935 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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)
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;
5950 DeviceListList = DeviceListList->flink;
5955 /* incremental discovery */
5956 TI_DBG3(("tdsaPortSASDeviceFind: Incremental discovery\n"));
5957 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
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)
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));
5970 RetDeviceData = oneDeviceData;
5973 DeviceListList = DeviceListList->flink;
5977 tdsaSingleThreadedLeave(tiRoot, TD_DEVICE_LOCK);
5979 return RetDeviceData;
5982 /* include both sas and stp-sata targets*/
5983 /*****************************************************************************
5984 *! \brief tdsaPortSASDeviceAdd
5986 * Purpose: This function adds the SAS device to the device list.
5988 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
5999 * Pointer to device data.
6003 *****************************************************************************/
6004 GLOBAL tdsaDeviceData_t *
6005 tdsaPortSASDeviceAdd(
6007 tdsaPortContext_t *onePortContext,
6008 agsaSASIdentify_t sasIdentify,
6010 bit8 connectionRate,
6011 bit32 itNexusTimeout,
6012 bit32 firstBurstSize,
6014 tdsaDeviceData_t *oneExpDeviceData,
6018 tdsaDeviceData_t *oneDeviceData = agNULL;
6019 bit8 dev_s_rate = 0;
6022 tdsaSASSubID_t agSASSubID;
6023 tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL;
6025 TI_DBG3(("tdsaPortSASDeviceAdd: start\n"));
6026 TI_DBG3(("tdsaPortSASDeviceAdd: connectionRate %d\n", connectionRate));
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;
6033 /* old device and already registered to LL; added by link-up event */
6034 if ( agFALSE == tdssNewSASorNot(
6035 onePortContext->agRoot,
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,
6052 if (oneDeviceData == agNULL)
6054 TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n"));
6057 /* If a device is allocated */
6058 if ( oneDeviceData != agNULL )
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)));
6064 oneDeviceData->sasIdentify = sasIdentify;
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)));
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);
6075 oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify));
6077 /* adjusting connectionRate */
6078 oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
6079 if (oneAttachedExpDeviceData != agNULL)
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)));
6087 TI_DBG3(("tdsaPortSASDeviceAdd: 1st oneAttachedExpDeviceData is NULL\n"));
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);
6098 DEVINFO_PUT_SAS_ADDRESSLO(
6099 &oneDeviceData->agDeviceInfo,
6100 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)
6102 DEVINFO_PUT_SAS_ADDRESSHI(
6103 &oneDeviceData->agDeviceInfo,
6104 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)
6106 oneDeviceData->agContext.osData = oneDeviceData;
6107 oneDeviceData->agContext.sdkData = agNULL;
6110 return oneDeviceData;
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));
6117 /* allocate a new device and set the valid bit */
6118 oneDeviceData = tdssNewAddSASToSharedcontext(
6119 onePortContext->agRoot,
6126 if (oneDeviceData == agNULL)
6128 TI_DBG1(("tdsaPortSASDeviceAdd: no more device!!! oneDeviceData is null\n"));
6131 /* If a device is allocated */
6132 if ( oneDeviceData != agNULL )
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)));
6138 oneDeviceData->sasIdentify = sasIdentify;
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)));
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);
6150 oneDeviceData->SASSpecDeviceType = (bit8)(SA_IDFRM_GET_DEVICETTYPE(&sasIdentify));
6152 /* adjusting connectionRate */
6153 oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
6154 if (oneAttachedExpDeviceData != agNULL)
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)));
6162 TI_DBG3(("tdsaPortSASDeviceAdd: 2nd oneAttachedExpDeviceData is NULL\n"));
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);
6172 DEVINFO_PUT_SAS_ADDRESSLO(
6173 &oneDeviceData->agDeviceInfo,
6174 SA_IDFRM_GET_SAS_ADDRESSLO(&oneDeviceData->sasIdentify)
6176 DEVINFO_PUT_SAS_ADDRESSHI(
6177 &oneDeviceData->agDeviceInfo,
6178 SA_IDFRM_GET_SAS_ADDRESSHI(&oneDeviceData->sasIdentify)
6180 oneDeviceData->agContext.osData = oneDeviceData;
6181 oneDeviceData->agContext.sdkData = agNULL;
6183 TI_DBG3(("tdsaPortSASDeviceAdd: did %d\n", oneDeviceData->id));
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))
6189 (((sasIdentify.initiator_ssp_stp_smp & DEVICE_STP_BIT) == DEVICE_STP_BIT) &&
6190 ((sasIdentify.target_ssp_stp_smp & DEVICE_SSP_BIT) != DEVICE_SSP_BIT))
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)));
6200 if (oneDeviceData->registered == agFALSE)
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,
6215 return oneDeviceData;
6218 /*****************************************************************************
6219 *! \brief tdsaDiscoveryResetProcessed
6221 * Purpose: This function called to reset "processed flag" of device belong to
6224 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6226 * \param onePortContext: Pointer to the portal context instance.
6233 *****************************************************************************/
6236 tdsaDiscoveryResetProcessed(
6238 tdsaPortContext_t *onePortContext
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;
6246 TI_DBG6(("tdsaDiscoveryResetProcessed: start\n"));
6248 /* reinitialize the device data belonging to this portcontext */
6249 DeviceListList = tdsaAllShared->MainDeviceList.flink;
6250 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
6252 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
6253 TI_DBG6(("tdsaDiscoveryResetProcessed: loop did %d\n", oneDeviceData->id));
6254 if (oneDeviceData->tdPortContext == onePortContext)
6256 TI_DBG6(("tdsaDiscoveryResetProcessed: resetting procssed flag\n"));
6257 oneDeviceData->processed = agFALSE;
6259 DeviceListList = DeviceListList->flink;
6265 /*****************************************************************************
6266 *! \brief tdsaSATADiscoverDone
6268 * Purpose: This function called to finish up SATA discovery.
6270 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6272 * \param onePortContext: Pointer to the portal context instance.
6273 * \param flag: status of discovery (success or failure).
6280 *****************************************************************************/
6282 tdsaSATADiscoverDone(
6284 tdsaPortContext_t *onePortContext,
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);
6293 if (onePortContext->discovery.SeenBC == agTRUE)
6295 TI_DBG3(("tdsaSATADiscoverDone: broadcast change; discover again\n"));
6296 tdssInternalRemovals(onePortContext->agRoot,
6300 /* processed broadcast change */
6301 onePortContext->discovery.SeenBC = agFALSE;
6302 if (tdsaAllShared->ResetInDiscovery != 0 &&
6303 onePortContext->discovery.ResetTriggerred == agTRUE)
6305 TI_DBG1(("tdsaSATADiscoverDone: tdsaBCTimer\n"));
6306 tdsaBCTimer(tiRoot, onePortContext);
6313 TDSA_DISCOVERY_TYPE_SAS,
6314 TDSA_DISCOVERY_OPTION_INCREMENTAL_START
6320 onePortContext->DiscoveryState = ITD_DSTATE_COMPLETED;
6322 if (onePortContext->discovery.type == TDSA_DISCOVERY_OPTION_FULL_START)
6324 if (flag == tiSuccess)
6327 tdsaContext_t *tdsaAllShared =
6328 &((tdsaRoot_t*)tiRoot->tdData)->tdsaAllShared;
6330 if (tdsaAllShared->SASConnectTimeLimit)
6331 tdsaCTLSet(tiRoot, onePortContext, tiIntrEventTypeDiscovery,
6337 onePortContext->tiPortalContext,
6339 tiIntrEventTypeDiscovery,
6346 TI_DBG1(("tdsaSATADiscoverDone: Error; clean up\n"));
6347 tdssDiscoveryErrorRemovals(onePortContext->agRoot,
6353 onePortContext->tiPortalContext,
6355 tiIntrEventTypeDiscovery,
6363 if (flag == tiSuccess)
6365 tdssReportChanges(onePortContext->agRoot,
6371 tdssReportRemovals(onePortContext->agRoot,
6380 tdsaAckBC(tiRoot, onePortContext);
6388 tdsaPortContext_t *onePortContext
6391 #ifdef TBD /* not yet */
6392 agsaEventSource_t eventSource[TD_MAX_NUM_PHYS];
6393 bit32 HwAckSatus = AGSA_RC_SUCCESS;
6395 TI_DBG3(("tdsaAckBC: start\n"));
6397 for (i=0;i<TD_MAX_NUM_PHYS;i++)
6399 if (onePortContext->BCPhyID[i] == agTRUE)
6401 /* saHwEventAck() */
6402 eventSource[i].agPortContext = onePortContext->agPortContext;
6403 eventSource[i].event = OSSA_HW_EVENT_BROADCAST_CHANGE;
6405 eventSource[i].param = i;
6406 HwAckSatus = saHwEventAck(
6407 onePortContext->agRoot,
6408 agNULL, /* agContext */
6410 &eventSource[i], /* agsaEventSource_t */
6414 TI_DBG3(("tdsaAckBC: calling saHwEventAck\n"));
6416 if ( HwAckSatus != AGSA_RC_SUCCESS)
6418 TI_DBG1(("tdsaAckBC: failing in saHwEventAck; status %d\n", HwAckSatus));
6422 onePortContext->BCPhyID[i] = agFALSE;
6429 /*****************************************************************************
6430 *! \brief tdsaSATAFullDiscover
6432 * Purpose: This function is called to trigger full SATA topology discovery
6433 * within a portcontext.
6435 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6437 * \param onePortContext: Pointer to the portal context instance.
6440 * tiSuccess Discovery initiated.
6441 * tiError Discovery could not be initiated at this time.
6445 *****************************************************************************/
6447 tdsaSATAFullDiscover(
6449 tdsaPortContext_t *onePortContext
6452 bit32 ret = tiSuccess;
6453 tdsaDeviceData_t *oneDeviceData = agNULL;
6455 bit8 phyRate = SAS_CONNECTION_RATE_3_0G;
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;
6463 TI_DBG3(("tdsaSATAFullDiscover: start\n"));
6464 if (onePortContext->valid == agFALSE)
6466 TI_DBG1(("tdsaSATAFullDiscover: aborting discovery\n"));
6467 tdsaSASDiscoverAbort(tiRoot, onePortContext);
6470 phyRate = onePortContext->LinkRate;
6471 DeviceListList = tdsaAllShared->MainDeviceList.flink;
6472 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
6473 /* If port is SATA mode */
6475 Native SATA mode is decided in ossaHWCB() SAS_LINK_UP or SATA_LINK_UP
6477 if (onePortContext->nativeSATAMode == agTRUE)
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)
6484 TI_DBG3(("tdsaSATAFullDiscover: Found a PM device\n"));
6485 oneDeviceData = tdsaPortSATADeviceAdd(
6489 onePortContext->remoteSignature,
6499 /* already added in ossahwcb() in SATA link up */
6500 TI_DBG3(("tdsaSATAFullDiscover: Found a DIRECT SATA device\n"));
6503 /* Process for different device type */
6504 switch ( deviceType )
6507 case SATA_PM_DEVICE:
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 ++ )
6514 /* Read the signature */
6515 /* Decode the device type */
6516 /* Create device descriptor */
6517 /* Callback with the discovered devices */
6521 /* if it's ATA device */
6522 case SATA_ATA_DEVICE:
6523 case SATA_ATAPI_DEVICE:
6525 TI_DBG3(("tdsaSATAFullDiscover: Process an ATA device. Sending Identify Device cmd\n"));
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);
6537 TI_DBG3(("siSATAFullDiscover: Process OTHER SATA device. Just report the device\n"));
6542 /* If port is SAS mode */
6545 TI_DBG3(("tdsaSATAFullDiscover: Discovering attached STP devices starts....\n"));
6546 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
6547 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
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
6556 /*****************************************************************************
6557 *! \brief tdsaPortSATADeviceAdd
6559 * Purpose: This function adds the SATA device to the device list.
6561 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
6571 * Pointer to device data.
6575 *****************************************************************************/
6576 GLOBAL tdsaDeviceData_t *
6577 tdsaPortSATADeviceAdd(
6579 tdsaPortContext_t *onePortContext,
6580 tdsaDeviceData_t *oneSTPBridge,
6584 bit8 connectionRate,
6585 tdsaDeviceData_t *oneExpDeviceData,
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;
6596 tdsaDeviceData_t *oneAttachedExpDeviceData = agNULL;
6598 TI_DBG3(("tdsaPortSATADeviceAdd: start\n"));
6601 TD_ASSERT((agNULL != tiRoot), "");
6602 TD_ASSERT((agNULL != agRoot), "");
6603 TD_ASSERT((agNULL != onePortContext), "");
6604 TD_ASSERT((agNULL != Signature), "");
6606 oneDeviceData = tdssNewAddSATAToSharedcontext(
6618 if (oneDeviceData == agNULL)
6620 TI_DBG1(("tdsaPortSATADeviceAdd: no more device!!! oneDeviceData is null\n"));
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);
6630 /* adjusting connectionRate */
6631 oneAttachedExpDeviceData = oneDeviceData->ExpDevice;
6632 if (oneAttachedExpDeviceData != agNULL)
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)));
6640 TI_DBG3(("tdsaPortSATADeviceAdd: 1st oneAttachedExpDeviceData is NULL\n"));
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);
6649 osti_memset(&oneDeviceData->agDeviceInfo.sasAddressHi, 0, 4);
6650 osti_memset(&oneDeviceData->agDeviceInfo.sasAddressLo, 0, 4);
6652 oneDeviceData->agContext.osData = oneDeviceData;
6653 oneDeviceData->agContext.sdkData = agNULL;
6655 TI_DBG1(("tdsaPortSATADeviceAdd: did %d\n", oneDeviceData->id));
6656 if (oneDeviceData->registered == agFALSE)
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,
6669 return oneDeviceData;
6673 /*****************************************************************************
6674 *! \brief tdsaFindRightDevice
6676 * Purpose: This function returns device-to-be processed.
6678 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6680 * \param onePortContext: Pointer to the portal context instance.
6681 * \param tdsaDeviceData: Pointer to the starting device data.
6684 * Pointer to device data.
6688 *****************************************************************************/
6689 osGLOBAL tdsaDeviceData_t *
6690 tdsaFindRightDevice(
6692 tdsaPortContext_t *onePortContext,
6693 tdsaDeviceData_t *tdsaDeviceData
6696 tdList_t *DeviceListList;
6697 tdsaDeviceData_t *oneDeviceData = agNULL;
6698 bit32 found = agFALSE;
6700 TI_DBG3(("tdsaFindHeadDevice: start\n"));
6702 DeviceListList = tdsaDeviceData->MainLink.flink;
6704 while (DeviceListList != &(tdsaDeviceData->MainLink))
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;
6711 DeviceListList = tdsaDeviceData->MainLink.flink;
6713 while (DeviceListList != &(tdsaDeviceData->MainLink))
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))
6723 TI_DBG3(("tdsaFindRightDevice: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
6724 oneDeviceData->processed = agTRUE;
6728 DeviceListList = DeviceListList->flink;
6731 if (found == agTRUE)
6733 return oneDeviceData;
6743 // tdsaDeviceData is head of list
6744 /*****************************************************************************
6745 *! \brief tdsaDiscoveringStpSATADevice
6747 * Purpose: For each device in the device list, this function peforms
6750 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6752 * \param onePortContext: Pointer to the portal context instance.
6753 * \param oneDeviceData: Pointer to the heade of device list.
6760 *****************************************************************************/
6762 tdsaDiscoveringStpSATADevice(
6764 tdsaPortContext_t *onePortContext,
6765 tdsaDeviceData_t *oneDeviceData
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;
6775 TI_DBG3(("tdsaDiscoveringStpSATADevice: start\n"));
6777 DeviceListList = tdsaAllShared->MainDeviceList.flink;
6778 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
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))
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)
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)
6799 TI_DBG3(("tdsaDiscoveringStpSATADevice: sending identify device data\n"));
6801 status = tdsaDiscoveryStartIDDev(tiRoot,
6803 &(oneDeviceData->tiDeviceHandle),
6807 if (status != tiSuccess)
6809 /* identify device data is not valid */
6810 TI_DBG1(("tdsaDiscoveringStpSATADevice: fail or busy %d\n", status));
6811 oneDeviceData->satDevData.IDDeviceValid = agFALSE;
6817 TI_DBG2(("tdsaDiscoveringStpSATADevice: moving to the next\n"));
6818 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
6819 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
6824 /* otherwise, there is no more SATA device found */
6825 TI_DBG3(("tdsaDiscoveringStpSATADevice: No More Device; SATA discovery finished\n"));
6827 tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess);
6833 /*****************************************************************************
6834 *! \brief tdsaSASIncrementalDiscover
6836 * Purpose: This function is called to trigger incremental SAS topology discovery
6837 * within a portcontext.
6839 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6841 * \param onePortContext: Pointer to the portal context instance.
6844 * tiSuccess Discovery initiated.
6845 * tiError Discovery could not be initiated at this time.
6849 *****************************************************************************/
6851 tdsaSASIncrementalDiscover(
6853 tdsaPortContext_t *onePortContext
6856 tdsaDeviceData_t *oneDeviceData = agNULL;
6860 TI_DBG3(("tdsaSASIncrementalDiscover: start\n"));
6862 if (onePortContext->valid == agFALSE)
6864 TI_DBG1(("tdsaSASIncrementalDiscover: aborting discovery\n"));
6865 tdsaSASDiscoverAbort(tiRoot, onePortContext);
6869 onePortContext->DiscoveryState = ITD_DSTATE_STARTED;
6871 /* nativeSATAMode is set in ossaHwCB() in link up */
6872 if (onePortContext->nativeSATAMode == agFALSE) /* default: SAS and SAS/SATA mode */
6874 if (SA_IDFRM_GET_DEVICETTYPE(&onePortContext->sasIDframe) == SAS_END_DEVICE &&
6875 SA_IDFRM_IS_SSP_TARGET(&onePortContext->sasIDframe) )
6877 for(i=0;i<TD_MAX_NUM_PHYS;i++)
6879 if (onePortContext->PhyIDList[i] == agTRUE)
6882 for (j=0;j<TD_MAX_NUM_NOTIFY_SPINUP;j++)
6884 saLocalPhyControl(onePortContext->agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL);
6892 1. add device in TD layer
6893 2. call saRegisterNewDevice
6894 3. update agDevHandle in ossaDeviceRegistrationCB()
6896 portMaxRate = onePortContext->LinkRate;
6897 oneDeviceData = tdsaPortSASDeviceAdd(
6900 onePortContext->sasIDframe,
6911 if (oneDeviceData->registered == agFALSE)
6914 set the timer and wait till the device(directly attached. eg Expander) to be registered.
6915 Then, in tdsaDeviceRegistrationTimerCB(), tdsaSASUpStreamDiscoverStart() is called
6917 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
6921 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
6925 else /* SATAOnlyMode*/
6927 tdsaSASDiscoverDone(tiRoot, onePortContext, tiSuccess);
6933 /* For the sake of completness; this is the same as tdsaSATAFullDiscover*/
6934 /*****************************************************************************
6935 *! \brief tdsaSATAIncrementalDiscover
6937 * Purpose: This function is called to trigger incremental SATA topology discovery
6938 * within a portcontext.
6940 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
6942 * \param onePortContext: Pointer to the portal context instance.
6945 * tiSuccess Discovery initiated.
6946 * tiError Discovery could not be initiated at this time.
6950 *****************************************************************************/
6952 tdsaSATAIncrementalDiscover(
6954 tdsaPortContext_t *onePortContext
6957 bit32 ret = tiSuccess;
6958 tdsaDeviceData_t *oneDeviceData = agNULL;
6960 bit8 phyRate = SAS_CONNECTION_RATE_3_0G;
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;
6968 TI_DBG3(("tdsaSATAIncrementalDiscover: start\n"));
6970 if (onePortContext->valid == agFALSE)
6972 TI_DBG1(("tdsaSATAIncrementalDiscover: aborting discovery\n"));
6973 tdsaSASDiscoverAbort(tiRoot, onePortContext);
6977 DeviceListList = tdsaAllShared->MainDeviceList.flink;
6978 tdsaDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
6980 /* If port is SATA mode */
6982 Native SATA mode is decided in ossaHWCB() SAS_LINK_UP or SATA_LINK_UP
6984 if (onePortContext->nativeSATAMode == agTRUE)
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)
6991 TI_DBG3(("tdsaSATAIncrementalDiscover: Found a PM device\n"));
6992 oneDeviceData = tdsaPortSATADeviceAdd(
6996 onePortContext->remoteSignature,
7005 /* already added in ossahwcb() in SATA link up */
7006 TI_DBG3(("tdsaSATAIncrementalDiscover: Found a DIRECT SATA device\n"));
7009 /* Process for different device type */
7010 switch ( deviceType )
7013 case SATA_PM_DEVICE:
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 ++ )
7020 /* Read the signature */
7021 /* Decode the device type */
7022 /* Create device descriptor */
7023 /* Callback with the discovered devices */
7027 /* if it's ATA device */
7028 case SATA_ATA_DEVICE:
7029 case SATA_ATAPI_DEVICE:
7031 TI_DBG3(("tdsaSATAIncrementalDiscover: Process an ATA device. Sending Identify Device cmd\n"));
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);
7037 tdsaSATADiscoverDone(tiRoot, onePortContext, tiSuccess);
7045 TI_DBG3(("siSATAIncrementalDiscover: Process OTHER SATA device. Just report the device\n"));
7051 /* If port is SAS mode */
7054 TI_DBG3(("tdsaSATAIncrementalDiscover: Discovering attached STP devices starts....\n"));
7055 oneDeviceData = tdsaFindRightDevice(tiRoot, onePortContext, tdsaDeviceData);
7057 tdsaDiscoveringStpSATADevice(tiRoot, onePortContext, oneDeviceData);
7065 /******************** SMP *******************************/
7067 /*****************************************************************************
7068 *! \brief tdSMPStart
7070 * Purpose: This function sends SMP request.
7072 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
7082 * tiSuccess SMP is sent successfully
7083 * tiError SMP is not sent successfully
7087 *****************************************************************************/
7092 tdsaDeviceData_t *oneDeviceData,
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,
7104 bit32 memAllocStatus;
7105 bit32 expectedRspLen = 0;
7108 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
7109 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
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;
7121 void *IndirectSMPReqosMemHandle;
7122 bit32 IndirectSMPReqPhysUpper32;
7123 bit32 IndirectSMPReqPhysLower32;
7124 bit32 IndirectSMPReqmemAllocStatus;
7125 bit8 *IndirectSMPReq;
7127 void *IndirectSMPResposMemHandle;
7128 bit32 IndirectSMPRespPhysUpper32;
7129 bit32 IndirectSMPRespPhysLower32;
7130 bit32 IndirectSMPRespmemAllocStatus;
7131 bit8 *IndirectSMPResp;
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));
7141 onePortContext = oneDeviceData->tdPortContext;
7143 if (onePortContext != agNULL)
7145 TI_DBG3(("tdSMPStart: pid %d\n", onePortContext->id));
7146 /* increment the number of pending SMP */
7147 onePortContext->discovery.pendingSMP++;
7151 TI_DBG1(("tdSMPStart: Wrong!!! onePortContext is NULL\n"));
7157 memAllocStatus = ostiAllocMemory(
7160 (void **)&tdSMPRequestBody,
7164 sizeof(tdssSMPRequestBody_t),
7168 if (memAllocStatus != tiSuccess)
7170 TI_DBG1(("tdSMPStart: ostiAllocMemory failed...\n"));
7174 if (tdSMPRequestBody == agNULL)
7176 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL tdSMPRequestBody\n"));
7179 /* saves mem handle for freeing later */
7180 tdSMPRequestBody->osMemHandle = osMemHandle;
7182 /* saves tdsaDeviceData */
7183 tdSMPRequestBody->tdDevice = oneDeviceData;
7185 /* saving port id */
7186 tdSMPRequestBody->tdPortContext = onePortContext;
7189 agDevHandle = oneDeviceData->agDevHandle;
7191 /* save the callback funtion */
7192 tdSMPRequestBody->SMPCompletionFunc = itdssSMPCompleted; /* in itdcb.c */
7194 /* for simulate warm target reset */
7195 tdSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
7197 /* initializes the number of SMP retries */
7198 tdSMPRequestBody->retries = 0;
7200 #ifdef TD_INTERNAL_DEBUG /* debugging */
7201 TI_DBG4(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody));
7202 TI_DBG4(("tdSMPStart: callback fn %p\n", tdSMPRequestBody->SMPCompletionFunc));
7205 agIORequest = &(tdSMPRequestBody->agIORequest);
7206 agIORequest->osData = (void *) tdSMPRequestBody;
7207 agIORequest->sdkData = agNULL; /* SALL takes care of this */
7210 agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody);
7211 agSMPFrame = &(agSASRequestBody->smpFrame);
7213 TI_DBG3(("tdSMPStart: agIORequest %p\n", agIORequest));
7214 TI_DBG3(("tdSMPStart: SMPRequestbody %p\n", tdSMPRequestBody));
7217 depending on functionCode, set expectedRspLen in smp
7219 switch (functionCode)
7221 case SMP_REPORT_GENERAL:
7222 expectedRspLen = sizeof(smpRespReportGeneral_t) + 4;
7224 case SMP_REPORT_MANUFACTURE_INFORMATION:
7225 expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4;
7228 expectedRspLen = sizeof(smpRespDiscover_t) + 4;
7230 case SMP_REPORT_PHY_ERROR_LOG:
7231 expectedRspLen = 32 - 4;
7233 case SMP_REPORT_PHY_SATA:
7234 expectedRspLen = sizeof(smpRespReportPhySata_t) + 4;
7236 case SMP_REPORT_ROUTING_INFORMATION:
7237 expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4;
7239 case SMP_CONFIGURE_ROUTING_INFORMATION:
7242 case SMP_PHY_CONTROL:
7245 case SMP_PHY_TEST_FUNCTION:
7248 case SMP_PMC_SPECIFIC:
7253 TI_DBG1(("tdSMPStart: error!!! undefined or unused smp function code 0x%x\n", functionCode));
7257 if (tiIS_SPC(agRoot))
7259 #ifdef DIRECT_SMP /* direct SMP with 48 or less payload */
7260 if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
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);
7267 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
7268 tdSMPFrameHeader.smpFunction = (bit8)functionCode;
7269 tdSMPFrameHeader.smpFunctionResult = 0;
7270 tdSMPFrameHeader.smpReserved = 0;
7272 osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4);
7273 // osti_memcpy((tdSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
7274 osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize);
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;
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;
7287 agSMPFrame->expectedRespLen = expectedRspLen;
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));
7295 TI_DBG3(("tdSMPStart: INDIRECT smp payload\n"));
7301 /* allocate Direct SMP request payload */
7302 IndirectSMPReqmemAllocStatus = ostiAllocMemory(
7304 &IndirectSMPReqosMemHandle,
7305 (void **)&IndirectSMPReq,
7306 &IndirectSMPReqPhysUpper32,
7307 &IndirectSMPReqPhysLower32,
7313 if (IndirectSMPReqmemAllocStatus != tiSuccess)
7315 TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP request...\n"));
7319 if (IndirectSMPReq == agNULL)
7321 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPReq\n"));
7325 /* allocate indirect SMP response payload */
7326 IndirectSMPRespmemAllocStatus = ostiAllocMemory(
7328 &IndirectSMPResposMemHandle,
7329 (void **)&IndirectSMPResp,
7330 &IndirectSMPRespPhysUpper32,
7331 &IndirectSMPRespPhysLower32,
7337 if (IndirectSMPRespmemAllocStatus != tiSuccess)
7339 TI_DBG1(("tdSMPStart: ostiAllocMemory failed for indirect SMP reponse...\n"));
7343 if (IndirectSMPResp == agNULL)
7345 TI_DBG1(("tdSMPStart: ostiAllocMemory returned NULL IndirectSMPResp\n"));
7349 /* saves mem handle for freeing later */
7350 tdSMPRequestBody->IndirectSMPReqosMemHandle = IndirectSMPReqosMemHandle;
7351 tdSMPRequestBody->IndirectSMPResposMemHandle = IndirectSMPResposMemHandle;
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;
7359 /* fill in indirect SMP request fields */
7360 TI_DBG3(("tdSMPStart: INDIRECT smp payload\n"));
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);
7367 /* SMP request header */
7368 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
7369 tdSMPFrameHeader.smpFunction = (bit8)functionCode;
7370 tdSMPFrameHeader.smpFunctionResult = 0;
7371 tdSMPFrameHeader.smpReserved = 0;
7373 osti_memcpy(IndirectSMPReq, &tdSMPFrameHeader, 4);
7374 osti_memcpy(IndirectSMPReq+4, pSmpBody, smpBodySize);
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 */
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;
7389 else /* SPCv controller */
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);
7398 tdSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
7399 tdSMPFrameHeader.smpFunction = (bit8)functionCode;
7400 tdSMPFrameHeader.smpFunctionResult = 0;
7401 tdSMPFrameHeader.smpReserved = 0;
7403 osti_memcpy(tdSMPRequestBody->smpPayload, &tdSMPFrameHeader, 4);
7404 // osti_memcpy((tdSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
7405 osti_memcpy(&(tdSMPRequestBody->smpPayload[4]), pSmpBody, smpBodySize);
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;
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;
7418 agSMPFrame->expectedRespLen = expectedRspLen;
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));
7426 if (agDevHandle == agNULL)
7428 TI_DBG1(("tdSMPStart: !!! agDevHandle is NULL !!! \n"));
7432 tdSMPRequestBody->queueNumber = queueNumber;
7433 status = saSMPStart(
7436 queueNumber, //tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData),
7443 if (status == AGSA_RC_SUCCESS)
7445 /* start SMP timer */
7446 if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
7447 functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION
7450 tdsaDiscoverySMPTimer(tiRoot, onePortContext, functionCode, tdSMPRequestBody);
7454 else if (status == AGSA_RC_BUSY)
7457 if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
7458 functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
7460 /* only for discovery related SMPs*/
7461 tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody);
7464 else if (functionCode == SMP_PHY_CONTROL)
7469 sizeof(tdssSMPRequestBody_t)
7478 sizeof(tdssSMPRequestBody_t)
7483 else /* AGSA_RC_FAILURE */
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)
7489 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
7494 sizeof(tdssSMPRequestBody_t)
7502 /*****************************************************************************
7503 *! \brief tdsaFindLocalLinkRate
7505 * Purpose: This function finds local link rate.
7507 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
7509 * \param tdsaPortStartInfo: Pointer to the port start information.
7516 *****************************************************************************/
7518 tdsaFindLocalLinkRate(
7520 tdsaPortStartInfo_t *tdsaPortStartInfo
7523 bit8 ans = SAS_CONNECTION_RATE_3_0G; /* default */
7524 bit32 phyProperties;
7526 phyProperties = tdsaPortStartInfo->agPhyConfig.phyProperties;
7528 TI_DBG3(("tdsaFindLocalLinkRate: start\n"));
7529 if (phyProperties & 0x4)
7531 ans = SAS_CONNECTION_RATE_6_0G;
7533 if (phyProperties & 0x2)
7535 ans = SAS_CONNECTION_RATE_3_0G;
7537 if (phyProperties & 0x1)
7539 ans = SAS_CONNECTION_RATE_1_5G;
7541 TI_DBG3(("tdsaFindLocalLinkRate: ans 0x%x\n", ans));
7545 /*****************************************************************************
7546 *! \brief tdsaConfigureRouteTimer
7548 * Purpose: This function sets timers for configuring routing of discovery and
7549 * its callback function.
7551 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
7560 * \note: called by tdsaDiscoverRespRcvd()
7562 *****************************************************************************/
7564 tdsaConfigureRouteTimer(tiRoot_t *tiRoot,
7565 tdsaPortContext_t *onePortContext,
7566 tdsaExpander_t *oneExpander,
7567 smpRespDiscover_t *ptdSMPDiscoverResp
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;
7575 TI_DBG1(("tdsaConfigureRouteTimer: start\n"));
7576 TI_DBG1(("tdsaConfigureRouteTimer: pid %d\n", onePortContext->id));
7578 discovery = &(onePortContext->discovery);
7580 TI_DBG1(("tdsaConfigureRouteTimer: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp));
7582 TI_DBG1(("tdsaConfigureRouteTimer: discovery %p \n", discovery));
7584 TI_DBG1(("tdsaConfigureRouteTimer: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries));
7586 TI_DBG1(("tdsaConfigureRouteTimer: discovery->status %d\n", discovery->status));
7588 if (discovery->configureRouteTimer.timerRunning == agTRUE)
7592 &discovery->configureRouteTimer
7596 TI_DBG1(("tdsaConfigureRouteTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
7597 TI_DBG1(("tdsaConfigureRouteTimer: Timervalue %d\n", CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
7599 tdsaSetTimerRequest(
7601 &discovery->configureRouteTimer,
7602 CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
7603 tdsaConfigureRouteTimerCB,
7604 (void *)onePortContext,
7605 (void *)oneExpander,
7606 (void *)ptdSMPDiscoverResp
7611 &Initiator->timerlist,
7612 &discovery->configureRouteTimer
7618 /*****************************************************************************
7619 *! \brief tdsaConfigureRouteTimerCB
7621 * Purpose: This function is callback function for tdsaConfigureRouteTimer.
7623 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
7634 *****************************************************************************/
7636 tdsaConfigureRouteTimerCB(
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;
7651 TI_DBG1(("tdsaConfigureRouteTimerCB: start\n"));
7653 onePortContext = (tdsaPortContext_t *)timerData1;
7654 oneExpander = (tdsaExpander_t *)timerData2;
7655 ptdSMPDiscoverResp = (smpRespDiscover_t *)timerData3;
7657 discovery = &(onePortContext->discovery);
7659 TI_DBG1(("tdsaConfigureRouteTimerCB: onePortContext %p oneExpander %p ptdSMPDiscoverResp %p\n", onePortContext, oneExpander, ptdSMPDiscoverResp));
7661 TI_DBG1(("tdsaConfigureRouteTimerCB: discovery %p\n", discovery));
7663 TI_DBG1(("tdsaConfigureRouteTimerCB: pid %d configureRouteRetries %d\n", onePortContext->id, discovery->configureRouteRetries));
7665 TI_DBG1(("tdsaConfigureRouteTimerCB: discovery.status %d\n", discovery->status));
7667 discovery->configureRouteRetries++;
7668 if (discovery->configureRouteRetries >= DISCOVERY_RETRIES)
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)
7678 &discovery->configureRouteTimer
7685 if (onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
7687 TI_DBG1(("tdsaConfigureRouteTimerCB: proceed by calling tdsaSASDownStreamDiscoverExpanderPhy\n"));
7688 tdhexdump("tdsaConfigureRouteTimerCB", (bit8*)ptdSMPDiscoverResp, sizeof(smpRespDiscover_t));
7689 discovery->configureRouteRetries = 0;
7691 tdsaSASDownStreamDiscoverExpanderPhy(tiRoot, onePortContext, oneExpander, ptdSMPDiscoverResp);
7695 TI_DBG1(("tdsaConfigureRouteTimerCB: setting timer again\n"));
7696 /* set the timer again */
7697 tdsaSetTimerRequest(
7699 &discovery->configureRouteTimer,
7700 CONFIGURE_ROUTE_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
7701 tdsaConfigureRouteTimerCB,
7702 (void *)onePortContext,
7703 (void *)oneExpander,
7704 (void *)ptdSMPDiscoverResp
7709 &Initiator->timerlist,
7710 &discovery->configureRouteTimer
7713 // tdsaReportGeneralSend(tiRoot, oneDeviceData);
7717 /*****************************************************************************
7718 *! \brief tdsaDiscoveryTimer
7720 * Purpose: This function sets timers for discovery and its callback
7723 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
7725 * \param onePortContext: Pointer to the portal context instance.
7726 * \param oneDeviceData: Pointer to the device data.
7733 *****************************************************************************/
7735 tdsaDiscoveryTimer(tiRoot_t *tiRoot,
7736 tdsaPortContext_t *onePortContext,
7737 tdsaDeviceData_t *oneDeviceData
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;
7745 TI_DBG1(("tdsaDiscoveryTimer: start\n"));
7746 TI_DBG1(("tdsaDiscoveryTimer: pid %d\n", onePortContext->id));
7748 discovery = &(onePortContext->discovery);
7750 if (discovery->discoveryTimer.timerRunning == agTRUE)
7754 &discovery->discoveryTimer
7758 TI_DBG1(("tdsaDiscoveryTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
7759 TI_DBG1(("tdsaDiscoveryTimer: Timervalue %d\n", DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
7761 tdsaSetTimerRequest(
7763 &discovery->discoveryTimer,
7764 DISCOVERY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
7765 tdsaDiscoveryTimerCB,
7773 &Initiator->timerlist,
7774 &discovery->discoveryTimer
7780 /*****************************************************************************
7781 *! \brief tdsaDiscoveryTimerCB
7783 * Purpose: This function is callback function for discovery timer.
7785 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
7796 *****************************************************************************/
7798 tdsaDiscoveryTimerCB(
7805 tdsaDeviceData_t *oneDeviceData;
7806 oneDeviceData = (tdsaDeviceData_t *)timerData1;
7808 TI_DBG1(("tdsaDiscoveryTimerCB: start\n"));
7810 if (oneDeviceData->registered == agTRUE)
7812 TI_DBG1(("tdsaDiscoveryTimerCB: resumes discovery\n"));
7813 tdsaReportGeneralSend(tiRoot, oneDeviceData);
7819 /*****************************************************************************
7820 *! \brief tdsaDeviceRegistrationTimer
7822 * Purpose: This function sets timers for device registration in discovery
7824 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
7826 * \param onePortContext: Pointer to the portal context instance.
7827 * \param oneDeviceData: Pointer to the device data.
7831 * \note: called by tdsaSASFullDiscover() or tdsaSASIncrementalDiscover()
7832 * or tdsaDeviceRegistrationTimerCB()
7834 *****************************************************************************/
7836 tdsaDeviceRegistrationTimer(tiRoot_t *tiRoot,
7837 tdsaPortContext_t *onePortContext,
7838 tdsaDeviceData_t *oneDeviceData
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;
7846 TI_DBG1(("tdsaDeviceRegistrationTimer: start\n"));
7847 TI_DBG1(("tdsaDeviceRegistrationTimer: pid %d\n", onePortContext->id));
7849 discovery = &(onePortContext->discovery);
7851 if (discovery->deviceRegistrationTimer.timerRunning == agTRUE)
7855 &discovery->deviceRegistrationTimer
7859 TI_DBG1(("tdsaDeviceRegistrationTimer: UsecsPerTick %d\n", Initiator->OperatingOption.UsecsPerTick));
7860 TI_DBG1(("tdsaDeviceRegistrationTimer: Timervalue %d\n", DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick));
7862 tdsaSetTimerRequest(
7864 &discovery->deviceRegistrationTimer,
7865 DEVICE_REGISTRATION_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
7866 tdsaDeviceRegistrationTimerCB,
7874 &Initiator->timerlist,
7875 &discovery->deviceRegistrationTimer
7880 /*****************************************************************************
7881 *! \brief tdsaDeviceRegistrationTimerCB
7883 * Purpose: This function is callback function for tdsaDeviceRegistrationTimer.
7885 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
7896 *****************************************************************************/
7898 tdsaDeviceRegistrationTimerCB(
7905 tdsaPortContext_t *onePortContext;
7906 tdsaDeviceData_t *oneDeviceData;
7907 tdsaDiscovery_t *discovery;
7909 TI_DBG1(("tdsaDeviceRegistrationTimerCB: start\n"));
7911 onePortContext = (tdsaPortContext_t *)timerData1;
7912 oneDeviceData = (tdsaDeviceData_t *)timerData2;
7913 discovery = &(onePortContext->discovery);
7915 if (oneDeviceData->registered == agFALSE)
7917 discovery->deviceRetistrationRetries++;
7918 if (discovery->deviceRetistrationRetries >= DISCOVERY_RETRIES)
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)
7928 &discovery->deviceRegistrationTimer
7934 TI_DBG1(("tdsaDeviceRegistrationTimerCB: keep retrying\n"));
7935 /* start timer for device registration */
7936 tdsaDeviceRegistrationTimer(tiRoot, onePortContext, oneDeviceData);
7941 /* go ahead; continue the discovery */
7942 discovery->deviceRetistrationRetries = 0;
7943 tdsaSASUpStreamDiscoverStart(tiRoot, onePortContext, oneDeviceData);
7947 /*****************************************************************************
7948 *! \brief tdsaSMPBusyTimer
7950 * Purpose: This function sets timers for busy of saSMPStart.
7952 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
7963 *****************************************************************************/
7965 tdsaSMPBusyTimer(tiRoot_t *tiRoot,
7966 tdsaPortContext_t *onePortContext,
7967 tdsaDeviceData_t *oneDeviceData,
7968 tdssSMPRequestBody_t *tdSMPRequestBody
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;
7976 TI_DBG1(("tdsaSMPBusyTimer: start\n"));
7977 TI_DBG1(("tdsaSMPBusyTimer: pid %d\n", onePortContext->id));
7979 discovery = &(onePortContext->discovery);
7981 if (discovery->SMPBusyTimer.timerRunning == agTRUE)
7985 &discovery->SMPBusyTimer
7989 tdsaSetTimerRequest(
7991 &discovery->SMPBusyTimer,
7992 SMP_BUSY_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
8001 &Initiator->timerlist,
8002 &discovery->SMPBusyTimer
8007 /*****************************************************************************
8008 *! \brief tdsaSMPBusyTimerCB
8010 * Purpose: This function is callback function for SMP busy timer.
8012 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
8023 *****************************************************************************/
8032 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
8033 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
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;
8044 TI_DBG1(("tdsaSMPBusyTimerCB: start\n"));
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);
8055 discovery->SMPRetries++;
8057 if (discovery->SMPRetries < SMP_BUSY_RETRIES)
8059 status = saSMPStart(
8062 tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData),
8070 if (status == AGSA_RC_SUCCESS)
8072 discovery->SMPRetries = 0;
8073 if (discovery->SMPBusyTimer.timerRunning == agTRUE)
8077 &discovery->SMPBusyTimer
8081 else if (status == AGSA_RC_FAILURE)
8083 discovery->SMPRetries = 0;
8084 tdsaSASDiscoverDone(tiRoot, onePortContext, tiError);
8085 if (discovery->SMPBusyTimer.timerRunning == agTRUE)
8089 &discovery->SMPBusyTimer
8093 else /* AGSA_RC_BUSY */
8095 if (discovery->SMPRetries >= SMP_BUSY_RETRIES)
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)
8105 &discovery->SMPBusyTimer
8112 tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody);
8119 /*****************************************************************************
8120 *! \brief tdsaBCTimer
8122 * Purpose: This function sets timers for sending ID device data only for
8123 * directly attached SATA device.
8125 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
8136 *****************************************************************************/
8138 tdsaBCTimer(tiRoot_t *tiRoot,
8139 tdsaPortContext_t *onePortContext
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;
8148 TI_DBG1(("tdsaBCTimer: start\n"));
8150 discovery = &(onePortContext->discovery);
8152 if (discovery->BCTimer.timerRunning == agTRUE)
8160 if (onePortContext->valid == agTRUE)
8162 tdsaSetTimerRequest(
8164 &discovery->BCTimer,
8165 BC_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
8174 &Initiator->timerlist,
8183 /*****************************************************************************
8184 *! \brief tdsaBCTimerCB
8186 * Purpose: This function is callback function for SATA ID device data.
8188 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
8199 *****************************************************************************/
8208 tdsaPortContext_t *onePortContext;
8209 tdsaDiscovery_t *discovery;
8211 TI_DBG1(("tdsaBCTimerCB: start\n"));
8213 onePortContext = (tdsaPortContext_t *)timerData1;
8214 discovery = &(onePortContext->discovery);
8216 discovery->ResetTriggerred = agFALSE;
8218 if (onePortContext->valid == agTRUE)
8223 TDSA_DISCOVERY_TYPE_SAS,
8224 TDSA_DISCOVERY_OPTION_INCREMENTAL_START
8227 if (discovery->BCTimer.timerRunning == agTRUE)
8238 /*****************************************************************************
8239 *! \brief tdsaDiscoverySMPTimer
8241 * Purpose: This function sets timers for sending discovery-related SMP
8243 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
8245 * \param onePortContext: Pointer to the portal context instance.
8246 * \param functionCode: SMP function.
8247 * \param tdSMPRequestBody: Pointer to the SMP request body.
8254 *****************************************************************************/
8256 tdsaDiscoverySMPTimer(tiRoot_t *tiRoot,
8257 tdsaPortContext_t *onePortContext,
8258 bit32 functionCode, /* smp function code */
8259 tdssSMPRequestBody_t *tdSMPRequestBody
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;
8267 TI_DBG3(("tdsaDiscoverySMPTimer: start\n"));
8268 TI_DBG3(("tdsaDiscoverySMPTimer: pid %d SMPFn 0x%x\n", onePortContext->id, functionCode));
8270 /* start the SMP timer which works as SMP application timer */
8271 discovery = &(onePortContext->discovery);
8273 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE)
8277 &discovery->DiscoverySMPTimer
8280 tdsaSetTimerRequest(
8282 &discovery->DiscoverySMPTimer,
8283 SMP_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
8284 tdsaDiscoverySMPTimerCB,
8292 &Initiator->timerlist,
8293 &discovery->DiscoverySMPTimer
8299 /*****************************************************************************
8300 *! \brief tdsaDiscoverySMPTimerCB
8302 * Purpose: This function is callback function for tdsaDiscoverySMPTimer.
8304 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
8315 *****************************************************************************/
8317 tdsaDiscoverySMPTimerCB(
8325 tdsaPortContext_t *onePortContext;
8328 tdssSMPFrameHeader_t *tdSMPFrameHeader;
8331 tdssSMPRequestBody_t *tdSMPRequestBody;
8332 tdsaDiscovery_t *discovery;
8333 tdsaDeviceData_t *oneDeviceData;
8334 agsaIORequest_t *agAbortIORequest = agNULL;
8335 tdIORequestBody_t *tdAbortIORequestBody = agNULL;
8338 bit32 memAllocStatus;
8340 agsaIORequest_t *agToBeAbortIORequest = agNULL;
8342 TI_DBG1(("tdsaDiscoverySMPTimerCB: start\n"));
8345 if discovery related SMP, fail the discovery
8347 be sure to abort SMP
8349 onePortContext = (tdsaPortContext_t *)timerData1;
8350 tdSMPRequestBody = (tdssSMPRequestBody_t *)timerData2;
8352 discovery = &(onePortContext->discovery);
8353 oneDeviceData = tdSMPRequestBody->tdDevice;
8354 agToBeAbortIORequest = &(tdSMPRequestBody->agIORequest);
8355 agRoot = oneDeviceData->agRoot;
8358 SMPFunction = tdSMPRequestBody->smpPayload[1];
8360 saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 0, smpHeader, 4);
8361 tdSMPFrameHeader = (tdssSMPFrameHeader_t *)smpHeader;
8362 SMPFunction = tdSMPFrameHeader->smpFunction;
8365 TI_DBG1(("tdsaDiscoverySMPTimerCB: SMP function 0x%x\n", SMPFunction));
8367 if (discovery->DiscoverySMPTimer.timerRunning == agTRUE)
8371 &discovery->DiscoverySMPTimer
8374 switch (SMPFunction)
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);
8382 case SMP_REPORT_PHY_SATA:
8383 TI_DBG1(("tdsaDiscoverySMPTimerCB: failing discovery, SMP function SMP_REPORT_PHY_SATA\n"));
8384 tdsaSATADiscoverDone(tiRoot, onePortContext, tiError);
8388 TI_DBG1(("tdsaDiscoverySMPTimerCB: Error!!!! not allowed case\n"));
8392 if (onePortContext->discovery.SeenBC == agTRUE)
8394 /* allocating agIORequest for abort itself */
8395 memAllocStatus = ostiAllocMemory(
8398 (void **)&tdAbortIORequestBody,
8402 sizeof(tdIORequestBody_t),
8405 if (memAllocStatus != tiSuccess)
8407 /* let os process IO */
8408 TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory failed...\n"));
8412 if (tdAbortIORequestBody == agNULL)
8414 /* let os process IO */
8415 TI_DBG1(("tdsaDiscoverySMPTimerCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
8419 /* setup task management structure */
8420 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
8421 /* setting callback */
8422 tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler;
8424 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle);
8426 /* initialize agIORequest */
8427 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
8428 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
8429 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
8431 /* SMPAbort - abort one */
8435 oneDeviceData->agDevHandle,
8437 agToBeAbortIORequest,
8446 /*****************************************************************************
8447 *! \brief tdsaSATAIDDeviceTimer
8449 * Purpose: This function sets timers for sending ID device data only for
8450 * directly attached SATA device.
8452 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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.
8463 *****************************************************************************/
8465 tdsaSATAIDDeviceTimer(tiRoot_t *tiRoot,
8466 tdsaDeviceData_t *oneDeviceData
8469 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
8470 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
8471 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
8473 TI_DBG1(("tdsaSATAIDDeviceTimer: start\n"));
8475 if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE)
8479 &oneDeviceData->SATAIDDeviceTimer
8483 tdsaSetTimerRequest(
8485 &oneDeviceData->SATAIDDeviceTimer,
8486 SATA_ID_DEVICE_DATA_TIMER_VALUE/Initiator->OperatingOption.UsecsPerTick,
8487 tdsaSATAIDDeviceTimerCB,
8495 &Initiator->timerlist,
8496 &oneDeviceData->SATAIDDeviceTimer
8502 /*****************************************************************************
8503 *! \brief tdsaSATAIDDeviceTimerCB
8505 * Purpose: This function is callback function for SATA ID device data.
8507 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t
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
8518 *****************************************************************************/
8520 tdsaSATAIDDeviceTimerCB(
8527 tdsaDeviceData_t *oneDeviceData;
8529 TI_DBG1(("tdsaSATAIDDeviceTimerCB: start\n"));
8531 oneDeviceData = (tdsaDeviceData_t *)timerData1;
8533 /* send identify device data */
8534 tdssSubAddSATAToSharedcontext(tiRoot, oneDeviceData);
8536 if (oneDeviceData->SATAIDDeviceTimer.timerRunning == agTRUE)
8540 &oneDeviceData->SATAIDDeviceTimer
8547 #endif /* TD_DISCOVER */