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