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