1/*******************************************************************************
2*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3*
4*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*that the following conditions are met:
6*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*following disclaimer.
8*2. Redistributions in binary form must reproduce the above copyright notice,
9*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*with the distribution.
11*
12*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21**
22********************************************************************************/
23#include <sys/cdefs.h>
24__FBSDID("$FreeBSD$");
25#include <dev/pms/config.h>
26
27#include <dev/pms/freebsd/driver/common/osenv.h>
28#include <dev/pms/freebsd/driver/common/ostypes.h>
29#include <dev/pms/freebsd/driver/common/osdebug.h>
30
31#include <dev/pms/RefTisa/sallsdk/api/sa.h>
32#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34
35#ifdef FDS_DM
36#include <dev/pms/RefTisa/discovery/api/dm.h>
37#include <dev/pms/RefTisa/discovery/api/dmapi.h>
38#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
39
40#include <dev/pms/RefTisa/discovery/dm/dmdefs.h>
41#include <dev/pms/RefTisa/discovery/dm/dmtypes.h>
42#include <dev/pms/RefTisa/discovery/dm/dmproto.h>
43
44osGLOBAL bit32
45dmSMPStart(
46           dmRoot_t              *dmRoot,
47           agsaRoot_t            *agRoot,
48           dmDeviceData_t        *oneDeviceData,
49           bit32                 functionCode,
50           bit8                  *pSmpBody,
51           bit32                 smpBodySize,
52           bit32                 agRequestType
53           )
54{
55  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
56  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
57  dmIntPortContext_t        *onePortContext = agNULL;
58  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
59#ifndef DIRECT_SMP
60  dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
61#endif
62  agsaSASRequestBody_t      *agSASRequestBody;
63  dmList_t                  *SMPList;
64  agsaDevHandle_t           *agDevHandle;
65  agsaIORequest_t           *agIORequest;
66  agsaSMPFrame_t            *agSMPFrame;
67  bit32                     expectedRspLen = 0;
68  dmSMPFrameHeader_t        dmSMPFrameHeader;
69  dmExpander_t              *oneExpander = agNULL;
70  bit32                     status;
71
72  DM_DBG5(("dmSMPStart: start\n"));
73  DM_DBG5(("dmSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
74  DM_DBG5(("dmSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
75
76  dm_memset(&dmSMPFrameHeader, 0, sizeof(dmSMPFrameHeader_t));
77
78  onePortContext = oneDeviceData->dmPortContext;
79
80  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
81  {
82    DM_DBG1(("dmSMPStart: invalid port or aborted discovery!!!\n"));
83    return DM_RC_FAILURE;
84  }
85
86  oneExpander = oneDeviceData->dmExpander;
87  if (oneExpander == agNULL)
88  {
89    DM_DBG1(("dmSMPStart: Wrong!!! oneExpander is NULL!!!\n"));
90    return DM_RC_FAILURE;
91  }
92
93  if (onePortContext != agNULL)
94  {
95    DM_DBG5(("dmSMPStart: pid %d\n", onePortContext->id));
96    /* increment the number of pending SMP */
97    onePortContext->discovery.pendingSMP++;
98  }
99  else
100  {
101    DM_DBG1(("dmSMPStart: Wrong, onePortContext is NULL!!!\n"));
102    return DM_RC_FAILURE;
103  }
104
105  /* get an smp REQUEST from the free list */
106  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
107  if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
108  {
109    DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
110    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
111    /* undo increment the number of pending SMP */
112    onePortContext->discovery.pendingSMP--;
113    return DM_RC_FAILURE;
114  }
115  else
116  {
117    DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
118    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
119    dmSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
120  }
121
122  if (dmSMPRequestBody == agNULL)
123  {
124    DM_DBG1(("dmSMPStart: dmSMPRequestBody is NULL, wrong!!!\n"));
125    return DM_RC_FAILURE;
126  }
127  DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPRequestBody->id));
128
129  dmSMPRequestBody->dmRoot = dmRoot;
130  dmSMPRequestBody->dmDevice = oneDeviceData;
131  dmSMPRequestBody->dmPortContext = onePortContext;
132
133  agDevHandle = oneExpander->agDevHandle;
134
135  /* save the callback funtion */
136  dmSMPRequestBody->SMPCompletionFunc = dmSMPCompleted; /* in dmsmp.c */
137
138  dmSMPRequestBody->retries = 0;
139
140  agIORequest = &(dmSMPRequestBody->agIORequest);
141  agIORequest->osData = (void *) dmSMPRequestBody;
142  agIORequest->sdkData = agNULL; /* SALL takes care of this */
143
144  agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
145  agSMPFrame = &(agSASRequestBody->smpFrame);
146
147  /* sets dmSMPFrameHeader values */
148  if (oneExpander->SAS2 == 0)
149  {
150    DM_DBG5(("dmSMPStart: SAS 1.1\n"));
151    switch (functionCode)
152    {
153    case SMP_REPORT_GENERAL:
154      expectedRspLen = sizeof(smpRespReportGeneral_t) + 4;
155      break;
156    case SMP_REPORT_MANUFACTURE_INFORMATION:
157      expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4;
158      break;
159    case SMP_DISCOVER:
160      expectedRspLen = sizeof(smpRespDiscover_t) + 4;
161      break;
162    case SMP_REPORT_PHY_ERROR_LOG:
163      expectedRspLen = 32 - 4;
164      break;
165    case SMP_REPORT_PHY_SATA:
166      expectedRspLen = sizeof(smpRespReportPhySata_t) + 4;
167      break;
168    case SMP_REPORT_ROUTING_INFORMATION:
169      expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4;
170      break;
171    case SMP_CONFIGURE_ROUTING_INFORMATION:
172      expectedRspLen = 4;
173      break;
174    case SMP_PHY_CONTROL:
175      expectedRspLen = 4;
176      break;
177    case SMP_PHY_TEST_FUNCTION:
178      expectedRspLen = 4;
179      break;
180    case SMP_PMC_SPECIFIC:
181      expectedRspLen = 4;
182      break;
183    default:
184      expectedRspLen = 0;
185      DM_DBG1(("dmSMPStart: SAS 1.1 error, undefined or unused smp function code 0x%x !!!\n", functionCode));
186      return DM_RC_FAILURE;
187    }
188    /* SMP 1.1 header */
189    dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
190    dmSMPFrameHeader.smpFunction = (bit8)functionCode;
191    dmSMPFrameHeader.smpFunctionResult = 0;
192    dmSMPFrameHeader.smpReserved = 0;
193  }
194  else /* SAS 2 */
195  {
196    DM_DBG2(("dmSMPStart: SAS 2\n"));
197    switch (functionCode)
198    {
199    case SMP_REPORT_GENERAL:
200      expectedRspLen = sizeof(smpRespReportGeneral2_t) + 4;
201      /* SMP 2.0 header */
202      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
203      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
204      dmSMPFrameHeader.smpFunctionResult = 0x11;
205      dmSMPFrameHeader.smpReserved = 0;
206      break;
207    case SMP_REPORT_MANUFACTURE_INFORMATION:
208      expectedRspLen = sizeof(smpRespReportManufactureInfo2_t) + 4;
209      break;
210    case SMP_DISCOVER:
211      expectedRspLen = sizeof(smpRespDiscover2_t) + 4;
212      /* SMP 2.0 header */
213      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
214      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
215//      dmSMPFrameHeader.smpFunctionResult = 0x6c;
216      dmSMPFrameHeader.smpFunctionResult = 0x1b;
217      dmSMPFrameHeader.smpReserved = 0x02;
218      break;
219    case SMP_REPORT_PHY_ERROR_LOG:
220      expectedRspLen = 32 - 4;
221      break;
222    case SMP_REPORT_PHY_SATA:
223      /* SMP 2.0 header */
224      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
225      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
226      dmSMPFrameHeader.smpFunctionResult = 0x10;
227      dmSMPFrameHeader.smpReserved = 0x02;
228      expectedRspLen = sizeof(smpRespReportPhySata2_t) + 4;
229      break;
230    case SMP_REPORT_ROUTING_INFORMATION:
231      expectedRspLen = sizeof(smpRespReportRouteTable2_t) + 4;
232      break;
233    case SMP_CONFIGURE_ROUTING_INFORMATION:
234      expectedRspLen = 4;
235      /* SMP 2.0 header */
236      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
237      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
238      dmSMPFrameHeader.smpFunctionResult = 0;
239      dmSMPFrameHeader.smpReserved = 0x09;
240      break;
241    case SMP_PHY_CONTROL:
242      expectedRspLen = 4;
243      /* SMP 2.0 header */
244      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
245      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
246      dmSMPFrameHeader.smpFunctionResult = 0;
247      dmSMPFrameHeader.smpReserved = 0x09;
248     break;
249    case SMP_PHY_TEST_FUNCTION:
250      expectedRspLen = 4;
251      break;
252    case SMP_DISCOVER_LIST:
253      expectedRspLen = SMP_MAXIMUM_PAYLOAD; /* 1024 without CRC */
254      /* SMP 2.0 header */
255      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
256      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
257      dmSMPFrameHeader.smpFunctionResult = 0xFF;
258      dmSMPFrameHeader.smpReserved = 0x06;
259      break;
260    case SMP_PMC_SPECIFIC:
261      expectedRspLen = 4;
262      break;
263    default:
264      expectedRspLen = 0;
265      DM_DBG1(("dmSMPStart: SAS 2 error!!! undefined or unused smp function code 0x%x!!!\n", functionCode));
266      return DM_RC_FAILURE;
267    }
268  }
269
270  if (DMIsSPC(agRoot))
271  {
272#ifdef DIRECT_SMP  /* direct SMP with 48 or less payload */
273  if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
274  {
275    DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
276    dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
277    dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
278    dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
279
280    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
281    agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
282    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
283    /* to specify DIRECT SMP response */
284    agSMPFrame->inFrameLen = 0;
285
286    /* temporary solution for T2D Combo*/
287#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
288    /* force smp repsonse to be direct */
289    agSMPFrame->expectedRespLen = 0;
290#else
291    agSMPFrame->expectedRespLen = expectedRspLen;
292#endif
293  }
294  else
295  {
296    DM_DBG5(("dmSMPStart: INDIRECT smp payload, TBD\n"));
297  }
298
299#else
300
301  /*
302     dmSMPRequestBody is SMP request
303     dmSMPResponsebody is SMP response
304  */
305
306  /* get an smp RESPONSE from the free list */
307  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
308  if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
309  {
310    DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
311    /* puy back dmSMPRequestBody to the freelist ???*/
312//    DMLIST_DEQUEUE_THIS(&(dmSMPRequestBody->Link));
313    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
314    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
315
316    /* undo increment the number of pending SMP */
317    onePortContext->discovery.pendingSMP--;
318    return DM_RC_FAILURE;
319  }
320  else
321  {
322    DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
323    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
324    dmSMPResponseBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
325    DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPResponseBody->id));
326  }
327
328  if (dmSMPResponseBody == agNULL)
329  {
330    DM_DBG1(("dmSMPStart: dmSMPResponseBody is NULL, wrong!!!\n"));
331    return DM_RC_FAILURE;
332  }
333
334  /* fill in indirect SMP request fields */
335  DM_DBG5(("dmSMPStart: INDIRECT smp payload\n"));
336
337  /* save the pointer to SMP response in SMP request */
338  dmSMPRequestBody->IndirectSMPResponse = dmSMPResponseBody;
339  /* SMP request and response initialization */
340  dm_memset(dmSMPRequestBody->IndirectSMP, 0, smpBodySize + 4);
341  dm_memset(dmSMPResponseBody->IndirectSMP, 0, expectedRspLen);
342
343  dm_memcpy(dmSMPRequestBody->IndirectSMP, &dmSMPFrameHeader, 4);
344  dm_memcpy(dmSMPRequestBody->IndirectSMP+4, pSmpBody, smpBodySize);
345
346  /* Indirect SMP request */
347  agSMPFrame->outFrameBuf = agNULL;
348  agSMPFrame->outFrameAddrUpper32 = dmSMPRequestBody->IndirectSMPUpper32;
349  agSMPFrame->outFrameAddrLower32 = dmSMPRequestBody->IndirectSMPLower32;
350  agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
351
352  /* Indirect SMP response */
353  agSMPFrame->expectedRespLen = expectedRspLen;
354  agSMPFrame->inFrameAddrUpper32 = dmSMPResponseBody->IndirectSMPUpper32;
355  agSMPFrame->inFrameAddrLower32 = dmSMPResponseBody->IndirectSMPLower32;
356  agSMPFrame->inFrameLen = expectedRspLen; /* without last 4 byte crc */
357
358#endif
359  }
360  else /* SPCv controller */
361  {
362    /* only direct mode for both request and response */
363    DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
364    agSMPFrame->flag = 0;
365    dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
366    dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
367    dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
368
369    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
370    agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
371    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
372    /* to specify DIRECT SMP response */
373    agSMPFrame->inFrameLen = 0;
374
375      /* temporary solution for T2D Combo*/
376#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
377    /* force smp repsonse to be direct */
378    agSMPFrame->expectedRespLen = 0;
379#else
380    agSMPFrame->expectedRespLen = expectedRspLen;
381#endif
382  //    tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
383  //    tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
384  //    tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t));
385  }
386
387  if (agDevHandle == agNULL)
388  {
389    DM_DBG1(("dmSMPStart: !!! agDevHandle is NULL !!! \n"));
390  }
391  else
392  {
393    status = saSMPStart(
394                      agRoot,
395                      agIORequest,
396                      0,
397                      agDevHandle,
398                      agRequestType,
399                      agSASRequestBody,
400                      &dmsaSMPCompleted
401                      );
402
403    if (status == AGSA_RC_SUCCESS)
404    {
405      /* start SMP timer */
406      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
407          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION
408        )
409      {
410        dmDiscoverySMPTimer(dmRoot, onePortContext, functionCode, dmSMPRequestBody);
411      }
412      return DM_RC_SUCCESS;
413    }
414    else if (status == AGSA_RC_BUSY)
415    {
416      /* set timer */
417      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
418          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
419      {
420        /* only for discovery related SMPs*/
421        dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
422        return DM_RC_SUCCESS;
423      }
424      else
425      {
426        DM_DBG1(("dmSMPStart: return DM_RC_BUSY!!! \n"));
427#ifdef DIRECT_SMP
428        tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
429        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
430        tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
431#else
432        tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
433        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
434        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
435        tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
436#endif
437        return DM_RC_BUSY;
438      }
439    }
440    else /* AGSA_RC_FAILURE */
441    {
442      DM_DBG1(("dmSMPStart: return DM_RC_FAILURE!!! \n"));
443      /* discovery failure or task management failure */
444      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
445          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
446      {
447        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
448      }
449#ifdef DIRECT_SMP
450      tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
451      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
452      tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
453#else
454      tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
455      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
456      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
457      tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
458#endif
459
460      return DM_RC_FAILURE;
461    }
462  }
463  return DM_RC_SUCCESS;
464}
465
466osGLOBAL void
467dmsaSMPCompleted(
468                 agsaRoot_t            *agRoot,
469                 agsaIORequest_t       *agIORequest,
470                 bit32                 agIOStatus,
471                 bit32                 agIOInfoLen,
472                 agsaFrameHandle_t     agFrameHandle
473                 )
474{
475  dmSMPRequestBody_t   *pSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
476
477  /* SPC can't be SMP target */
478
479  DM_DBG5(("dmsaSMPCompleted: start\n"));
480
481  if (pSMPRequestBody == agNULL)
482  {
483    DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody is NULL!!! \n"));
484    return;
485  }
486
487  if (pSMPRequestBody->SMPCompletionFunc == agNULL)
488  {
489    DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody->SMPCompletionFunc is NULL!!!\n"));
490    return;
491  }
492
493#ifdef DM_INTERNAL_DEBUG /* debugging */
494  DM_DBG3(("dmsaSMPCompleted: agIOrequest %p\n", agIORequest->osData));
495  DM_DBG3(("dmsaSMPCompleted: sizeof(tdIORequestBody_t) %d 0x%x\n", sizeof(tdIORequestBody_t),
496           sizeof(tdIORequestBody_t)));
497  DM_DBG3(("dmsaSMPCompleted: SMPRequestbody %p\n", pSMPRequestBody));
498  DM_DBG3(("dmsaSMPCompleted: calling callback fn\n"));
499  DM_DBG3(("dmsaSMPCompleted: callback fn %p\n",pSMPRequestBody->SMPCompletionFunc));
500#endif /* TD_INTERNAL_DEBUG */
501  /*
502    if initiator, calling dmSMPCompleted() in dmsmp.c
503  */
504  pSMPRequestBody->SMPCompletionFunc(
505                                     agRoot,
506                                     agIORequest,
507                                     agIOStatus,
508                                     agIOInfoLen,
509                                     agFrameHandle
510                                     );
511
512  return;
513
514}
515
516osGLOBAL bit32
517dmPhyControlSend(
518                   dmRoot_t             *dmRoot,
519//                   dmDeviceData_t     *oneDeviceData, /* taget disk */
520                   dmDeviceData_t     *oneExpDeviceData, /* taget disk */
521                   bit8                 phyOp,
522bit8 phyID // added
523                   )
524{
525  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
526  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
527  agsaRoot_t                *agRoot = dmAllShared->agRoot;
528//  thenil
529//  dmDeviceData_t      *oneExpDeviceData;
530  smpReqPhyControl_t    smpPhyControlReq;
531//  bit8                  phyID;
532  bit32                 status;
533
534  DM_DBG3(("dmPhyControlSend: start\n"));
535
536
537
538  osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
539
540  /* fill in SMP payload */
541  smpPhyControlReq.phyIdentifier = phyID;
542  smpPhyControlReq.phyOperation = phyOp;
543
544  status = dmSMPStart(
545                      dmRoot,
546                      agRoot,
547                      oneExpDeviceData,
548                      SMP_PHY_CONTROL,
549                      (bit8 *)&smpPhyControlReq,
550                      sizeof(smpReqPhyControl_t),
551                      AGSA_SMP_INIT_REQ
552                     );
553  return status;
554}
555
556osGLOBAL void
557dmReportGeneralSend(
558                    dmRoot_t             *dmRoot,
559                    dmDeviceData_t       *oneDeviceData
560                    )
561{
562  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
563  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
564  agsaRoot_t                *agRoot = dmAllShared->agRoot;
565
566  DM_DBG3(("dmReportGeneralSend: start\n"));
567  DM_DBG3(("dmReportGeneralSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
568  DM_DBG3(("dmReportGeneralSend: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id));
569
570  if (agRoot == agNULL)
571  {
572    DM_DBG1(("dmReportGeneralSend: agRoot is NULL!!!\n"));
573    return;
574  }
575
576  dmSMPStart(
577             dmRoot,
578             agRoot,
579             oneDeviceData,
580             SMP_REPORT_GENERAL,
581             agNULL,
582             0,
583             AGSA_SMP_INIT_REQ
584             );
585  return;
586}
587osGLOBAL void
588dmReportGeneralRespRcvd(
589                        dmRoot_t              *dmRoot,
590                        agsaRoot_t            *agRoot,
591                        agsaIORequest_t       *agIORequest,
592                        dmDeviceData_t        *oneDeviceData,
593                        dmSMPFrameHeader_t    *frameHeader,
594                        agsaFrameHandle_t     frameHandle
595                        )
596{
597  smpRespReportGeneral_t       dmSMPReportGeneralResp;
598  smpRespReportGeneral_t       *pdmSMPReportGeneralResp;
599  dmIntPortContext_t           *onePortContext = agNULL;
600  dmDiscovery_t                *discovery;
601  dmExpander_t                 *oneExpander = agNULL;
602#ifndef DIRECT_SMP
603  dmSMPRequestBody_t           *dmSMPRequestBody;
604  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
605#endif
606  dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
607  dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
608
609  DM_DBG3(("dmReportGeneralRespRcvd: start\n"));
610  DM_DBG3(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
611  DM_DBG3(("dmReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
612
613#ifndef DIRECT_SMP
614  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
615#endif
616  pdmSMPReportGeneralResp = &dmSMPReportGeneralResp;
617
618  dm_memset(&dmSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t));
619
620#ifdef DIRECT_SMP
621  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
622#else
623  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
624  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
625#endif
626
627  onePortContext = oneDeviceData->dmPortContext;
628  discovery = &(onePortContext->discovery);
629
630  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
631  {
632    DM_DBG1(("dmReportGeneralRespRcvd: invalid port or aborted discovery!!!\n"));
633    return;
634  }
635
636  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
637  {
638    oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneralResp->numOfPhys;
639    oneExpander = oneDeviceData->dmExpander;
640    oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneralResp);
641    oneExpander->configReserved = 0;
642    oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneralResp) ? 1 : 0;
643    oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneralResp) ? 1 : 0;
644    DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
645    DM_DBG3(("dmReportGeneralRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
646    DM_DBG3(("dmReportGeneralRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
647
648    if ( oneExpander->SAS2 == 0 && REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp) == 1)
649    {
650      oneExpander->SAS2 = REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp);
651      DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 Long Response=%d\n", REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp)));
652      dmReportGeneralSend(dmRoot, oneDeviceData);
653      return;
654    }
655
656    DM_DBG3(("dmReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
657      oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
658    DM_DBG3(("dmReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n",
659      oneExpander->configRouteTable, oneExpander->configuring));
660
661    if (oneExpander->configuring == 1)
662    {
663      discovery->retries++;
664      if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
665      {
666        DM_DBG1(("dmReportGeneralRespRcvd: retries are over!!!\n"));
667        DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
668        discovery->retries = 0;
669        /* failed the discovery */
670        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
671      }
672      else
673      {
674        DM_DBG3(("dmReportGeneralRespRcvd: keep retrying\n"));
675        DM_DBG1(("dmReportGeneralRespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
676        DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
677        // start timer for sending ReportGeneral
678        dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
679      }
680    }
681    else
682    {
683      discovery->retries = 0;
684      dmDiscoverSend(dmRoot, oneDeviceData);
685    }
686  }
687  else
688  {
689     DM_DBG1(("dmReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery !!!\n", frameHeader->smpFunctionResult));
690     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
691  }
692  return;
693}
694
695osGLOBAL void
696dmReportGeneral2RespRcvd(
697                        dmRoot_t              *dmRoot,
698                        agsaRoot_t            *agRoot,
699                        agsaIORequest_t       *agIORequest,
700                        dmDeviceData_t        *oneDeviceData,
701                        dmSMPFrameHeader_t    *frameHeader,
702                        agsaFrameHandle_t     frameHandle
703                        )
704{
705  smpRespReportGeneral2_t      dmSMPReportGeneral2Resp;
706  smpRespReportGeneral2_t      *pdmSMPReportGeneral2Resp;
707  dmExpander_t                 *oneExpander = agNULL;
708  dmIntPortContext_t           *onePortContext = agNULL;
709  dmDiscovery_t                *discovery;
710#ifndef DIRECT_SMP
711  dmSMPRequestBody_t           *dmSMPRequestBody;
712  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
713#endif
714  bit32                        ConfiguresOthers = agFALSE;
715  dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
716  dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
717
718
719  DM_DBG2(("dmReportGeneral2RespRcvd: start\n"));
720  DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
721  DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
722
723#ifndef DIRECT_SMP
724  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
725#endif
726  pdmSMPReportGeneral2Resp = &dmSMPReportGeneral2Resp;
727
728  dm_memset(&dmSMPReportGeneral2Resp, 0, sizeof(smpRespReportGeneral2_t));
729
730#ifdef DIRECT_SMP
731  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
732#else
733  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
734  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
735#endif
736
737  onePortContext = oneDeviceData->dmPortContext;
738  discovery = &(onePortContext->discovery);
739  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
740  {
741    DM_DBG1(("dmReportGeneral2RespRcvd: invalid port or aborted discovery!!!\n"));
742    return;
743  }
744
745/* ??? start here */
746  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
747  {
748    oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneral2Resp->numOfPhys;
749    oneExpander = oneDeviceData->dmExpander;
750    oneExpander->routingIndex = (bit16) SAS2_REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneral2Resp);
751    oneExpander->configReserved = 0;
752    oneExpander->configRouteTable = SAS2_REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneral2Resp) ? 1 : 0;
753    oneExpander->configuring = SAS2_REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneral2Resp) ? 1 : 0;
754    oneExpander->TTTSupported = SAS2_REPORT_GENERAL_IS_TABLE_TO_TABLE_SUPPORTED(pdmSMPReportGeneral2Resp) ? 1 : 0;
755    ConfiguresOthers = SAS2_REPORT_GENERAL_IS_CONFIGURES_OTHERS(pdmSMPReportGeneral2Resp) ? 1 : 0;
756
757    DM_DBG2(("dmReportGeneral2RespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
758    DM_DBG3(("dmReportGeneral2RespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
759    DM_DBG3(("dmReportGeneral2RespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
760
761
762    DM_DBG2(("dmReportGeneral2RespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
763      oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
764    DM_DBG2(("dmReportGeneral2RespRcvd: configRouteTable=%d configuring=%d\n",
765      oneExpander->configRouteTable, oneExpander->configuring));
766    if (ConfiguresOthers)
767    {
768      DM_DBG2(("dmReportGeneral2RespRcvd: ConfiguresOthers is true\n"));
769      discovery->ConfiguresOthers = agTRUE;
770    }
771    if (oneExpander->configuring == 1)
772    {
773      discovery->retries++;
774      if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
775      {
776        DM_DBG1(("dmReportGeneral2RespRcvd: retries are over!!!\n"));
777        DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
778
779        discovery->retries = 0;
780        /* failed the discovery */
781        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
782      }
783      else
784      {
785        DM_DBG2(("dmReportGeneral2RespRcvd: keep retrying\n"));
786        DM_DBG1(("dmReportGeneral2RespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
787        DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
788        // start timer for sending ReportGeneral
789        dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
790      }
791    }
792    else
793    {
794      discovery->retries = 0;
795      dmDiscoverSend(dmRoot, oneDeviceData);
796    }
797  }
798  else
799  {
800     DM_DBG2(("dmReportGeneral2RespRcvd: SMP failed, stopping discovery\n"));
801     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
802  }
803
804  return;
805}
806
807
808osGLOBAL void
809dmDiscoverSend(
810               dmRoot_t             *dmRoot,
811               dmDeviceData_t       *oneDeviceData
812              )
813{
814  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
815  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
816  agsaRoot_t                *agRoot = dmAllShared->agRoot;
817  smpReqDiscover_t          smpDiscoverReq;
818  dmExpander_t              *oneExpander;
819
820  DM_DBG3(("dmDiscoverSend: start\n"));
821  DM_DBG3(("dmDiscoverSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
822  oneExpander = oneDeviceData->dmExpander;
823  DM_DBG3(("dmDiscoverSend: oneExpander %p did %d\n", oneExpander, oneExpander->id));
824  DM_DBG3(("dmDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId));
825
826  dm_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t));
827
828  smpDiscoverReq.reserved1 = 0;
829  smpDiscoverReq.reserved2 = 0;
830  smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId;
831  smpDiscoverReq.reserved3 = 0;
832
833  dmSMPStart(
834             dmRoot,
835             agRoot,
836             oneDeviceData,
837             SMP_DISCOVER,
838             (bit8 *)&smpDiscoverReq,
839             sizeof(smpReqDiscover_t),
840             AGSA_SMP_INIT_REQ
841             );
842  return;
843}
844
845osGLOBAL void
846dmDiscoverRespRcvd(
847                   dmRoot_t              *dmRoot,
848                   agsaRoot_t            *agRoot,
849                   agsaIORequest_t       *agIORequest,
850                   dmDeviceData_t        *oneDeviceData,
851                   dmSMPFrameHeader_t    *frameHeader,
852                   agsaFrameHandle_t     frameHandle
853                  )
854{
855  dmIntPortContext_t           *onePortContext = agNULL;
856  dmDiscovery_t                *discovery;
857  smpRespDiscover_t            *pdmSMPDiscoverResp;
858#ifndef DIRECT_SMP
859  dmSMPRequestBody_t           *dmSMPRequestBody;
860  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
861#endif
862  dmExpander_t                 *oneExpander = agNULL;
863
864  DM_DBG3(("dmDiscoverRespRcvd: start\n"));
865  DM_DBG3(("dmDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
866  DM_DBG3(("dmDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
867
868  onePortContext = oneDeviceData->dmPortContext;
869  oneExpander = oneDeviceData->dmExpander;
870  discovery = &(onePortContext->discovery);
871#ifndef DIRECT_SMP
872  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
873#endif
874  DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
875  DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
876
877  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
878  {
879    DM_DBG1(("dmDiscoverRespRcvd: invalid port or aborted discovery!!!\n"));
880    return;
881  }
882
883  pdmSMPDiscoverResp = &(discovery->SMPDiscoverResp);
884
885#ifdef DIRECT_SMP
886  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
887#else
888  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
889  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
890#endif
891
892  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
893  {
894    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
895    {
896      dmUpStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
897    }
898    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
899    {
900      dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
901    }
902    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
903    {
904      /* not done with configuring routing
905         1. set the timer
906         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
907      */
908      DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
909      DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
910      dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
911
912      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
913    }
914    else
915    {
916      /* nothing */
917    }
918  }
919  else if (frameHeader->smpFunctionResult == PHY_VACANT)
920  {
921    DM_DBG3(("dmDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
922    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
923    {
924      dmUpStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
925    }
926    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
927    {
928      dmDownStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
929    }
930    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
931    {
932      /* not done with configuring routing
933         1. set the timer
934         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
935      */
936      DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
937      DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
938      dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
939
940      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
941    }
942  }
943  else
944  {
945     DM_DBG1(("dmDiscoverRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n",
946               frameHeader->smpFunctionResult));
947     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
948  }
949
950
951
952  return;
953}
954
955osGLOBAL void
956dmDiscover2RespRcvd(
957                   dmRoot_t              *dmRoot,
958                   agsaRoot_t            *agRoot,
959                   agsaIORequest_t       *agIORequest,
960                   dmDeviceData_t        *oneDeviceData,
961                   dmSMPFrameHeader_t    *frameHeader,
962                   agsaFrameHandle_t     frameHandle
963                  )
964{
965  dmIntPortContext_t           *onePortContext = agNULL;
966  dmDiscovery_t                *discovery;
967  smpRespDiscover2_t           *pdmSMPDiscover2Resp;
968#ifndef DIRECT_SMP
969  dmSMPRequestBody_t           *dmSMPRequestBody;
970  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
971#endif
972  dmExpander_t                 *oneExpander = agNULL;
973
974  DM_DBG2(("dmDiscover2RespRcvd: start\n"));
975  DM_DBG2(("dmDiscover2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
976  DM_DBG2(("dmDiscover2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
977
978  onePortContext = oneDeviceData->dmPortContext;
979  oneExpander = oneDeviceData->dmExpander;
980  discovery = &(onePortContext->discovery);
981#ifndef DIRECT_SMP
982  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
983#endif
984  DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
985  DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
986
987  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
988  {
989    DM_DBG1(("dmDiscover2RespRcvd: invalid port or aborted discovery!!!\n"));
990    return;
991  }
992
993  pdmSMPDiscover2Resp = &(discovery->SMPDiscover2Resp);
994
995#ifdef DIRECT_SMP
996  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
997#else
998  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
999  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1000#endif
1001
1002  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
1003  {
1004    DM_DBG2(("dmDiscover2RespRcvd: phyIdentifier %d\n", pdmSMPDiscover2Resp->phyIdentifier));
1005    DM_DBG2(("dmDiscover2RespRcvd: NegotiatedSSCHWMuxingSupported %d\n", pdmSMPDiscover2Resp->NegotiatedSSCHWMuxingSupported));
1006    DM_DBG2(("dmDiscover2RespRcvd: SAS2_MUXING_SUPPORTED %d\n", SAS2_DISCRSP_IS_MUXING_SUPPORTED(pdmSMPDiscover2Resp)));
1007    DM_DBG2(("dmDiscover2RespRcvd: NegotiatedLogicalLinkRate %d\n", pdmSMPDiscover2Resp->NegotiatedLogicalLinkRate));
1008    DM_DBG2(("dmDiscover2RespRcvd: ReasonNegotiatedPhysicalLinkRate %d\n", pdmSMPDiscover2Resp->ReasonNegotiatedPhysicalLinkRate));
1009    DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LOGICAL_LINKRATE %d\n", SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pdmSMPDiscover2Resp)));
1010    DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LINKRATE %d\n", SAS2_DISCRSP_GET_LINKRATE(pdmSMPDiscover2Resp)));
1011
1012//NegotiatedLogicalLinkRate 13
1013//ReasonNegotiatedPhysicalLinkRate 94
1014    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
1015    {
1016      dmUpStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
1017    }
1018    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
1019    {
1020      dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
1021    }
1022    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
1023    {
1024      /* not done with configuring routing
1025         1. set the timer
1026         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
1027      */
1028      DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
1029      DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
1030      dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1031      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
1032    }
1033    else
1034    {
1035      /* nothing */
1036    }
1037  }
1038  else if (frameHeader->smpFunctionResult == PHY_VACANT)
1039  {
1040    DM_DBG2(("dmDiscover2RespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
1041    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
1042    {
1043      dmUpStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
1044    }
1045    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
1046    {
1047      dmDownStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
1048    }
1049    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
1050    {
1051      /* not done with configuring routing
1052         1. set the timer
1053         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
1054      */
1055      DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
1056      DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
1057      dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1058      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
1059    }
1060    else
1061    {
1062      /* nothing */
1063    }
1064  }
1065  else
1066  {
1067     DM_DBG1(("dmDiscover2RespRcvd: Discovery Error SMP function return result error=0x%x\n",
1068               frameHeader->smpFunctionResult));
1069     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1070  }
1071  return;
1072}
1073
1074#ifdef NOT_YET
1075osGLOBAL void
1076tdsaDiscoverList2Send(
1077                 tiRoot_t             *tiRoot,
1078                 tdsaDeviceData_t     *oneDeviceData
1079                 )
1080{
1081  agsaRoot_t            *agRoot;
1082  tdsaExpander_t        *oneExpander;
1083  smpReqDiscoverList2_t smpDiscoverListReq;
1084
1085  DM_DBG1(("tdsaDiscoverList2Send: start\n"));
1086  DM_DBG1(("tdsaDiscoverList2Send: device %p did %d\n", oneDeviceData, oneDeviceData->id));
1087  agRoot = oneDeviceData->agRoot;
1088  oneExpander = oneDeviceData->dmExpander;
1089  DM_DBG1(("tdsaDiscoverList2Send: phyID 0x%x\n", oneExpander->discoveringPhyId));
1090
1091
1092  osti_memset(&smpDiscoverListReq, 0, sizeof(smpReqDiscoverList2_t));
1093
1094  smpDiscoverListReq.reserved1 = 0;
1095  smpDiscoverListReq.StartingPhyID = 0;
1096  smpDiscoverListReq.MaxNumDiscoverDesc = 40; /* 40 for SHORT FORMAT; 8 for Long Format; SAS2 p630 */
1097  smpDiscoverListReq.byte10 = 0x2; /* phy filter; all but "no device attached" */
1098  smpDiscoverListReq.byte11 = 0x1; /* descriptor type; SHORT FORMAT */
1099
1100
1101  dmSMPStart(
1102             dmRoot,
1103             agRoot,
1104             oneDeviceData,
1105             SMP_DISCOVER_LIST,
1106             (bit8 *)&smpDiscoverListReq,
1107             sizeof(smpReqDiscoverList2_t),
1108             AGSA_SMP_INIT_REQ,
1109             agNULL
1110             );
1111  return;
1112}
1113
1114osGLOBAL void
1115tdsaDiscoverList2RespRcvd(
1116                     tiRoot_t              *tiRoot,
1117                     agsaRoot_t            *agRoot,
1118                     tdsaDeviceData_t      *oneDeviceData,
1119                     tdssSMPFrameHeader_t  *frameHeader,
1120                     agsaFrameHandle_t     frameHandle
1121                     )
1122{
1123  return;
1124}
1125#endif /* not yet */
1126
1127/*****************************************************************************
1128*! \brief  dmReportPhySataSend
1129*
1130*  Purpose:  This function sends Report Phy SATA to a device.
1131*
1132*  \param   dmRoot: Pointer to the OS Specific module allocated dmRoot_t
1133*                   instance.
1134*  \param   oneDeviceData: Pointer to the device data.
1135*  \param   phyId: Phy Identifier.
1136*
1137*  \return:
1138*           None
1139*
1140*   \note:
1141*
1142*****************************************************************************/
1143osGLOBAL void
1144dmReportPhySataSend(
1145                    dmRoot_t           *dmRoot,
1146                    dmDeviceData_t     *oneDeviceData,
1147                    bit8               phyId
1148                    )
1149{
1150  dmIntRoot_t        *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
1151  dmIntContext_t     *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
1152  agsaRoot_t         *agRoot      = dmAllShared->agRoot;
1153  dmExpander_t       *oneExpander;
1154  smpReqReportPhySata_t  smpReportPhySataReq;
1155
1156  DM_DBG3(("dmReportPhySataSend: start\n"));
1157  DM_DBG3(("dmReportPhySataSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
1158  DM_DBG3(("dmReportPhySataSend: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1159  DM_DBG3(("dmReportPhySataSend: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1160
1161  oneExpander = oneDeviceData->dmExpander;
1162
1163  if (oneExpander == agNULL)
1164  {
1165    DM_DBG1(("dmReportPhySataSend: Error!!! expander is NULL\n"));
1166    return;
1167  }
1168  DM_DBG3(("dmReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
1169  DM_DBG3(("dmReportPhySataSend: phyid %d\n", phyId));
1170
1171  dm_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t));
1172
1173  smpReportPhySataReq.phyIdentifier = phyId;
1174
1175  dmSMPStart(
1176             dmRoot,
1177             agRoot,
1178             oneExpander->dmDevice,
1179             SMP_REPORT_PHY_SATA,
1180             (bit8 *)&smpReportPhySataReq,
1181             sizeof(smpReqReportPhySata_t),
1182             AGSA_SMP_INIT_REQ
1183             );
1184
1185  return;
1186}
1187/*****************************************************************************
1188*! \brief  dmReportPhySataRcvd
1189*
1190*  Purpose:  This function processes Report Phy SATA response.
1191*
1192*  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
1193*                   instance.
1194*  \param   agRoot: Pointer to chip/driver Instance.
1195*  \param   oneDeviceData: Pointer to the device data.
1196*  \param   frameHeader: Pointer to SMP frame header.
1197*  \param   frameHandle: A Handle used to refer to the response frame
1198*
1199*  \return:
1200*           None
1201*
1202*   \note:
1203*
1204*****************************************************************************/
1205
1206osGLOBAL void
1207dmReportPhySataRcvd(
1208                    dmRoot_t              *dmRoot,
1209                    agsaRoot_t            *agRoot,
1210                    agsaIORequest_t       *agIORequest,
1211                    dmDeviceData_t        *oneDeviceData,
1212                    dmSMPFrameHeader_t    *frameHeader,
1213                    agsaFrameHandle_t     frameHandle
1214                   )
1215{
1216  smpRespReportPhySata_t      SMPreportPhySataResp;
1217  smpRespReportPhySata_t      *pSMPReportPhySataResp;
1218  dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
1219  dmIntPortContext_t          *onePortContext = agNULL;
1220  agsaFisRegDeviceToHost_t    *fis;
1221  dmDeviceData_t              *SataDevice = agNULL;
1222#ifndef DIRECT_SMP
1223  dmSMPRequestBody_t          *tdSMPRequestBody;
1224#endif
1225  bit8                        sataDeviceType;
1226  bit8                        *bit8fis;
1227  bit8                        i = 0;
1228  bit32                       a = 0;
1229  bit8                        bit8fisarray[20];
1230
1231  DM_DBG3(("dmReportPhySataRcvd: start\n"));
1232  DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1233  DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1234
1235#ifndef DIRECT_SMP
1236  tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
1237#endif
1238  /* get the current sata device hanlde stored in the expander structure */
1239  if (oneExpander != agNULL)
1240  {
1241      SataDevice = oneExpander->dmDeviceToProcess;
1242  }
1243
1244  if (SataDevice != agNULL)
1245  {
1246    DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
1247    DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
1248  }
1249  else
1250  {
1251    DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
1252  }
1253
1254  pSMPReportPhySataResp = &SMPreportPhySataResp;
1255
1256#ifdef DIRECT_SMP
1257  saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1258#else
1259  saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1260#endif
1261
1262  /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
1263
1264#ifndef DIRECT_SMP
1265  ostiFreeMemory(
1266                 dmRoot,
1267                 tdSMPRequestBody->IndirectSMPReqosMemHandle,
1268                 tdSMPRequestBody->IndirectSMPReqLen
1269                );
1270  ostiFreeMemory(
1271                 dmRoot,
1272                 tdSMPRequestBody->IndirectSMPResposMemHandle,
1273                 tdSMPRequestBody->IndirectSMPRespLen
1274                );
1275#endif
1276
1277  onePortContext = oneDeviceData->dmPortContext;
1278
1279  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1280  {
1281    DM_DBG1(("dmReportPhySataRcvd: invalid port or aborted discovery!!!\n"));
1282    return;
1283  }
1284
1285  if (SataDevice == agNULL)
1286  {
1287    DM_DBG1(("dmReportPhySataRcvd: SataDevice is NULL, wrong\n"));
1288    dmDiscoverAbort(dmRoot, onePortContext);
1289    return;
1290  }
1291
1292  if (frameHeader->smpFunctionResult == PHY_VACANT )
1293  {
1294     DM_DBG1(("dmReportPhySataRcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
1295     return;
1296  }
1297
1298  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED  )
1299  {
1300    fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
1301    if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
1302    {
1303      /* save signature */
1304      DM_DBG3(("dmReportPhySataRcvd: saves the signature\n"));
1305      /* saves signature */
1306      SataDevice->satSignature[0] = fis->d.sectorCount;
1307      SataDevice->satSignature[1] = fis->d.lbaLow;
1308      SataDevice->satSignature[2] = fis->d.lbaMid;
1309      SataDevice->satSignature[3] = fis->d.lbaHigh;
1310      SataDevice->satSignature[4] = fis->d.device;
1311      SataDevice->satSignature[5] = 0;
1312      SataDevice->satSignature[6] = 0;
1313      SataDevice->satSignature[7] = 0;
1314
1315      DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1316       SataDevice->satSignature[0],
1317       SataDevice->satSignature[1],
1318       SataDevice->satSignature[2],
1319       SataDevice->satSignature[3],
1320       SataDevice->satSignature[4]));
1321
1322       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1323       if( sataDeviceType == SATA_ATAPI_DEVICE)
1324       {
1325          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1326       }
1327       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1328    }
1329    /* Handling DataDomain buggy FIS */
1330    else if (fis->h.error == REG_DEV_TO_HOST_FIS)
1331    {
1332      /* needs to flip fis to host order */
1333      bit8fis = (bit8*)fis;
1334      for (i=0;i<5;i++)
1335      {
1336        a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
1337        DM_DBG3(("dmReportPhySataRcvd: a 0x%8x\n", a));
1338        bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
1339        bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
1340        bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
1341        bit8fisarray[4*i+3] = (a & 0x000000FF);
1342        bit8fis = bit8fis + 4;
1343      }
1344      fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
1345      /* save signature */
1346      DM_DBG3(("dmReportPhySataRcvd: DataDomain ATAPI saves the signature\n"));
1347      /* saves signature */
1348      SataDevice->satSignature[0] = fis->d.sectorCount;
1349      SataDevice->satSignature[1] = fis->d.lbaLow;
1350      SataDevice->satSignature[2] = fis->d.lbaMid;
1351      SataDevice->satSignature[3] = fis->d.lbaHigh;
1352      SataDevice->satSignature[4] = fis->d.device;
1353      SataDevice->satSignature[5] = 0;
1354      SataDevice->satSignature[6] = 0;
1355      SataDevice->satSignature[7] = 0;
1356
1357      DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1358       SataDevice->satSignature[0],
1359       SataDevice->satSignature[1],
1360       SataDevice->satSignature[2],
1361       SataDevice->satSignature[3],
1362       SataDevice->satSignature[4]));
1363
1364       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1365       if( sataDeviceType == SATA_ATAPI_DEVICE)
1366       {
1367          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1368       }
1369       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1370    }
1371    else
1372    {
1373      DM_DBG3(("dmReportPhySataRcvd: getting next stp bride\n"));
1374    }
1375
1376    /* Continure to report this STP device to TD*/
1377    if (SataDevice->ExpDevice != agNULL)
1378    {
1379       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
1380    }
1381    else
1382    {
1383       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
1384    }
1385  }
1386  else
1387  {
1388    DM_DBG3(("dmReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n",
1389             frameHeader->smpFunctionResult));
1390    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1391  }
1392
1393  return;
1394}
1395
1396/*****************************************************************************
1397*! \brief  dmReportPhySata2Rcvd
1398*
1399*  Purpose:  This function processes SAS2.0 Report Phy SATA response.
1400*
1401*  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
1402*                   instance.
1403*  \param   agRoot: Pointer to chip/driver Instance.
1404*  \param   oneDeviceData: Pointer to the device data.
1405*  \param   frameHeader: Pointer to SMP frame header.
1406*  \param   frameHandle: A Handle used to refer to the response frame
1407*
1408*  \return:
1409*           None
1410*
1411*   \note:
1412*
1413*****************************************************************************/
1414osGLOBAL void
1415dmReportPhySata2Rcvd(
1416                    dmRoot_t              *dmRoot,
1417                    agsaRoot_t            *agRoot,
1418                    agsaIORequest_t       *agIORequest,
1419                    dmDeviceData_t        *oneDeviceData,
1420                    dmSMPFrameHeader_t    *frameHeader,
1421                    agsaFrameHandle_t     frameHandle
1422                   )
1423{
1424   smpRespReportPhySata2_t      SMPreportPhySataResp;
1425   smpRespReportPhySata2_t      *pSMPReportPhySataResp;
1426   dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
1427   dmIntPortContext_t          *onePortContext = agNULL;
1428   agsaFisRegDeviceToHost_t    *fis;
1429   dmDeviceData_t              *SataDevice = agNULL;
1430#ifndef DIRECT_SMP
1431   dmSMPRequestBody_t          *tdSMPRequestBody;
1432#endif
1433   bit8                         sataDeviceType = 0;
1434   bit8                        *bit8fis;
1435   bit8                        i = 0;
1436   bit32                       a = 0;
1437   bit8                        bit8fisarray[20];
1438
1439   DM_DBG3(("dmReportPhySata2Rcvd: start\n"));
1440   DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1441   DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1442
1443#ifndef DIRECT_SMP
1444   tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
1445#endif
1446   /* get the current sata device hanlde stored in the expander structure */
1447   if (oneExpander != agNULL)
1448   {
1449     SataDevice = oneExpander->dmDeviceToProcess;
1450   }
1451
1452   if (SataDevice != agNULL)
1453   {
1454     DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
1455     DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
1456   }
1457   else
1458   {
1459     DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
1460   }
1461
1462  pSMPReportPhySataResp = &SMPreportPhySataResp;
1463
1464#ifdef DIRECT_SMP
1465   saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1466#else
1467   saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1468#endif
1469
1470   /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
1471
1472#ifndef DIRECT_SMP
1473   ostiFreeMemory(
1474                  dmRoot,
1475                  tdSMPRequestBody->IndirectSMPReqosMemHandle,
1476                  tdSMPRequestBody->IndirectSMPReqLen
1477                 );
1478   ostiFreeMemory(
1479                  dmRoot,
1480                  tdSMPRequestBody->IndirectSMPResposMemHandle,
1481                  tdSMPRequestBody->IndirectSMPRespLen
1482                 );
1483#endif
1484
1485   onePortContext = oneDeviceData->dmPortContext;
1486
1487   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1488   {
1489     DM_DBG1(("dmReportPhySata2Rcvd: invalid port or aborted discovery!!!\n"));
1490     return;
1491   }
1492
1493   if (SataDevice == agNULL)
1494   {
1495     DM_DBG1(("dmReportPhySata2Rcvd: SataDevice is NULL, wrong\n"));
1496     dmDiscoverAbort(dmRoot, onePortContext);
1497     return;
1498   }
1499
1500   if ( frameHeader->smpFunctionResult == PHY_VACANT )
1501   {
1502      DM_DBG1(("dmReportPhySata2Rcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
1503      return;
1504   }
1505
1506   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
1507   {
1508     fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
1509     if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
1510     {
1511       /* save signature */
1512       DM_DBG3(("dmReportPhySata2Rcvd: saves the signature\n"));
1513       /* saves signature */
1514       SataDevice->satSignature[0] = fis->d.sectorCount;
1515       SataDevice->satSignature[1] = fis->d.lbaLow;
1516       SataDevice->satSignature[2] = fis->d.lbaMid;
1517       SataDevice->satSignature[3] = fis->d.lbaHigh;
1518       SataDevice->satSignature[4] = fis->d.device;
1519       SataDevice->satSignature[5] = 0;
1520       SataDevice->satSignature[6] = 0;
1521       SataDevice->satSignature[7] = 0;
1522       DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1523        SataDevice->satSignature[0],
1524        SataDevice->satSignature[1],
1525        SataDevice->satSignature[2],
1526        SataDevice->satSignature[3],
1527        SataDevice->satSignature[4]));
1528       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1529       if( sataDeviceType == SATA_ATAPI_DEVICE)
1530       {
1531          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1532       }
1533       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1534    }
1535    /* Handling DataDomain buggy FIS */
1536    else if (fis->h.error == REG_DEV_TO_HOST_FIS)
1537    {
1538      /* needs to flip fis to host order */
1539      bit8fis = (bit8*)fis;
1540      for (i=0;i<5;i++)
1541      {
1542        a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
1543        DM_DBG3(("dmReportPhySata2Rcvd: a 0x%8x\n", a));
1544        bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
1545        bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
1546        bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
1547        bit8fisarray[4*i+3] = (a & 0x000000FF);
1548        bit8fis = bit8fis + 4;
1549      }
1550      fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
1551      /* save signature */
1552      DM_DBG3(("dmReportPhySata2Rcvd: DataDomain ATAPI saves the signature\n"));
1553      /* saves signature */
1554      SataDevice->satSignature[0] = fis->d.sectorCount;
1555      SataDevice->satSignature[1] = fis->d.lbaLow;
1556      SataDevice->satSignature[2] = fis->d.lbaMid;
1557      SataDevice->satSignature[3] = fis->d.lbaHigh;
1558      SataDevice->satSignature[4] = fis->d.device;
1559      SataDevice->satSignature[5] = 0;
1560      SataDevice->satSignature[6] = 0;
1561      SataDevice->satSignature[7] = 0;
1562      DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1563       SataDevice->satSignature[0],
1564       SataDevice->satSignature[1],
1565       SataDevice->satSignature[2],
1566       SataDevice->satSignature[3],
1567       SataDevice->satSignature[4]));
1568
1569       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1570       if( sataDeviceType == SATA_ATAPI_DEVICE)
1571       {
1572          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1573       }
1574       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1575    }
1576    else
1577    {
1578      DM_DBG3(("dmReportPhySata2Rcvd: getting next stp bride\n"));
1579    }
1580
1581    /* Continue to report this STP device to TD*/
1582    if (SataDevice->ExpDevice != agNULL)
1583    {
1584       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
1585    }
1586    else
1587    {
1588       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
1589    }
1590
1591   }
1592   else
1593   {
1594     DM_DBG3(("dmReportPhySata2Rcvd: siReportPhySataRcvd SMP function return result %x\n",
1595              frameHeader->smpFunctionResult));
1596     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1597   }
1598
1599   return;
1600}
1601
1602
1603
1604osGLOBAL bit32
1605dmRoutingEntryAdd(
1606                  dmRoot_t          *dmRoot,
1607                  dmExpander_t      *oneExpander,
1608                  bit32             phyId,
1609                  bit32             configSASAddressHi,
1610                  bit32             configSASAddressLo
1611                 )
1612{
1613  dmIntRoot_t                             *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
1614  dmIntContext_t                          *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
1615  agsaRoot_t                              *agRoot = dmAllShared->agRoot;
1616  bit32                                   ret = agTRUE;
1617  dmIntPortContext_t                      *onePortContext;
1618  smpReqConfigureRouteInformation_t       confRoutingInfo;
1619  bit32                                   i;
1620
1621  DM_DBG3(("dmRoutingEntryAdd: start\n"));
1622  DM_DBG3(("dmRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1623  DM_DBG3(("dmRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1624  DM_DBG3(("dmRoutingEntryAdd: phyid %d\n", phyId));
1625
1626  if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
1627      oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo
1628     )
1629  {
1630    DM_DBG3(("dmRoutingEntryAdd: unnecessary\n"));
1631    return ret;
1632  }
1633  if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE)
1634  {
1635    DM_DBG3(("dmRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId]));
1636    return ret;
1637  }
1638
1639  onePortContext = oneExpander->dmDevice->dmPortContext;
1640
1641  onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING;
1642
1643  /* reset smpReqConfigureRouteInformation_t */
1644  dm_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t));
1645  if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex )
1646  {
1647    DM_DBG3(("dmRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi));
1648    DM_DBG3(("dmRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo));
1649    DM_DBG3(("dmRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId]));
1650
1651    oneExpander->configSASAddressHi = configSASAddressHi;
1652    oneExpander->configSASAddressLo = configSASAddressLo;
1653    confRoutingInfo.reserved1[0] = 0;
1654    confRoutingInfo.reserved1[1] = 0;
1655    OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId]));
1656    confRoutingInfo.reserved2 = 0;
1657    confRoutingInfo.phyIdentifier = (bit8)phyId;
1658    confRoutingInfo.reserved3[0] = 0;
1659    confRoutingInfo.reserved3[1] = 0;
1660    confRoutingInfo.disabledBit_reserved4 = 0;
1661    confRoutingInfo.reserved5[0] = 0;
1662    confRoutingInfo.reserved5[1] = 0;
1663    confRoutingInfo.reserved5[2] = 0;
1664    OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi);
1665    OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo);
1666    for ( i = 0; i < 16; i ++ )
1667    {
1668      confRoutingInfo.reserved6[i] = 0;
1669    }
1670    dmSMPStart(dmRoot, agRoot, oneExpander->dmDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ);
1671
1672    oneExpander->currentIndex[phyId] ++;
1673  }
1674  else
1675  {
1676    DM_DBG3(("dmRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex));
1677    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1678
1679    ret = agFALSE;
1680  }
1681  return ret;
1682}
1683
1684
1685osGLOBAL void
1686dmConfigRoutingInfoRespRcvd(
1687                            dmRoot_t              *dmRoot,
1688                            agsaRoot_t            *agRoot,
1689                            agsaIORequest_t       *agIORequest,
1690                            dmDeviceData_t        *oneDeviceData,
1691                            dmSMPFrameHeader_t    *frameHeader,
1692                            agsaFrameHandle_t     frameHandle
1693                           )
1694{
1695  dmIntPortContext_t                    *onePortContext;
1696  dmExpander_t                          *oneExpander = oneDeviceData->dmExpander;
1697  dmExpander_t                          *UpStreamExpander;
1698  dmExpander_t                          *DownStreamExpander;
1699  dmExpander_t                          *ReturningExpander;
1700  dmExpander_t                          *ConfigurableExpander;
1701  dmDeviceData_t                        *ReturningExpanderDeviceData = agNULL;
1702  bit32                                 dupConfigSASAddr = agFALSE;
1703
1704
1705  DM_DBG3(("dmConfigRoutingInfoRespRcvd: start\n"));
1706  DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1707  DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1708
1709  onePortContext = oneDeviceData->dmPortContext;
1710
1711  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1712  {
1713    DM_DBG1(("dmConfigRoutingInfoRespRcvd: invalid port or aborted discovery!!!\n"));
1714    return;
1715  }
1716
1717  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
1718       frameHeader->smpFunctionResult == PHY_VACANT
1719     )
1720  {
1721    DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
1722    if (DownStreamExpander != agNULL)
1723    {
1724      DownStreamExpander->currentUpStreamPhyIndex ++;
1725      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1726      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
1727      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1728      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1729
1730    }
1731
1732    oneExpander->currentDownStreamPhyIndex++;
1733    DM_DBG3(("dmConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
1734
1735    if ( (DownStreamExpander != agNULL) &&
1736         (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
1737       )
1738    {
1739      DM_DBG3(("dmConfigRoutingInfoRespRcvd: first if\n"));
1740      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1741
1742      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
1743
1744      dmRoutingEntryAdd(dmRoot,
1745                           oneExpander,
1746                           DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
1747                           oneExpander->configSASAddressHi,
1748                           oneExpander->configSASAddressLo
1749                          );
1750    }
1751    else
1752    {
1753      /* traversing up till discovery Root onePortContext->discovery.RootExp */
1754      DM_DBG3(("dmConfigRoutingInfoRespRcvd: else\n"));
1755
1756      UpStreamExpander = oneExpander->dmUpStreamExpander;
1757      ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
1758      if (UpStreamExpander != agNULL)
1759      {
1760        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1761        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1762      }
1763      else
1764      {
1765        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n"));
1766      }
1767      dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
1768                                                  ConfigurableExpander,
1769                                                  oneExpander->configSASAddressHi,
1770                                                  oneExpander->configSASAddressLo
1771                                                  );
1772
1773      if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
1774      {
1775        DM_DBG3(("dmConfigRoutingInfoRespRcvd: else if\n"));
1776
1777        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
1778        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
1779
1780        if ( UpStreamExpander != agNULL)
1781        {
1782          UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
1783        }
1784        ConfigurableExpander->currentDownStreamPhyIndex =
1785                dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
1786        ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
1787        if ( DownStreamExpander != agNULL)
1788        {
1789          DownStreamExpander->currentUpStreamPhyIndex = 0;
1790        }
1791        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
1792
1793        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
1794        dmRoutingEntryAdd(dmRoot,
1795                             ConfigurableExpander,
1796                             ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
1797                             oneExpander->configSASAddressHi,
1798                             oneExpander->configSASAddressLo
1799                            );
1800      }
1801      else
1802      {
1803        /* going back to where it was */
1804        /* ConfigRoutingInfo is done for a target */
1805        DM_DBG3(("dmConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n"));
1806        ReturningExpander = oneExpander->dmReturnginExpander;
1807        if ( DownStreamExpander != agNULL)
1808        {
1809          DownStreamExpander->currentUpStreamPhyIndex = 0;
1810        }
1811        /* debugging */
1812        if (ReturningExpander != agNULL)
1813        {
1814          DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
1815          DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
1816          ReturningExpanderDeviceData = ReturningExpander->dmDevice;
1817        }
1818
1819        /* No longer in DISCOVERY_CONFIG_ROUTING */
1820        onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
1821
1822        if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
1823        {
1824      /* If not the last phy */
1825          if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
1826          {
1827            DM_DBG3(("dmConfigRoutingInfoRespRcvd: More Phys to discover\n"));
1828            /* continue discovery for the next phy */
1829            /* needs to send only one Discovery not multiple times */
1830            if (ReturningExpander->discoverSMPAllowed == agTRUE)
1831            {
1832              dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
1833            }
1834            if (ReturningExpander != agNULL)
1835            {
1836              ReturningExpander->discoverSMPAllowed = agFALSE;
1837            }
1838          }
1839          /* If the last phy */
1840          else
1841          {
1842            DM_DBG3(("dmConfigRoutingInfoRespRcvd: No More Phys\n"));
1843            ReturningExpander->discoverSMPAllowed = agTRUE;
1844
1845            /* remove the expander from the discovering list */
1846            dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
1847            /* continue downstream discovering */
1848            dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
1849
1850            //DownStreamExpander
1851          }
1852    }
1853      }
1854    }
1855  }
1856  else
1857  {
1858    DM_DBG1(("dmConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n", frameHeader->smpFunctionResult));
1859    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1860  }
1861  return;
1862}
1863
1864osGLOBAL void
1865dmConfigRoutingInfo2RespRcvd(
1866                            dmRoot_t              *dmRoot,
1867                            agsaRoot_t            *agRoot,
1868                            agsaIORequest_t       *agIORequest,
1869                            dmDeviceData_t        *oneDeviceData,
1870                            dmSMPFrameHeader_t    *frameHeader,
1871                            agsaFrameHandle_t     frameHandle
1872                           )
1873{
1874  dmExpander_t                            *oneExpander = oneDeviceData->dmExpander;
1875  dmExpander_t                            *UpStreamExpander;
1876  dmExpander_t                            *DownStreamExpander;
1877  dmExpander_t                            *ReturningExpander;
1878  dmExpander_t                            *ConfigurableExpander;
1879
1880  dmIntPortContext_t                      *onePortContext;
1881  dmDeviceData_t                          *ReturningExpanderDeviceData = agNULL;
1882  bit32                                   dupConfigSASAddr = agFALSE;
1883
1884  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: start\n"));
1885  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1886  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1887
1888  onePortContext = oneDeviceData->dmPortContext;
1889
1890  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1891  {
1892    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: invalid port or aborted discovery!!!\n"));
1893    return;
1894  }
1895
1896  if (frameHeader->smpFunctionResult == PHY_VACANT)
1897  {
1898    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: smpFunctionResult is PHY_VACANT\n"));
1899  }
1900
1901  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
1902       frameHeader->smpFunctionResult == PHY_VACANT
1903     )
1904  {
1905    DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
1906    if (DownStreamExpander != agNULL)
1907    {
1908      DownStreamExpander->currentUpStreamPhyIndex ++;
1909      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1910      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
1911      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1912      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1913
1914    }
1915
1916    oneExpander->currentDownStreamPhyIndex++;
1917    DM_DBG2(("dmConfigRoutingInfo2RespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
1918
1919    if ( (DownStreamExpander != agNULL) &&
1920         (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
1921       )
1922    {
1923      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: first if\n"));
1924      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1925
1926      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
1927
1928      dmRoutingEntryAdd(dmRoot,
1929                        oneExpander,
1930                        DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
1931                        oneExpander->configSASAddressHi,
1932                        oneExpander->configSASAddressLo
1933                       );
1934    }
1935    else
1936    {
1937      /* traversing up till discovery Root onePortContext->discovery.RootExp */
1938      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else\n"));
1939
1940      UpStreamExpander = oneExpander->dmUpStreamExpander;
1941      ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
1942      if (UpStreamExpander != agNULL)
1943      {
1944        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1945        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1946      }
1947      else
1948      {
1949        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander is NULL\n"));
1950      }
1951      dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
1952                                                  ConfigurableExpander,
1953                                                  oneExpander->configSASAddressHi,
1954                                                  oneExpander->configSASAddressLo
1955                                                  );
1956
1957      if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
1958      {
1959        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else if\n"));
1960
1961        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
1962        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
1963
1964        if ( UpStreamExpander != agNULL)
1965        {
1966    UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
1967        }
1968        ConfigurableExpander->currentDownStreamPhyIndex =
1969                dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
1970        ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
1971        if ( DownStreamExpander != agNULL)
1972        {
1973          DownStreamExpander->currentUpStreamPhyIndex = 0;
1974        }
1975        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
1976
1977        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
1978        dmRoutingEntryAdd(dmRoot,
1979                          ConfigurableExpander,
1980                          ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
1981                          oneExpander->configSASAddressHi,
1982                          oneExpander->configSASAddressLo
1983                         );
1984      }
1985      else
1986      {
1987        /* going back to where it was */
1988        /* ConfigRoutingInfo is done for a target */
1989        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: $$$$$$ my change $$$$$ \n"));
1990        ReturningExpander = oneExpander->dmReturnginExpander;
1991        if ( DownStreamExpander != agNULL)
1992        {
1993          DownStreamExpander->currentUpStreamPhyIndex = 0;
1994        }
1995        /* debugging */
1996        if (ReturningExpander != agNULL)
1997        {
1998           DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
1999           DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
2000           ReturningExpanderDeviceData = ReturningExpander->dmDevice;
2001        }
2002
2003        /* No longer in DISCOVERY_CONFIG_ROUTING */
2004        onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
2005
2006        if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
2007        {
2008      /* If not the last phy */
2009          if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
2010          {
2011            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: More Phys to discover\n"));
2012            /* continue discovery for the next phy */
2013            /* needs to send only one Discovery not multiple times */
2014            if (ReturningExpander->discoverSMPAllowed == agTRUE)
2015            {
2016              dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
2017            }
2018            if (ReturningExpander != agNULL)
2019            {
2020              ReturningExpander->discoverSMPAllowed = agFALSE;
2021            }
2022          }
2023          /* If the last phy */
2024          else
2025          {
2026            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: No More Phys\n"));
2027            ReturningExpander->discoverSMPAllowed = agTRUE;
2028
2029            /* remove the expander from the discovering list */
2030            dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
2031            /* continue downstream discovering */
2032            dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
2033
2034            //DownStreamExpander
2035          }
2036        }
2037      }
2038    }
2039  }
2040  else
2041  {
2042    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: Discovery Error SMP function return result error=0x%x!!!\n", frameHeader->smpFunctionResult));
2043    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2044  }
2045  return;
2046}
2047
2048
2049/* no task management case here for phyControl*/
2050
2051/* no task management case here for phyControl*/
2052osGLOBAL void
2053dmPhyControlRespRcvd(
2054                     dmRoot_t              *dmRoot,
2055                     agsaRoot_t            *agRoot,
2056                     agsaIORequest_t       *agIORequest,
2057                     dmDeviceData_t        *oneDeviceData,
2058                     dmSMPFrameHeader_t    *frameHeader,
2059                     agsaFrameHandle_t     frameHandle
2060                    )
2061{
2062  DM_DBG3(("dmPhyControlRespRcvd: start\n"));
2063  DM_DBG3(("dmPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2064  DM_DBG3(("dmPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2065
2066  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2067  {
2068    DM_DBG3(("dmPhyControlRespRcvd: SMP success\n"));
2069  }
2070  else
2071  {
2072    DM_DBG1(("dmPhyControlRespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
2073  }
2074
2075  return;
2076}
2077
2078/* no task management case here for phyControl*/
2079osGLOBAL void
2080dmPhyControl2RespRcvd(
2081                     dmRoot_t              *dmRoot,
2082                     agsaRoot_t            *agRoot,
2083                     agsaIORequest_t       *agIORequest,
2084                     dmDeviceData_t        *oneDeviceData,
2085                     dmSMPFrameHeader_t    *frameHeader,
2086                     agsaFrameHandle_t     frameHandle
2087                    )
2088{
2089  DM_DBG2(("dmPhyControl2RespRcvd: start\n"));
2090  DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2091  DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2092
2093  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2094  {
2095    DM_DBG2(("dmPhyControl2RespRcvd: SMP success\n"));
2096  }
2097  else
2098  {
2099    DM_DBG1(("dmPhyControl2RespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
2100  }
2101
2102  return;
2103}
2104
2105osGLOBAL void
2106dmPhyControlFailureRespRcvd(
2107                            dmRoot_t              *dmRoot,
2108                            agsaRoot_t            *agRoot,
2109                            dmDeviceData_t        *oneDeviceData,
2110                            dmSMPFrameHeader_t    *frameHeader,
2111                            agsaFrameHandle_t     frameHandle
2112                           )
2113{
2114  DM_DBG1(("dmPhyControlFailureRespRcvd: start\n"));
2115  return;
2116}
2117
2118GLOBAL void dmSetDeviceInfoCB(
2119                                agsaRoot_t        *agRoot,
2120                                agsaContext_t     *agContext,
2121                                agsaDevHandle_t   *agDevHandle,
2122                                bit32             status,
2123                                bit32             option,
2124                                bit32             param
2125                                )
2126{
2127  dmRoot_t                  *dmRoot = agNULL;
2128  agsaIORequest_t           *agIORequest;
2129  bit32                     smstatus;
2130  agsaSASRequestBody_t      *agSASRequestBody;
2131  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
2132  dmIntPortContext_t        *onePortContext = agNULL;
2133  dmDeviceData_t            *oneDeviceData;
2134  bit8                      SMPRequestFunction;
2135  bit8                      devType_S_Rate;
2136  DM_DBG1(("dmSetDeviceInfoCB: start\n"));
2137  DM_DBG4(("dmSetDeviceInfoCB: status 0x%x\n", status));
2138  DM_DBG4(("dmSetDeviceInfoCB: option 0x%x\n", option));
2139  DM_DBG4(("dmSetDeviceInfoCB: param 0x%x\n", param));
2140  if (status != OSSA_SUCCESS)
2141  {
2142    DM_DBG1(("dmSetDeviceInfoCB: status %d\n", status));
2143    DM_DBG1(("dmSetDeviceInfoCB: option 0x%x\n", option));
2144    DM_DBG1(("dmSetDeviceInfoCB: param 0x%x\n", param));
2145    if (option == 32) /* set connection rate */
2146    {
2147      DM_DBG1(("dmSetDeviceInfoCB: IO failure\n"));
2148      agIORequest = (agsaIORequest_t *)agContext->osData;
2149      dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2150      dmRoot = dmSMPRequestBody->dmRoot;
2151      oneDeviceData = dmSMPRequestBody->dmDevice;
2152      onePortContext = oneDeviceData->dmPortContext;
2153      SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2154      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2155          SMPRequestFunction == SMP_DISCOVER ||
2156          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2157          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2158        )
2159      {
2160        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2161      }
2162      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2163      {
2164        /* task management failure */
2165        dmPhyControlFailureRespRcvd(
2166                                    dmRoot,
2167                                    agRoot,
2168                                    oneDeviceData,
2169                                    agNULL,
2170                                    agNULL
2171                                   );
2172      }
2173    }
2174  }
2175  if (agDevHandle == agNULL)
2176  {
2177    DM_DBG1(("dmSetDeviceInfoCB: agDevHandle is NULL\n"));
2178    return;
2179  }
2180
2181  /* retry SMP */
2182  if (option == 32) /* set connection rate */
2183  {
2184    DM_DBG1(("dmSetDeviceInfoCB: set connection rate option\n"));
2185    agIORequest = (agsaIORequest_t *)agContext->osData;
2186    dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2187    dmRoot = dmSMPRequestBody->dmRoot;
2188    agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
2189    oneDeviceData = dmSMPRequestBody->dmDevice;
2190    onePortContext = oneDeviceData->dmPortContext;
2191    devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
2192    devType_S_Rate = (devType_S_Rate & 0xF0) | (param >> 28);
2193    oneDeviceData->agDeviceInfo.devType_S_Rate =  devType_S_Rate;
2194    SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2195    DM_DBG1(("dmSetDeviceInfoCB: SMPRequestFunction 0x%x\n", SMPRequestFunction));
2196    DM_DBG1(("dmSetDeviceInfoCB: new rate is 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo)));
2197    smstatus = saSMPStart(
2198                          agRoot,
2199                          agIORequest,
2200                          0,
2201                          agDevHandle,
2202                          AGSA_SMP_INIT_REQ,
2203                          agSASRequestBody,
2204                          &dmsaSMPCompleted
2205                         );
2206    if (status == AGSA_RC_SUCCESS)
2207    {
2208      /* increment the number of pending SMP */
2209      onePortContext->discovery.pendingSMP++;
2210//          dmSMPRequestBody->retries++;
2211      if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2212          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2213          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2214         )
2215      {
2216        /* start discovery-related SMP timer */
2217        dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)SMPRequestFunction, dmSMPRequestBody);
2218      }
2219      return;
2220    }
2221    else if (status == AGSA_RC_BUSY)
2222    {
2223      onePortContext->discovery.pendingSMP++;
2224//          dmSMPRequestBody->retries++;
2225      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2226          SMPRequestFunction == SMP_DISCOVER ||
2227          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2228          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2229         )
2230      {
2231        dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
2232      }
2233      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2234      {
2235        /* For taskmanagement SMP, let's fail task management failure */
2236        dmPhyControlFailureRespRcvd(
2237                                    dmRoot,
2238                                    agRoot,
2239                                    oneDeviceData,
2240                                    agNULL,
2241                                    agNULL
2242                                   );
2243      }
2244      else
2245      {
2246      }
2247    }
2248    else /* AGSA_RC_FAILURE */
2249    {
2250      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2251          SMPRequestFunction == SMP_DISCOVER ||
2252          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2253          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2254         )
2255      {
2256        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2257      }
2258      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2259      {
2260        /* task management failure */
2261        dmPhyControlFailureRespRcvd(
2262                                    dmRoot,
2263                                    agRoot,
2264                                    oneDeviceData,
2265                                    agNULL,
2266                                    agNULL
2267                                   );
2268      }
2269      else
2270      {
2271      }
2272    }
2273  }
2274  return;
2275}
2276/* smp completion */
2277osGLOBAL void
2278dmSMPCompleted(
2279               agsaRoot_t            *agRoot,
2280               agsaIORequest_t       *agIORequest,
2281               bit32                 agIOStatus,
2282               bit32                 agIOInfoLen,
2283               agsaFrameHandle_t     agFrameHandle
2284              )
2285{
2286  dmIntRoot_t               *dmIntRoot    = agNULL;
2287  dmIntContext_t            *dmAllShared = agNULL;
2288  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
2289  agsaSMPFrame_t            *agSMPFrame;
2290  dmRoot_t                  *dmRoot = agNULL;
2291  dmIntPortContext_t        *onePortContext = agNULL;
2292  dmIntPortContext_t        *oldonePortContext;
2293  dmExpander_t              *oneExpander = agNULL;
2294  dmDeviceData_t            *oneDeviceData;
2295  agsaDevHandle_t           *agDevHandle = agNULL;
2296  agsaSASRequestBody_t      *agSASRequestBody;
2297  bit8                      smpHeader[4];
2298  bit8                      SMPRequestFunction;
2299  dmSMPFrameHeader_t        *dmResponseSMPFrameHeader;
2300  dmSMPFrameHeader_t        *dmSMPFrameHeader;
2301  bit8                      *dmSMPPayload;
2302  smpReqPhyControl_t        *smpPhyControlReq;
2303  smpReqPhyControl2_t       *smpPhyControl2Req;
2304#ifndef DIRECT_SMP
2305  dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
2306  dmSMPFrameHeader_t        *dmRequestSMPFrameHeader;
2307  bit8                      smpRequestHeader[4];
2308#endif
2309  bit32                     status;
2310  bit32                     ConnRate = SAS_CONNECTION_RATE_12_0G;
2311  agsaContext_t             *agContext = agNULL;
2312
2313  DM_DBG3(("dmSMPCompleted: start\n"));
2314
2315  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2316
2317  dmRoot = dmSMPRequestBody->dmRoot;
2318  dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
2319  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
2320
2321  oneDeviceData = dmSMPRequestBody->dmDevice;
2322  agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
2323  agSMPFrame = &(agSASRequestBody->smpFrame);
2324
2325  if (oneDeviceData->valid == agFALSE &&
2326      oneDeviceData->valid2 == agFALSE &&
2327      oneDeviceData->dmPortContext == agNULL &&
2328      dmSMPRequestBody->dmPortContext->valid == agFALSE
2329      )
2330  {
2331    DM_DBG3(("dmSMPCompleted: port has been destroyed\n"));
2332    /* all device, port information have been reset
2333       just put smp to freeList
2334    */
2335    /* SMP request */
2336    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2337    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2338    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2339
2340#ifndef DIRECT_SMP
2341    /* SMP response */
2342    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2343    if (dmSMPResponseBody == agNULL)
2344    {
2345      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2346      return;
2347    }
2348    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2349    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2350    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2351#endif
2352    return;
2353  }
2354
2355  onePortContext = oneDeviceData->dmPortContext;
2356  oneExpander = oneDeviceData->dmExpander;
2357  agDevHandle = oneExpander->agDevHandle;
2358
2359
2360#ifdef DIRECT_SMP
2361  SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2362#else
2363  saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpRequestHeader, 4);
2364  dmRequestSMPFrameHeader = (dmSMPFrameHeader_t *)smpRequestHeader;
2365  SMPRequestFunction = dmRequestSMPFrameHeader->smpFunction;
2366#endif
2367
2368#ifdef NOT_IN_USE
2369  /* for debugging; dump SMP request payload */
2370  dmhexdump("smp payload",
2371            (bit8 *)agSASRequestBody->smpFrame.outFrameBuf,
2372            agSASRequestBody->smpFrame.outFrameLen
2373           );
2374  dmhexdump("smp payload new",
2375            (bit8 *)dmSMPRequestBody->smpPayload,
2376            agSASRequestBody->smpFrame.outFrameLen
2377           );
2378#endif
2379
2380  /* sanity check */
2381  if (onePortContext != agNULL)
2382  {
2383    DM_DBG5(("dmSMPCompleted: pid %d\n", onePortContext->id));
2384  }
2385  else
2386  {
2387    DM_DBG1(("dmSMPCompleted: Wrong, onePortContext is NULL!!!\n"));
2388    /* SMP request */
2389    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2390    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2391    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2392
2393#ifndef DIRECT_SMP
2394    /* SMP response */
2395    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2396    if (dmSMPResponseBody == agNULL)
2397    {
2398      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2399      return;
2400    }
2401    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2402    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2403    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2404#endif
2405    return;
2406  }
2407
2408  oldonePortContext = dmSMPRequestBody->dmPortContext;
2409  if (oldonePortContext != agNULL)
2410  {
2411    DM_DBG5(("dmSMPCompleted: old pid %d\n", oldonePortContext->id));
2412  }
2413  else
2414  {
2415    DM_DBG1(("dmSMPCompleted: Wrong, oldonePortContext is NULL!!!\n"));
2416    /* SMP request */
2417    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2418    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2419    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2420
2421#ifndef DIRECT_SMP
2422    /* SMP response */
2423    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2424    if (dmSMPResponseBody == agNULL)
2425    {
2426      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2427      return;
2428    }
2429    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2430    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2431    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2432#endif
2433    return;
2434  }
2435
2436  /* decrement the number of pending SMP */
2437  onePortContext->discovery.pendingSMP--;
2438
2439
2440  /* for port invalid case;
2441     full discovery -> full discovery; incremental discovery -> full discovery
2442   */
2443  if (onePortContext != oldonePortContext)
2444  {
2445    DM_DBG1(("dmSMPCompleted: portcontext has changed!!!\n"));
2446    if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2447        SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2448        SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2449        )
2450    {
2451      /* stop SMP timer */
2452      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2453      if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2454      {
2455        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2456        dmKillTimer(
2457                      dmRoot,
2458                      &(onePortContext->discovery.DiscoverySMPTimer)
2459                     );
2460      }
2461      else
2462      {
2463        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2464      }
2465
2466      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2467      if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2468      {
2469        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2470        dmKillTimer(
2471                      dmRoot,
2472                      &(oldonePortContext->discovery.DiscoverySMPTimer)
2473                     );
2474      }
2475      else
2476      {
2477        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2478      }
2479    }
2480    /* clean up expanders data strucures; move to free exp when device is cleaned */
2481    dmCleanAllExp(dmRoot, oldonePortContext);
2482    /* remove devices */
2483    dmInternalRemovals(dmRoot, oldonePortContext);
2484
2485    /* SMP request */
2486    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2487    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2488    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2489
2490#ifndef DIRECT_SMP
2491    /* SMP response */
2492    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2493    if (dmSMPResponseBody == agNULL)
2494    {
2495      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2496      return;
2497    }
2498    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2499    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2500    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2501#endif
2502
2503
2504    return;
2505  }
2506
2507  if (onePortContext->valid == agFALSE ||
2508      onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
2509      onePortContext->discovery.status == DISCOVERY_SAS_DONE  ||
2510      onePortContext->DiscoveryAbortInProgress == agTRUE
2511     )
2512  {
2513    if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2514        SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2515        SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2516        )
2517    {
2518      /* stop SMP timer */
2519      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2520      if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2521      {
2522        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2523        dmKillTimer(
2524                    dmRoot,
2525                    &(onePortContext->discovery.DiscoverySMPTimer)
2526                   );
2527      }
2528      else
2529      {
2530        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2531      }
2532
2533
2534
2535      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2536      if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2537      {
2538        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2539        dmKillTimer(
2540                    dmRoot,
2541                    &(oldonePortContext->discovery.DiscoverySMPTimer)
2542                   );
2543      }
2544      else
2545      {
2546        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2547      }
2548    }
2549
2550    /* SMP request */
2551    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2552    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2553    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2554
2555#ifndef DIRECT_SMP
2556    /* SMP response */
2557    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2558    if (dmSMPResponseBody == agNULL)
2559    {
2560      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2561      return;
2562    }
2563    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2564    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2565    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2566#endif
2567
2568    if (onePortContext->discovery.pendingSMP == 0)
2569    {
2570      DM_DBG1(("dmSMPCompleted: aborting discovery\n"));
2571      if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
2572          onePortContext->discovery.status == DISCOVERY_SAS_DONE ||
2573          onePortContext->DiscoveryAbortInProgress == agTRUE
2574         )
2575      {
2576        onePortContext->DiscoveryAbortInProgress = agFALSE;
2577        onePortContext->DiscoveryState = DM_DSTATE_COMPLETED;
2578        onePortContext->discovery.status = DISCOVERY_SAS_DONE;
2579        dmCleanAllExp(dmRoot, onePortContext);
2580        if ( onePortContext->DiscoveryAbortInProgress == agTRUE)
2581        {
2582          tddmDiscoverCB(
2583                         dmRoot,
2584                         onePortContext->dmPortContext,
2585                         dmDiscAborted
2586                  );
2587        }
2588      }
2589    }
2590    else
2591    {
2592      DM_DBG3(("dmSMPCompleted: not yet abort; non zero pendingSMP %d\n", onePortContext->discovery.pendingSMP));
2593    }
2594    return;
2595  }
2596
2597  if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2598      SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2599      SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2600      )
2601  {
2602    /* stop SMP timer */
2603    tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2604    if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2605    {
2606      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2607      dmKillTimer(
2608                  dmRoot,
2609                  &(onePortContext->discovery.DiscoverySMPTimer)
2610                 );
2611    }
2612    else
2613    {
2614      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2615    }
2616
2617
2618    tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2619    if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2620    {
2621      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2622      dmKillTimer(
2623                  dmRoot,
2624                  &(oldonePortContext->discovery.DiscoverySMPTimer)
2625                 );
2626    }
2627    else
2628    {
2629      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2630    }
2631  }
2632
2633  if (oneExpander->SAS2 == 0)
2634  {
2635    DM_DBG3(("dmSMPCompleted: SAS 1.1\n"));
2636    if (agIOStatus == OSSA_IO_SUCCESS)
2637    {
2638      //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
2639      /* parsing SMP payload */
2640#ifdef DIRECT_SMP
2641      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2642#else
2643      dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2644      saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
2645#endif
2646      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2647
2648      /* SMP function dependent payload */
2649      switch (dmResponseSMPFrameHeader->smpFunction)
2650      {
2651      case SMP_REPORT_GENERAL:
2652        DM_DBG3(("dmSMPCompleted: report general\n"));
2653        if (agIOInfoLen != sizeof(smpRespReportGeneral_t) + 4 &&
2654            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2655        {
2656          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportGeneral_t) + 4));
2657          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2658
2659          /* SMP request */
2660          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2661          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2662          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2663
2664#ifndef DIRECT_SMP
2665          /* SMP response */
2666          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2667          if (dmSMPResponseBody == agNULL)
2668          {
2669            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2670            return;
2671          }
2672          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2673          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2674          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2675#endif
2676          return;
2677        }
2678        /* start here */
2679        dmReportGeneralRespRcvd(
2680                                dmRoot,
2681                                agRoot,
2682                                agIORequest,
2683                                oneDeviceData,
2684                                dmResponseSMPFrameHeader,
2685                                agFrameHandle
2686                                );
2687        break;
2688      case SMP_DISCOVER:
2689        DM_DBG3(("dmSMPCompleted: discover\n"));
2690        if (agIOInfoLen != sizeof(smpRespDiscover_t) + 4 &&
2691            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2692        {
2693          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespDiscover_t) + 4));
2694          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2695          /* SMP request */
2696          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2697          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2698          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2699
2700#ifndef DIRECT_SMP
2701          /* SMP response */
2702          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2703          if (dmSMPResponseBody == agNULL)
2704          {
2705            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2706            return;
2707          }
2708          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2709          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2710          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2711#endif
2712          return;
2713        }
2714        dmDiscoverRespRcvd(
2715                           dmRoot,
2716                           agRoot,
2717                           agIORequest,
2718                           oneDeviceData,
2719                           dmResponseSMPFrameHeader,
2720                           agFrameHandle
2721                           );
2722        break;
2723      case SMP_REPORT_PHY_SATA:
2724        DM_DBG3(("dmSMPCompleted: report phy sata\n"));
2725        if (agIOInfoLen != sizeof(smpRespReportPhySata_t) + 4 &&
2726            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2727        {
2728          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportPhySata_t) + 4));
2729          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2730          /* SMP request */
2731          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2732          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2733          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2734
2735#ifndef DIRECT_SMP
2736          /* SMP response */
2737          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2738          if (dmSMPResponseBody == agNULL)
2739          {
2740            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2741            return;
2742          }
2743          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2744          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2745          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2746#endif
2747          return;
2748        }
2749        dmReportPhySataRcvd(
2750                            dmRoot,
2751                            agRoot,
2752                            agIORequest,
2753                            oneDeviceData,
2754                            dmResponseSMPFrameHeader,
2755                            agFrameHandle
2756                            );
2757        break;
2758      case SMP_CONFIGURE_ROUTING_INFORMATION:
2759        DM_DBG3(("dmSMPCompleted: configure routing information\n"));
2760        if (agIOInfoLen != 4 &&
2761            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2762        {
2763          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
2764          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2765          /* SMP request */
2766          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2767          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2768          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2769
2770#ifndef DIRECT_SMP
2771          /* SMP response */
2772          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2773          if (dmSMPResponseBody == agNULL)
2774          {
2775            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2776            return;
2777          }
2778          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2779          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2780          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2781#endif
2782          return;
2783        }
2784        dmConfigRoutingInfoRespRcvd(
2785                                    dmRoot,
2786                                    agRoot,
2787                                    agIORequest,
2788                                    oneDeviceData,
2789                                    dmResponseSMPFrameHeader,
2790                                    agFrameHandle
2791                                    );
2792
2793        break;
2794      case SMP_PHY_CONTROL:
2795        DM_DBG3(("dmSMPCompleted: phy control\n"));
2796        if (agIOInfoLen != 4 &&
2797            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */
2798        {
2799          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
2800          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2801
2802          /* SMP request */
2803          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2804          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2805          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2806
2807#ifndef DIRECT_SMP
2808          /* SMP response */
2809          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2810          if (dmSMPResponseBody == agNULL)
2811          {
2812            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2813            return;
2814          }
2815          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2816          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2817          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2818#endif
2819          return;
2820        }
2821        dmPhyControlRespRcvd(
2822                             dmRoot,
2823                             agRoot,
2824                             agIORequest,
2825                             oneDeviceData,
2826                             dmResponseSMPFrameHeader,
2827                             agFrameHandle
2828                            );
2829        break;
2830      case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
2831      case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
2832      case SMP_PHY_TEST_FUNCTION: /* fall through */
2833      case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
2834      case SMP_READ_GPIO_REGISTER: /* fall through */
2835      case SMP_WRITE_GPIO_REGISTER: /* fall through */
2836      default:
2837        DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunction));
2838        DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x !!!\n", dmResponseSMPFrameHeader->smpFrameType));
2839        DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunctionResult));
2840        DM_DBG1(("dmSMPCompleted: smpReserved 0x%x !!!\n", dmResponseSMPFrameHeader->smpReserved));
2841        dmhexdump("dmSMPCompleted: SMP payload !!!", (bit8 *)agFrameHandle, agIOInfoLen);
2842        break;
2843      } /* switch */
2844    } /* OSSA_IO_SUCCESS */
2845    else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
2846    {
2847      /* no retry this case */
2848      DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
2849    }
2850    else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
2851    {
2852      DM_DBG3(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
2853      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2854      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2855
2856      status = saSMPStart(
2857                 agRoot,
2858                 agIORequest,
2859                 0,
2860                 agDevHandle,
2861                 AGSA_SMP_INIT_REQ,
2862                 agSASRequestBody,
2863                 &dmsaSMPCompleted
2864                 );
2865
2866      if (status == AGSA_RC_SUCCESS)
2867      {
2868        /* increment the number of pending SMP */
2869        onePortContext->discovery.pendingSMP++;
2870        if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2871            SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2872            SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2873           )
2874        {
2875          /* start discovery-related SMP timer */
2876          dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
2877        }
2878        return;
2879      }
2880      else if (status == AGSA_RC_BUSY)
2881      {
2882        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
2883            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
2884            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
2885            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2886           )
2887        {
2888          dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
2889        }
2890        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
2891        {
2892          /* For taskmanagement SMP, let's fail task management failure */
2893          dmPhyControlFailureRespRcvd(
2894                                      dmRoot,
2895                                      agRoot,
2896                                      oneDeviceData,
2897                                      dmResponseSMPFrameHeader,
2898                                      agFrameHandle
2899                                     );
2900        }
2901        else
2902        {
2903        }
2904      }
2905      else /* AGSA_RC_FAILURE */
2906      {
2907        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
2908            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
2909            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
2910            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2911           )
2912        {
2913          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2914        }
2915        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
2916        {
2917          /* task management failure */
2918          dmPhyControlFailureRespRcvd(
2919                                      dmRoot,
2920                                      agRoot,
2921                                      oneDeviceData,
2922                                      dmResponseSMPFrameHeader,
2923                                      agFrameHandle
2924                                     );
2925        }
2926        else
2927        {
2928        }
2929      }
2930    }   /* OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE*/
2931    else
2932    {
2933      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
2934          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
2935          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
2936          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
2937          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
2938          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
2939          agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
2940      {
2941        DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
2942        saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
2943      }
2944      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
2945      {
2946        DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
2947        DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
2948        ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
2949        if (ConnRate == SAS_CONNECTION_RATE_1_5G)
2950        {
2951          /* no retry; failure ??? */
2952          if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2953              SMPRequestFunction == SMP_DISCOVER ||
2954              SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2955              SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2956             )
2957          {
2958            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2959          }
2960          else if (SMPRequestFunction == SMP_PHY_CONTROL)
2961          {
2962            /* task management failure */
2963            dmPhyControlFailureRespRcvd(
2964                                        dmRoot,
2965                                        agRoot,
2966                                        oneDeviceData,
2967                                        agNULL,
2968                                        agNULL
2969                                       );
2970          }
2971          else
2972          {
2973          }
2974        }
2975        else
2976        {
2977          ConnRate = ConnRate - 1;
2978        }
2979        agContext = &(dmSMPRequestBody->agContext);
2980        agContext->osData = agIORequest;
2981        saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
2982      }
2983      else
2984      {
2985        if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
2986        {
2987          /* retry the SMP again */
2988          DM_DBG1(("dmSMPCompleted: failed, but retries %d agIOStatus 0x%x %d agIOInfoLen %d !!!\n",
2989                   dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
2990          saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2991          dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2992          status = saSMPStart(
2993                              agRoot,
2994                              agIORequest,
2995                              0,
2996                              agDevHandle,
2997                              AGSA_SMP_INIT_REQ,
2998                              agSASRequestBody,
2999                              &dmsaSMPCompleted
3000                             );
3001          if (status == AGSA_RC_SUCCESS)
3002          {
3003            /* increment the number of pending SMP */
3004            onePortContext->discovery.pendingSMP++;
3005            dmSMPRequestBody->retries++;
3006            if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3007                SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3008                SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3009               )
3010            {
3011              /* start discovery-related SMP timer */
3012              dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3013            }
3014            return;
3015          }
3016          else if (status == AGSA_RC_BUSY)
3017          {
3018            onePortContext->discovery.pendingSMP++;
3019            dmSMPRequestBody->retries++;
3020            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3021                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3022                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3023                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3024               )
3025            {
3026              dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3027              return;
3028            }
3029            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3030            {
3031              /* For taskmanagement SMP, let's fail task management failure */
3032              dmPhyControlFailureRespRcvd(
3033                                          dmRoot,
3034                                          agRoot,
3035                                          oneDeviceData,
3036                                          dmResponseSMPFrameHeader,
3037                                          agFrameHandle
3038                                         );
3039            }
3040            else
3041            {
3042            }
3043          }
3044          else /* AGSA_RC_FAILURE */
3045          {
3046            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3047                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3048                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3049                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3050               )
3051            {
3052              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3053            }
3054            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3055            {
3056              /* task management failure */
3057              dmPhyControlFailureRespRcvd(
3058                                          dmRoot,
3059                                          agRoot,
3060                                          oneDeviceData,
3061                                          dmResponseSMPFrameHeader,
3062                                          agFrameHandle
3063                                         );
3064            }
3065            else
3066            {
3067            }
3068          }
3069        }
3070        else
3071        {
3072          dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
3073          dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
3074          DM_DBG1(("dmSMPCompleted: failed. no more retry. agIOStatus 0x%x %d !!!\n", agIOStatus, agIOStatus));
3075          if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
3076          {
3077            DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
3078          }
3079          if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
3080          {
3081            DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_IN_RECOVERY!!!\n"));
3082          }
3083          if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3084              dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3085              dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3086              dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3087             )
3088          {
3089            /* discovery failure */
3090            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3091            DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3092            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3093          }
3094          else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3095          {
3096            DM_DBG3(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
3097            smpPhyControlReq = (smpReqPhyControl_t *)dmSMPPayload;
3098            if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
3099            {
3100              DM_DBG3(("dmSMPCompleted: discover done with error\n"));
3101              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3102            }
3103            else
3104            {
3105              DM_DBG3(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControlReq->phyOperation));
3106            }
3107          } /* SMP_PHY_CONTROL */
3108          else
3109          {
3110            DM_DBG3(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3111          }
3112        } /* else */
3113      } /* for RateAdjust */
3114    } /* outer else */
3115  } /* SAS 1.1 */
3116  /************************************     SAS 2     ***********************************************/
3117  else
3118  {
3119    DM_DBG2(("dmSMPCompleted: SAS 2\n"));
3120    if (agIOStatus == OSSA_IO_SUCCESS)
3121    {
3122      //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
3123      /* parsing SMP payload */
3124#ifdef DIRECT_SMP
3125    saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3126#else
3127    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3128    saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
3129#endif
3130    dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3131
3132      /* SMP function dependent payload */
3133      switch (dmResponseSMPFrameHeader->smpFunction)
3134      {
3135      case SMP_REPORT_GENERAL:
3136        DM_DBG2(("dmSMPCompleted: report general\n"));
3137        if ((agIOInfoLen != sizeof(smpRespReportGeneral2_t) + 4) &&
3138             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3139           )
3140        {
3141          DM_DBG1(("dmSMPCompleted: report general mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportGeneral2_t) + 4));
3142          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3143
3144          /* SMP request */
3145          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3146          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3147          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3148
3149#ifndef DIRECT_SMP
3150          /* SMP response */
3151          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3152          if (dmSMPResponseBody == agNULL)
3153          {
3154            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3155            return;
3156          }
3157          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3158          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3159          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3160#endif
3161
3162          return;
3163        }
3164
3165        dmReportGeneral2RespRcvd(
3166                                  dmRoot,
3167                                  agRoot,
3168                                  agIORequest,
3169                                  oneDeviceData,
3170                                  dmResponseSMPFrameHeader,
3171                                  agFrameHandle
3172                                  );
3173        break;
3174      case SMP_DISCOVER:
3175        DM_DBG2(("dmSMPCompleted: discover\n"));
3176        if ((agIOInfoLen != sizeof(smpRespDiscover2_t) + 4) &&
3177             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3178           )
3179        {
3180          DM_DBG1(("dmSMPCompleted: discover mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespDiscover2_t) + 4));
3181          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3182
3183          /* SMP request */
3184          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3185          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3186          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3187
3188#ifndef DIRECT_SMP
3189          /* SMP response */
3190          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3191          if (dmSMPResponseBody == agNULL)
3192          {
3193            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3194            return;
3195          }
3196          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3197          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3198          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3199#endif
3200
3201          return;
3202        }
3203        dmDiscover2RespRcvd(
3204                             dmRoot,
3205                             agRoot,
3206                             agIORequest,
3207                                oneDeviceData,
3208                             dmResponseSMPFrameHeader,
3209                             agFrameHandle
3210                             );
3211        break;
3212      case SMP_REPORT_PHY_SATA:
3213        DM_DBG2(("dmSMPCompleted: report phy sata\n"));
3214        if ((agIOInfoLen != sizeof(smpRespReportPhySata2_t) + 4) &&
3215             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3216           )
3217        {
3218          DM_DBG1(("dmSMPCompleted: report phy sata mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportPhySata2_t) + 4));
3219          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3220
3221          /* SMP request */
3222          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3223          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3224          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3225
3226#ifndef DIRECT_SMP
3227          /* SMP response */
3228          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3229          if (dmSMPResponseBody == agNULL)
3230          {
3231            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3232            return;
3233          }
3234          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3235          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3236          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3237#endif
3238
3239          return;
3240        }
3241        dmReportPhySata2Rcvd(
3242                              dmRoot,
3243                              agRoot,
3244                              agIORequest,
3245                              oneDeviceData,
3246                              dmResponseSMPFrameHeader,
3247                              agFrameHandle
3248                              );
3249        break;
3250      case SMP_CONFIGURE_ROUTING_INFORMATION:
3251        DM_DBG2(("dmSMPCompleted: configure routing information\n"));
3252        if (agIOInfoLen != 4 &&
3253            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3254           )
3255        {
3256          DM_DBG1(("dmSMPCompleted: configure routing information mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
3257          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3258
3259          /* SMP request */
3260          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3261          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3262          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3263
3264#ifndef DIRECT_SMP
3265          /* SMP response */
3266          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3267          if (dmSMPResponseBody == agNULL)
3268          {
3269            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3270            return;
3271          }
3272          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3273          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3274          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3275#endif
3276
3277          return;
3278        }
3279        dmConfigRoutingInfo2RespRcvd(
3280                                      dmRoot,
3281                                      agRoot,
3282                                      agIORequest,
3283                                      oneDeviceData,
3284                                      dmResponseSMPFrameHeader,
3285                                      agFrameHandle
3286                                      );
3287
3288        break;
3289      case SMP_PHY_CONTROL:
3290        DM_DBG2(("dmSMPCompleted: phy control\n"));
3291        if (agIOInfoLen != 4 &&
3292            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3293           ) /*zero length is expected */
3294        {
3295          DM_DBG1(("dmSMPCompleted: phy control mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
3296          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3297
3298          /* SMP request */
3299          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3300          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3301          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3302
3303#ifndef DIRECT_SMP
3304          /* SMP response */
3305          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3306          if (dmSMPResponseBody == agNULL)
3307          {
3308            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3309            return;
3310          }
3311          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3312          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3313          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3314#endif
3315
3316          return;
3317        }
3318        dmPhyControl2RespRcvd(
3319                               dmRoot,
3320                               agRoot,
3321                               agIORequest,
3322             oneDeviceData,
3323                               dmResponseSMPFrameHeader,
3324                               agFrameHandle
3325            );
3326
3327
3328        break;
3329#ifdef NOT_YET
3330      case SMP_DISCOVER_LIST:
3331        DM_DBG1(("dmSMPCompleted: SMP_DISCOVER_LIST\n"));
3332        DM_DBG1(("dmSMPCompleted: agIOInfoLen 0x%x \n", agIOInfoLen));
3333        tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
3334        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3335
3336          /* SMP request */
3337          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3338          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3339          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3340
3341#ifndef DIRECT_SMP
3342          /* SMP response */
3343          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3344          if (dmSMPResponseBody == agNULL)
3345          {
3346            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3347            return;
3348          }
3349          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3350          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3351          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3352#endif
3353
3354        return;
3355        break;
3356#endif
3357      case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
3358      case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
3359      case SMP_PHY_TEST_FUNCTION: /* fall through */
3360      case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
3361      case SMP_READ_GPIO_REGISTER: /* fall through */
3362      case SMP_WRITE_GPIO_REGISTER: /* fall through */
3363      default:
3364        DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x\n", dmResponseSMPFrameHeader->smpFunction));
3365        DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x\n", dmResponseSMPFrameHeader->smpFrameType));
3366        DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x\n", dmResponseSMPFrameHeader->smpFunctionResult));
3367        DM_DBG1(("dmSMPCompleted: smpReserved 0x%x\n", dmResponseSMPFrameHeader->smpReserved));
3368        dmhexdump("dmSMPCompleted: SMP payload", (bit8 *)agFrameHandle, agIOInfoLen);
3369        break;
3370      }
3371    } /* agIOStatus == OSSA_IO_SUCCESS */
3372    else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
3373    {
3374      /* no retry this case */
3375      DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
3376    }
3377    else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
3378    {
3379      DM_DBG1(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
3380      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3381      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3382
3383      status = saSMPStart(
3384                          agRoot,
3385                          agIORequest,
3386                          0,
3387                          agDevHandle,
3388                          AGSA_SMP_INIT_REQ,
3389                          agSASRequestBody,
3390                          &dmsaSMPCompleted
3391                         );
3392
3393
3394      if (status == AGSA_RC_SUCCESS)
3395      {
3396        /* increment the number of pending SMP */
3397        onePortContext->discovery.pendingSMP++;
3398        if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3399            SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3400            SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3401           )
3402        {
3403          /* start discovery-related SMP timer */
3404          dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3405        }
3406        return;
3407      }
3408      else if (status == AGSA_RC_BUSY)
3409      {
3410        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3411            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3412            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3413            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3414           )
3415        {
3416          dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3417        }
3418        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3419        {
3420          /* For taskmanagement SMP, let's fail task management failure */
3421          dmPhyControlFailureRespRcvd(
3422                                      dmRoot,
3423                                      agRoot,
3424                                      oneDeviceData,
3425                                      dmResponseSMPFrameHeader,
3426                                      agFrameHandle
3427                                     );
3428        }
3429        else
3430        {
3431        }
3432      }
3433      else /* AGSA_RC_FAILURE */
3434      {
3435        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3436            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3437            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3438            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3439      )
3440        {
3441          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3442        }
3443        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3444        {
3445          /* task management failure */
3446          dmPhyControlFailureRespRcvd(
3447                                      dmRoot,
3448                                      agRoot,
3449                                      oneDeviceData,
3450                                      dmResponseSMPFrameHeader,
3451                                      agFrameHandle
3452                                     );
3453        }
3454        else
3455        {
3456        }
3457      }
3458    }
3459    else if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION)
3460    {
3461      DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
3462      /*
3463         skip to the next expander
3464      */
3465      dmHandleZoneViolation(
3466                           dmRoot,
3467                           agRoot,
3468                           agIORequest,
3469                           oneDeviceData,
3470                           agNULL,
3471                           agFrameHandle
3472                           );
3473    }
3474    else
3475    {
3476      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
3477          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
3478          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
3479          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
3480          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
3481          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
3482          agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
3483      {
3484        DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
3485        saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
3486      }
3487      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
3488      {
3489        DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
3490        DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
3491        ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
3492        if (ConnRate == SAS_CONNECTION_RATE_1_5G)
3493        {
3494          /* no retry; failure ??? */
3495          if (SMPRequestFunction == SMP_REPORT_GENERAL ||
3496              SMPRequestFunction == SMP_DISCOVER ||
3497              SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3498              SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3499             )
3500          {
3501            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3502          }
3503          else if (SMPRequestFunction == SMP_PHY_CONTROL)
3504          {
3505            /* task management failure */
3506            dmPhyControlFailureRespRcvd(
3507                                        dmRoot,
3508                                        agRoot,
3509                                        oneDeviceData,
3510                                        agNULL,
3511                                        agNULL
3512                                       );
3513          }
3514          else
3515          {
3516          }
3517        }
3518        else
3519        {
3520          ConnRate = ConnRate - 1;
3521        }
3522        agContext = &(dmSMPRequestBody->agContext);
3523        agContext->osData = agIORequest;
3524        saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
3525      }
3526      else
3527      {
3528        if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
3529        {
3530          /* retry the SMP again */
3531          DM_DBG1(("dmSMPCompleted: failed! but retries %d agIOStatus 0x%x %d agIOInfoLen %d\n",
3532                   dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
3533          saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3534          dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3535          status = saSMPStart(
3536                              agRoot,
3537                              agIORequest,
3538                              0,
3539                              agDevHandle,
3540                              AGSA_SMP_INIT_REQ,
3541                              agSASRequestBody,
3542                              &dmsaSMPCompleted
3543                             );
3544
3545          if (status == AGSA_RC_SUCCESS)
3546          {
3547            /* increment the number of pending SMP */
3548            onePortContext->discovery.pendingSMP++;
3549            dmSMPRequestBody->retries++;
3550            if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3551                SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3552                SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3553               )
3554            {
3555              /* start discovery-related SMP timer */
3556              dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3557            }
3558            return;
3559          }
3560          else if (status == AGSA_RC_BUSY)
3561          {
3562            onePortContext->discovery.pendingSMP++;
3563            dmSMPRequestBody->retries++;
3564            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3565                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3566                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3567                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3568               )
3569            {
3570              dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3571              return;
3572            }
3573            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3574            {
3575              /* For taskmanagement SMP, let's fail task management failure */
3576              dmPhyControlFailureRespRcvd(
3577                                          dmRoot,
3578                                          agRoot,
3579                                          oneDeviceData,
3580                                          dmResponseSMPFrameHeader,
3581                                          agFrameHandle
3582                                         );
3583            }
3584            else
3585            {
3586            }
3587          }
3588          else /* AGSA_RC_FAILURE */
3589          {
3590            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3591                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3592                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3593                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3594               )
3595            {
3596              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3597            }
3598            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3599            {
3600              /* task management failure */
3601              dmPhyControlFailureRespRcvd(
3602                                          dmRoot,
3603                                          agRoot,
3604                                          oneDeviceData,
3605                                          dmResponseSMPFrameHeader,
3606                                          agFrameHandle
3607                                         );
3608            }
3609            else
3610            {
3611            }
3612          }
3613        }
3614        else
3615        {
3616          dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
3617          dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
3618          DM_DBG1(("dmSMPCompleted: failed! no more retry! agIOStatus 0x%x %d\n", agIOStatus, agIOStatus));
3619          if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
3620          {
3621            DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_NON_OPERATIONAL\n"));
3622          }
3623          if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
3624          {
3625            DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_IN_RECOVERY\n"));
3626          }
3627          if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3628              dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3629              dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3630              dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3631             )
3632          {
3633            /* discovery failure */
3634            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3635            DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3636            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3637          }
3638          else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3639          {
3640            DM_DBG1(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
3641            smpPhyControl2Req = (smpReqPhyControl2_t *)dmSMPPayload;
3642            if (smpPhyControl2Req->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
3643            {
3644              DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3645              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3646            }
3647            else
3648            {
3649              DM_DBG1(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControl2Req->phyOperation));
3650            }
3651          } /* SMP_PHY_CONTROL */
3652          else
3653          {
3654            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3655          }
3656        } /* else */
3657      } /* for RateAdjust */
3658    } /* outer else */
3659  } /* SAS 2 else */
3660
3661  /* SMP request */
3662  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3663  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3664  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3665
3666#ifndef DIRECT_SMP
3667  /* SMP response */
3668  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3669  if (dmSMPResponseBody == agNULL)
3670  {
3671    DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3672    return;
3673  }
3674  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3675  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3676  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3677#endif
3678
3679  return;
3680}
3681
3682osGLOBAL void
3683dmSMPAbortCB(
3684             agsaRoot_t           *agRoot,
3685             agsaIORequest_t      *agIORequest,
3686             bit32                flag,
3687             bit32                status)
3688{
3689  dmRoot_t             *dmRoot = agNULL;
3690  dmIntRoot_t          *dmIntRoot    = agNULL;
3691  dmIntContext_t       *dmAllShared = agNULL;
3692  dmSMPRequestBody_t   *dmSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
3693
3694  DM_DBG5(("dmSMPAbortCB: start\n"));
3695
3696  if (dmSMPRequestBody == agNULL)
3697  {
3698    DM_DBG1(("dmSMPAbortCB: pSMPRequestBody is NULL!!! \n"));
3699    return;
3700  }
3701
3702  dmRoot = dmSMPRequestBody->dmRoot;
3703  dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
3704  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
3705
3706
3707  /* put back into free smplist */
3708  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3709  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3710  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3711
3712  /* start here */
3713  if (flag == 2)
3714  {
3715    /* abort all per port */
3716    DM_DBG1(("dmSMPAbortCB: abort per port; not used!!!\n"));
3717  }
3718  else if (flag == 1)
3719  {
3720    /* abort all */
3721    DM_DBG1(("dmSMPAbortCB: abort all; not used!!!\n"));
3722  }
3723  else if (flag == 0)
3724  {
3725    /* abort one */
3726    DM_DBG1(("ossaSMPAbortCB: abort one\n"));
3727    if (status != OSSA_IO_SUCCESS)
3728    {
3729      DM_DBG1(("dmSMPAbortCB: abort one, status 0x%x\n", status));
3730    }
3731  }
3732  else
3733  {
3734    DM_DBG1(("dmSMPAbortCB: not allowed case, flag 0x%x!!!\n", flag));
3735  }
3736
3737  return;
3738}
3739
3740
3741#endif /* FDS_DM */
3742
3743
3744