1285242Sachim/*******************************************************************************
2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285242Sachim*
4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285242Sachim*that the following conditions are met:
6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285242Sachim*following disclaimer.
8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice,
9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285242Sachim*with the distribution.
11285242Sachim*
12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285242Sachim
21285242Sachim**
22285242Sachim********************************************************************************/
23285242Sachim#include <sys/cdefs.h>
24285242Sachim__FBSDID("$FreeBSD: releng/11.0/sys/dev/pms/RefTisa/discovery/dm/dmsmp.c 285242 2015-07-07 13:17:02Z achim $");
25285242Sachim#include <dev/pms/config.h>
26285242Sachim
27285242Sachim#include <dev/pms/freebsd/driver/common/osenv.h>
28285242Sachim#include <dev/pms/freebsd/driver/common/ostypes.h>
29285242Sachim#include <dev/pms/freebsd/driver/common/osdebug.h>
30285242Sachim
31285242Sachim#include <dev/pms/RefTisa/sallsdk/api/sa.h>
32285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34285242Sachim
35285242Sachim#ifdef FDS_DM
36285242Sachim#include <dev/pms/RefTisa/discovery/api/dm.h>
37285242Sachim#include <dev/pms/RefTisa/discovery/api/dmapi.h>
38285242Sachim#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
39285242Sachim
40285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmdefs.h>
41285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmtypes.h>
42285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmproto.h>
43285242Sachim
44285242SachimosGLOBAL bit32
45285242SachimdmSMPStart(
46285242Sachim           dmRoot_t              *dmRoot,
47285242Sachim           agsaRoot_t            *agRoot,
48285242Sachim           dmDeviceData_t        *oneDeviceData,
49285242Sachim           bit32                 functionCode,
50285242Sachim           bit8                  *pSmpBody,
51285242Sachim           bit32                 smpBodySize,
52285242Sachim           bit32                 agRequestType
53285242Sachim           )
54285242Sachim{
55285242Sachim  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
56285242Sachim  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
57285242Sachim  dmIntPortContext_t        *onePortContext = agNULL;
58285242Sachim  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
59285242Sachim#ifndef DIRECT_SMP
60285242Sachim  dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
61285242Sachim#endif
62285242Sachim  agsaSASRequestBody_t      *agSASRequestBody;
63285242Sachim  dmList_t                  *SMPList;
64285242Sachim  agsaDevHandle_t           *agDevHandle;
65285242Sachim  agsaIORequest_t           *agIORequest;
66285242Sachim  agsaSMPFrame_t            *agSMPFrame;
67285242Sachim  bit32                     expectedRspLen = 0;
68285242Sachim  dmSMPFrameHeader_t        dmSMPFrameHeader;
69285242Sachim  dmExpander_t              *oneExpander = agNULL;
70285242Sachim  bit32                     status;
71285242Sachim
72285242Sachim  DM_DBG5(("dmSMPStart: start\n"));
73285242Sachim  DM_DBG5(("dmSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
74285242Sachim  DM_DBG5(("dmSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
75285242Sachim
76285242Sachim  dm_memset(&dmSMPFrameHeader, 0, sizeof(dmSMPFrameHeader_t));
77285242Sachim
78285242Sachim  onePortContext = oneDeviceData->dmPortContext;
79285242Sachim
80285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
81285242Sachim  {
82285242Sachim    DM_DBG1(("dmSMPStart: invalid port or aborted discovery!!!\n"));
83285242Sachim    return DM_RC_FAILURE;
84285242Sachim  }
85285242Sachim
86285242Sachim  oneExpander = oneDeviceData->dmExpander;
87285242Sachim  if (oneExpander == agNULL)
88285242Sachim  {
89285242Sachim    DM_DBG1(("dmSMPStart: Wrong!!! oneExpander is NULL!!!\n"));
90285242Sachim    return DM_RC_FAILURE;
91285242Sachim  }
92285242Sachim
93285242Sachim  if (onePortContext != agNULL)
94285242Sachim  {
95285242Sachim    DM_DBG5(("dmSMPStart: pid %d\n", onePortContext->id));
96285242Sachim    /* increment the number of pending SMP */
97285242Sachim    onePortContext->discovery.pendingSMP++;
98285242Sachim  }
99285242Sachim  else
100285242Sachim  {
101285242Sachim    DM_DBG1(("dmSMPStart: Wrong, onePortContext is NULL!!!\n"));
102285242Sachim    return DM_RC_FAILURE;
103285242Sachim  }
104285242Sachim
105285242Sachim  /* get an smp REQUEST from the free list */
106285242Sachim  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
107285242Sachim  if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
108285242Sachim  {
109285242Sachim    DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
110285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
111285242Sachim    /* undo increment the number of pending SMP */
112285242Sachim    onePortContext->discovery.pendingSMP--;
113285242Sachim    return DM_RC_FAILURE;
114285242Sachim  }
115285242Sachim  else
116285242Sachim  {
117285242Sachim    DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
118285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
119285242Sachim    dmSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
120285242Sachim  }
121285242Sachim
122285242Sachim  if (dmSMPRequestBody == agNULL)
123285242Sachim  {
124285242Sachim    DM_DBG1(("dmSMPStart: dmSMPRequestBody is NULL, wrong!!!\n"));
125285242Sachim    return DM_RC_FAILURE;
126285242Sachim  }
127285242Sachim  DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPRequestBody->id));
128285242Sachim
129285242Sachim  dmSMPRequestBody->dmRoot = dmRoot;
130285242Sachim  dmSMPRequestBody->dmDevice = oneDeviceData;
131285242Sachim  dmSMPRequestBody->dmPortContext = onePortContext;
132285242Sachim
133285242Sachim  agDevHandle = oneExpander->agDevHandle;
134285242Sachim
135285242Sachim  /* save the callback funtion */
136285242Sachim  dmSMPRequestBody->SMPCompletionFunc = dmSMPCompleted; /* in dmsmp.c */
137285242Sachim
138285242Sachim  dmSMPRequestBody->retries = 0;
139285242Sachim
140285242Sachim  agIORequest = &(dmSMPRequestBody->agIORequest);
141285242Sachim  agIORequest->osData = (void *) dmSMPRequestBody;
142285242Sachim  agIORequest->sdkData = agNULL; /* SALL takes care of this */
143285242Sachim
144285242Sachim  agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
145285242Sachim  agSMPFrame = &(agSASRequestBody->smpFrame);
146285242Sachim
147285242Sachim  /* sets dmSMPFrameHeader values */
148285242Sachim  if (oneExpander->SAS2 == 0)
149285242Sachim  {
150285242Sachim    DM_DBG5(("dmSMPStart: SAS 1.1\n"));
151285242Sachim    switch (functionCode)
152285242Sachim    {
153285242Sachim    case SMP_REPORT_GENERAL:
154285242Sachim      expectedRspLen = sizeof(smpRespReportGeneral_t) + 4;
155285242Sachim      break;
156285242Sachim    case SMP_REPORT_MANUFACTURE_INFORMATION:
157285242Sachim      expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4;
158285242Sachim      break;
159285242Sachim    case SMP_DISCOVER:
160285242Sachim      expectedRspLen = sizeof(smpRespDiscover_t) + 4;
161285242Sachim      break;
162285242Sachim    case SMP_REPORT_PHY_ERROR_LOG:
163285242Sachim      expectedRspLen = 32 - 4;
164285242Sachim      break;
165285242Sachim    case SMP_REPORT_PHY_SATA:
166285242Sachim      expectedRspLen = sizeof(smpRespReportPhySata_t) + 4;
167285242Sachim      break;
168285242Sachim    case SMP_REPORT_ROUTING_INFORMATION:
169285242Sachim      expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4;
170285242Sachim      break;
171285242Sachim    case SMP_CONFIGURE_ROUTING_INFORMATION:
172285242Sachim      expectedRspLen = 4;
173285242Sachim      break;
174285242Sachim    case SMP_PHY_CONTROL:
175285242Sachim      expectedRspLen = 4;
176285242Sachim      break;
177285242Sachim    case SMP_PHY_TEST_FUNCTION:
178285242Sachim      expectedRspLen = 4;
179285242Sachim      break;
180285242Sachim    case SMP_PMC_SPECIFIC:
181285242Sachim      expectedRspLen = 4;
182285242Sachim      break;
183285242Sachim    default:
184285242Sachim      expectedRspLen = 0;
185285242Sachim      DM_DBG1(("dmSMPStart: SAS 1.1 error, undefined or unused smp function code 0x%x !!!\n", functionCode));
186285242Sachim      return DM_RC_FAILURE;
187285242Sachim    }
188285242Sachim    /* SMP 1.1 header */
189285242Sachim    dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
190285242Sachim    dmSMPFrameHeader.smpFunction = (bit8)functionCode;
191285242Sachim    dmSMPFrameHeader.smpFunctionResult = 0;
192285242Sachim    dmSMPFrameHeader.smpReserved = 0;
193285242Sachim  }
194285242Sachim  else /* SAS 2 */
195285242Sachim  {
196285242Sachim    DM_DBG2(("dmSMPStart: SAS 2\n"));
197285242Sachim    switch (functionCode)
198285242Sachim    {
199285242Sachim    case SMP_REPORT_GENERAL:
200285242Sachim      expectedRspLen = sizeof(smpRespReportGeneral2_t) + 4;
201285242Sachim      /* SMP 2.0 header */
202285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
203285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
204285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0x11;
205285242Sachim      dmSMPFrameHeader.smpReserved = 0;
206285242Sachim      break;
207285242Sachim    case SMP_REPORT_MANUFACTURE_INFORMATION:
208285242Sachim      expectedRspLen = sizeof(smpRespReportManufactureInfo2_t) + 4;
209285242Sachim      break;
210285242Sachim    case SMP_DISCOVER:
211285242Sachim      expectedRspLen = sizeof(smpRespDiscover2_t) + 4;
212285242Sachim      /* SMP 2.0 header */
213285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
214285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
215285242Sachim//      dmSMPFrameHeader.smpFunctionResult = 0x6c;
216285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0x1b;
217285242Sachim      dmSMPFrameHeader.smpReserved = 0x02;
218285242Sachim      break;
219285242Sachim    case SMP_REPORT_PHY_ERROR_LOG:
220285242Sachim      expectedRspLen = 32 - 4;
221285242Sachim      break;
222285242Sachim    case SMP_REPORT_PHY_SATA:
223285242Sachim      /* SMP 2.0 header */
224285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
225285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
226285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0x10;
227285242Sachim      dmSMPFrameHeader.smpReserved = 0x02;
228285242Sachim      expectedRspLen = sizeof(smpRespReportPhySata2_t) + 4;
229285242Sachim      break;
230285242Sachim    case SMP_REPORT_ROUTING_INFORMATION:
231285242Sachim      expectedRspLen = sizeof(smpRespReportRouteTable2_t) + 4;
232285242Sachim      break;
233285242Sachim    case SMP_CONFIGURE_ROUTING_INFORMATION:
234285242Sachim      expectedRspLen = 4;
235285242Sachim      /* SMP 2.0 header */
236285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
237285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
238285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0;
239285242Sachim      dmSMPFrameHeader.smpReserved = 0x09;
240285242Sachim      break;
241285242Sachim    case SMP_PHY_CONTROL:
242285242Sachim      expectedRspLen = 4;
243285242Sachim      /* SMP 2.0 header */
244285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
245285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
246285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0;
247285242Sachim      dmSMPFrameHeader.smpReserved = 0x09;
248285242Sachim     break;
249285242Sachim    case SMP_PHY_TEST_FUNCTION:
250285242Sachim      expectedRspLen = 4;
251285242Sachim      break;
252285242Sachim    case SMP_DISCOVER_LIST:
253285242Sachim      expectedRspLen = SMP_MAXIMUM_PAYLOAD; /* 1024 without CRC */
254285242Sachim      /* SMP 2.0 header */
255285242Sachim      dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
256285242Sachim      dmSMPFrameHeader.smpFunction = (bit8)functionCode;
257285242Sachim      dmSMPFrameHeader.smpFunctionResult = 0xFF;
258285242Sachim      dmSMPFrameHeader.smpReserved = 0x06;
259285242Sachim      break;
260285242Sachim    case SMP_PMC_SPECIFIC:
261285242Sachim      expectedRspLen = 4;
262285242Sachim      break;
263285242Sachim    default:
264285242Sachim      expectedRspLen = 0;
265285242Sachim      DM_DBG1(("dmSMPStart: SAS 2 error!!! undefined or unused smp function code 0x%x!!!\n", functionCode));
266285242Sachim      return DM_RC_FAILURE;
267285242Sachim    }
268285242Sachim  }
269285242Sachim
270285242Sachim  if (DMIsSPC(agRoot))
271285242Sachim  {
272285242Sachim#ifdef DIRECT_SMP  /* direct SMP with 48 or less payload */
273285242Sachim  if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
274285242Sachim  {
275285242Sachim    DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
276285242Sachim    dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
277285242Sachim    dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
278285242Sachim    dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
279285242Sachim
280285242Sachim    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
281285242Sachim    agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
282285242Sachim    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
283285242Sachim    /* to specify DIRECT SMP response */
284285242Sachim    agSMPFrame->inFrameLen = 0;
285285242Sachim
286285242Sachim    /* temporary solution for T2D Combo*/
287285242Sachim#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
288285242Sachim    /* force smp repsonse to be direct */
289285242Sachim    agSMPFrame->expectedRespLen = 0;
290285242Sachim#else
291285242Sachim    agSMPFrame->expectedRespLen = expectedRspLen;
292285242Sachim#endif
293285242Sachim  }
294285242Sachim  else
295285242Sachim  {
296285242Sachim    DM_DBG5(("dmSMPStart: INDIRECT smp payload, TBD\n"));
297285242Sachim  }
298285242Sachim
299285242Sachim#else
300285242Sachim
301285242Sachim  /*
302285242Sachim     dmSMPRequestBody is SMP request
303285242Sachim     dmSMPResponsebody is SMP response
304285242Sachim  */
305285242Sachim
306285242Sachim  /* get an smp RESPONSE from the free list */
307285242Sachim  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
308285242Sachim  if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
309285242Sachim  {
310285242Sachim    DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
311285242Sachim    /* puy back dmSMPRequestBody to the freelist ???*/
312285242Sachim//    DMLIST_DEQUEUE_THIS(&(dmSMPRequestBody->Link));
313285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
314285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
315285242Sachim
316285242Sachim    /* undo increment the number of pending SMP */
317285242Sachim    onePortContext->discovery.pendingSMP--;
318285242Sachim    return DM_RC_FAILURE;
319285242Sachim  }
320285242Sachim  else
321285242Sachim  {
322285242Sachim    DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
323285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
324285242Sachim    dmSMPResponseBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
325285242Sachim    DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPResponseBody->id));
326285242Sachim  }
327285242Sachim
328285242Sachim  if (dmSMPResponseBody == agNULL)
329285242Sachim  {
330285242Sachim    DM_DBG1(("dmSMPStart: dmSMPResponseBody is NULL, wrong!!!\n"));
331285242Sachim    return DM_RC_FAILURE;
332285242Sachim  }
333285242Sachim
334285242Sachim  /* fill in indirect SMP request fields */
335285242Sachim  DM_DBG5(("dmSMPStart: INDIRECT smp payload\n"));
336285242Sachim
337285242Sachim  /* save the pointer to SMP response in SMP request */
338285242Sachim  dmSMPRequestBody->IndirectSMPResponse = dmSMPResponseBody;
339285242Sachim  /* SMP request and response initialization */
340285242Sachim  dm_memset(dmSMPRequestBody->IndirectSMP, 0, smpBodySize + 4);
341285242Sachim  dm_memset(dmSMPResponseBody->IndirectSMP, 0, expectedRspLen);
342285242Sachim
343285242Sachim  dm_memcpy(dmSMPRequestBody->IndirectSMP, &dmSMPFrameHeader, 4);
344285242Sachim  dm_memcpy(dmSMPRequestBody->IndirectSMP+4, pSmpBody, smpBodySize);
345285242Sachim
346285242Sachim  /* Indirect SMP request */
347285242Sachim  agSMPFrame->outFrameBuf = agNULL;
348285242Sachim  agSMPFrame->outFrameAddrUpper32 = dmSMPRequestBody->IndirectSMPUpper32;
349285242Sachim  agSMPFrame->outFrameAddrLower32 = dmSMPRequestBody->IndirectSMPLower32;
350285242Sachim  agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
351285242Sachim
352285242Sachim  /* Indirect SMP response */
353285242Sachim  agSMPFrame->expectedRespLen = expectedRspLen;
354285242Sachim  agSMPFrame->inFrameAddrUpper32 = dmSMPResponseBody->IndirectSMPUpper32;
355285242Sachim  agSMPFrame->inFrameAddrLower32 = dmSMPResponseBody->IndirectSMPLower32;
356285242Sachim  agSMPFrame->inFrameLen = expectedRspLen; /* without last 4 byte crc */
357285242Sachim
358285242Sachim#endif
359285242Sachim  }
360285242Sachim  else /* SPCv controller */
361285242Sachim  {
362285242Sachim    /* only direct mode for both request and response */
363285242Sachim    DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
364285242Sachim    agSMPFrame->flag = 0;
365285242Sachim    dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
366285242Sachim    dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
367285242Sachim    dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
368285242Sachim
369285242Sachim    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
370285242Sachim    agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
371285242Sachim    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
372285242Sachim    /* to specify DIRECT SMP response */
373285242Sachim    agSMPFrame->inFrameLen = 0;
374285242Sachim
375285242Sachim      /* temporary solution for T2D Combo*/
376285242Sachim#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
377285242Sachim    /* force smp repsonse to be direct */
378285242Sachim    agSMPFrame->expectedRespLen = 0;
379285242Sachim#else
380285242Sachim    agSMPFrame->expectedRespLen = expectedRspLen;
381285242Sachim#endif
382285242Sachim  //    tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
383285242Sachim  //    tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
384285242Sachim  //    tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t));
385285242Sachim  }
386285242Sachim
387285242Sachim  if (agDevHandle == agNULL)
388285242Sachim  {
389285242Sachim    DM_DBG1(("dmSMPStart: !!! agDevHandle is NULL !!! \n"));
390285242Sachim  }
391285242Sachim  else
392285242Sachim  {
393285242Sachim    status = saSMPStart(
394285242Sachim                      agRoot,
395285242Sachim                      agIORequest,
396285242Sachim                      0,
397285242Sachim                      agDevHandle,
398285242Sachim                      agRequestType,
399285242Sachim                      agSASRequestBody,
400285242Sachim                      &dmsaSMPCompleted
401285242Sachim                      );
402285242Sachim
403285242Sachim    if (status == AGSA_RC_SUCCESS)
404285242Sachim    {
405285242Sachim      /* start SMP timer */
406285242Sachim      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
407285242Sachim          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION
408285242Sachim        )
409285242Sachim      {
410285242Sachim        dmDiscoverySMPTimer(dmRoot, onePortContext, functionCode, dmSMPRequestBody);
411285242Sachim      }
412285242Sachim      return DM_RC_SUCCESS;
413285242Sachim    }
414285242Sachim    else if (status == AGSA_RC_BUSY)
415285242Sachim    {
416285242Sachim      /* set timer */
417285242Sachim      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
418285242Sachim          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
419285242Sachim      {
420285242Sachim        /* only for discovery related SMPs*/
421285242Sachim        dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
422285242Sachim        return DM_RC_SUCCESS;
423285242Sachim      }
424285242Sachim      else
425285242Sachim      {
426285242Sachim        DM_DBG1(("dmSMPStart: return DM_RC_BUSY!!! \n"));
427285242Sachim#ifdef DIRECT_SMP
428285242Sachim        tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
429285242Sachim        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
430285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
431285242Sachim#else
432285242Sachim        tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
433285242Sachim        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
434285242Sachim        DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
435285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
436285242Sachim#endif
437285242Sachim        return DM_RC_BUSY;
438285242Sachim      }
439285242Sachim    }
440285242Sachim    else /* AGSA_RC_FAILURE */
441285242Sachim    {
442285242Sachim      DM_DBG1(("dmSMPStart: return DM_RC_FAILURE!!! \n"));
443285242Sachim      /* discovery failure or task management failure */
444285242Sachim      if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
445285242Sachim          functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
446285242Sachim      {
447285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
448285242Sachim      }
449285242Sachim#ifdef DIRECT_SMP
450285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
451285242Sachim      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
452285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
453285242Sachim#else
454285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
455285242Sachim      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
456285242Sachim      DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
457285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
458285242Sachim#endif
459285242Sachim
460285242Sachim      return DM_RC_FAILURE;
461285242Sachim    }
462285242Sachim  }
463285242Sachim  return DM_RC_SUCCESS;
464285242Sachim}
465285242Sachim
466285242SachimosGLOBAL void
467285242SachimdmsaSMPCompleted(
468285242Sachim                 agsaRoot_t            *agRoot,
469285242Sachim                 agsaIORequest_t       *agIORequest,
470285242Sachim                 bit32                 agIOStatus,
471285242Sachim                 bit32                 agIOInfoLen,
472285242Sachim                 agsaFrameHandle_t     agFrameHandle
473285242Sachim                 )
474285242Sachim{
475285242Sachim  dmSMPRequestBody_t   *pSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
476285242Sachim
477285242Sachim  /* SPC can't be SMP target */
478285242Sachim
479285242Sachim  DM_DBG5(("dmsaSMPCompleted: start\n"));
480285242Sachim
481285242Sachim  if (pSMPRequestBody == agNULL)
482285242Sachim  {
483285242Sachim    DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody is NULL!!! \n"));
484285242Sachim    return;
485285242Sachim  }
486285242Sachim
487285242Sachim  if (pSMPRequestBody->SMPCompletionFunc == agNULL)
488285242Sachim  {
489285242Sachim    DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody->SMPCompletionFunc is NULL!!!\n"));
490285242Sachim    return;
491285242Sachim  }
492285242Sachim
493285242Sachim#ifdef DM_INTERNAL_DEBUG /* debugging */
494285242Sachim  DM_DBG3(("dmsaSMPCompleted: agIOrequest %p\n", agIORequest->osData));
495285242Sachim  DM_DBG3(("dmsaSMPCompleted: sizeof(tdIORequestBody_t) %d 0x%x\n", sizeof(tdIORequestBody_t),
496285242Sachim           sizeof(tdIORequestBody_t)));
497285242Sachim  DM_DBG3(("dmsaSMPCompleted: SMPRequestbody %p\n", pSMPRequestBody));
498285242Sachim  DM_DBG3(("dmsaSMPCompleted: calling callback fn\n"));
499285242Sachim  DM_DBG3(("dmsaSMPCompleted: callback fn %p\n",pSMPRequestBody->SMPCompletionFunc));
500285242Sachim#endif /* TD_INTERNAL_DEBUG */
501285242Sachim  /*
502285242Sachim    if initiator, calling dmSMPCompleted() in dmsmp.c
503285242Sachim  */
504285242Sachim  pSMPRequestBody->SMPCompletionFunc(
505285242Sachim                                     agRoot,
506285242Sachim                                     agIORequest,
507285242Sachim                                     agIOStatus,
508285242Sachim                                     agIOInfoLen,
509285242Sachim                                     agFrameHandle
510285242Sachim                                     );
511285242Sachim
512285242Sachim  return;
513285242Sachim
514285242Sachim}
515285242Sachim
516285242SachimosGLOBAL bit32
517285242SachimdmPhyControlSend(
518285242Sachim                   dmRoot_t             *dmRoot,
519285242Sachim//                   dmDeviceData_t     *oneDeviceData, /* taget disk */
520285242Sachim                   dmDeviceData_t     *oneExpDeviceData, /* taget disk */
521285242Sachim                   bit8                 phyOp,
522285242Sachimbit8 phyID // added
523285242Sachim                   )
524285242Sachim{
525285242Sachim  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
526285242Sachim  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
527285242Sachim  agsaRoot_t                *agRoot = dmAllShared->agRoot;
528285242Sachim//  thenil
529285242Sachim//  dmDeviceData_t      *oneExpDeviceData;
530285242Sachim  smpReqPhyControl_t    smpPhyControlReq;
531285242Sachim//  bit8                  phyID;
532285242Sachim  bit32                 status;
533285242Sachim
534285242Sachim  DM_DBG3(("dmPhyControlSend: start\n"));
535285242Sachim
536285242Sachim
537285242Sachim
538285242Sachim  osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
539285242Sachim
540285242Sachim  /* fill in SMP payload */
541285242Sachim  smpPhyControlReq.phyIdentifier = phyID;
542285242Sachim  smpPhyControlReq.phyOperation = phyOp;
543285242Sachim
544285242Sachim  status = dmSMPStart(
545285242Sachim                      dmRoot,
546285242Sachim                      agRoot,
547285242Sachim                      oneExpDeviceData,
548285242Sachim                      SMP_PHY_CONTROL,
549285242Sachim                      (bit8 *)&smpPhyControlReq,
550285242Sachim                      sizeof(smpReqPhyControl_t),
551285242Sachim                      AGSA_SMP_INIT_REQ
552285242Sachim                     );
553285242Sachim  return status;
554285242Sachim}
555285242Sachim
556285242SachimosGLOBAL void
557285242SachimdmReportGeneralSend(
558285242Sachim                    dmRoot_t             *dmRoot,
559285242Sachim                    dmDeviceData_t       *oneDeviceData
560285242Sachim                    )
561285242Sachim{
562285242Sachim  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
563285242Sachim  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
564285242Sachim  agsaRoot_t                *agRoot = dmAllShared->agRoot;
565285242Sachim
566285242Sachim  DM_DBG3(("dmReportGeneralSend: start\n"));
567285242Sachim  DM_DBG3(("dmReportGeneralSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
568285242Sachim  DM_DBG3(("dmReportGeneralSend: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id));
569285242Sachim
570285242Sachim  if (agRoot == agNULL)
571285242Sachim  {
572285242Sachim    DM_DBG1(("dmReportGeneralSend: agRoot is NULL!!!\n"));
573285242Sachim    return;
574285242Sachim  }
575285242Sachim
576285242Sachim  dmSMPStart(
577285242Sachim             dmRoot,
578285242Sachim             agRoot,
579285242Sachim             oneDeviceData,
580285242Sachim             SMP_REPORT_GENERAL,
581285242Sachim             agNULL,
582285242Sachim             0,
583285242Sachim             AGSA_SMP_INIT_REQ
584285242Sachim             );
585285242Sachim  return;
586285242Sachim}
587285242SachimosGLOBAL void
588285242SachimdmReportGeneralRespRcvd(
589285242Sachim                        dmRoot_t              *dmRoot,
590285242Sachim                        agsaRoot_t            *agRoot,
591285242Sachim                        agsaIORequest_t       *agIORequest,
592285242Sachim                        dmDeviceData_t        *oneDeviceData,
593285242Sachim                        dmSMPFrameHeader_t    *frameHeader,
594285242Sachim                        agsaFrameHandle_t     frameHandle
595285242Sachim                        )
596285242Sachim{
597285242Sachim  smpRespReportGeneral_t       dmSMPReportGeneralResp;
598285242Sachim  smpRespReportGeneral_t       *pdmSMPReportGeneralResp;
599285242Sachim  dmIntPortContext_t           *onePortContext = agNULL;
600285242Sachim  dmDiscovery_t                *discovery;
601285242Sachim  dmExpander_t                 *oneExpander = agNULL;
602285242Sachim#ifndef DIRECT_SMP
603285242Sachim  dmSMPRequestBody_t           *dmSMPRequestBody;
604285242Sachim  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
605285242Sachim#endif
606285242Sachim  dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
607285242Sachim  dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
608285242Sachim
609285242Sachim  DM_DBG3(("dmReportGeneralRespRcvd: start\n"));
610285242Sachim  DM_DBG3(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
611285242Sachim  DM_DBG3(("dmReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
612285242Sachim
613285242Sachim#ifndef DIRECT_SMP
614285242Sachim  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
615285242Sachim#endif
616285242Sachim  pdmSMPReportGeneralResp = &dmSMPReportGeneralResp;
617285242Sachim
618285242Sachim  dm_memset(&dmSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t));
619285242Sachim
620285242Sachim#ifdef DIRECT_SMP
621285242Sachim  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
622285242Sachim#else
623285242Sachim  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
624285242Sachim  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
625285242Sachim#endif
626285242Sachim
627285242Sachim  onePortContext = oneDeviceData->dmPortContext;
628285242Sachim  discovery = &(onePortContext->discovery);
629285242Sachim
630285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
631285242Sachim  {
632285242Sachim    DM_DBG1(("dmReportGeneralRespRcvd: invalid port or aborted discovery!!!\n"));
633285242Sachim    return;
634285242Sachim  }
635285242Sachim
636285242Sachim  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
637285242Sachim  {
638285242Sachim    oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneralResp->numOfPhys;
639285242Sachim    oneExpander = oneDeviceData->dmExpander;
640285242Sachim    oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneralResp);
641285242Sachim    oneExpander->configReserved = 0;
642285242Sachim    oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneralResp) ? 1 : 0;
643285242Sachim    oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneralResp) ? 1 : 0;
644285242Sachim    DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
645285242Sachim    DM_DBG3(("dmReportGeneralRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
646285242Sachim    DM_DBG3(("dmReportGeneralRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
647285242Sachim
648285242Sachim    if ( oneExpander->SAS2 == 0 && REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp) == 1)
649285242Sachim    {
650285242Sachim      oneExpander->SAS2 = REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp);
651285242Sachim      DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 Long Response=%d\n", REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp)));
652285242Sachim      dmReportGeneralSend(dmRoot, oneDeviceData);
653285242Sachim      return;
654285242Sachim    }
655285242Sachim
656285242Sachim    DM_DBG3(("dmReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
657285242Sachim      oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
658285242Sachim    DM_DBG3(("dmReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n",
659285242Sachim      oneExpander->configRouteTable, oneExpander->configuring));
660285242Sachim
661285242Sachim    if (oneExpander->configuring == 1)
662285242Sachim    {
663285242Sachim      discovery->retries++;
664285242Sachim      if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
665285242Sachim      {
666285242Sachim        DM_DBG1(("dmReportGeneralRespRcvd: retries are over!!!\n"));
667285242Sachim        DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
668285242Sachim        discovery->retries = 0;
669285242Sachim        /* failed the discovery */
670285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
671285242Sachim      }
672285242Sachim      else
673285242Sachim      {
674285242Sachim        DM_DBG3(("dmReportGeneralRespRcvd: keep retrying\n"));
675285242Sachim        DM_DBG1(("dmReportGeneralRespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
676285242Sachim        DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
677285242Sachim        // start timer for sending ReportGeneral
678285242Sachim        dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
679285242Sachim      }
680285242Sachim    }
681285242Sachim    else
682285242Sachim    {
683285242Sachim      discovery->retries = 0;
684285242Sachim      dmDiscoverSend(dmRoot, oneDeviceData);
685285242Sachim    }
686285242Sachim  }
687285242Sachim  else
688285242Sachim  {
689285242Sachim     DM_DBG1(("dmReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery !!!\n", frameHeader->smpFunctionResult));
690285242Sachim     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
691285242Sachim  }
692285242Sachim  return;
693285242Sachim}
694285242Sachim
695285242SachimosGLOBAL void
696285242SachimdmReportGeneral2RespRcvd(
697285242Sachim                        dmRoot_t              *dmRoot,
698285242Sachim                        agsaRoot_t            *agRoot,
699285242Sachim                        agsaIORequest_t       *agIORequest,
700285242Sachim                        dmDeviceData_t        *oneDeviceData,
701285242Sachim                        dmSMPFrameHeader_t    *frameHeader,
702285242Sachim                        agsaFrameHandle_t     frameHandle
703285242Sachim                        )
704285242Sachim{
705285242Sachim  smpRespReportGeneral2_t      dmSMPReportGeneral2Resp;
706285242Sachim  smpRespReportGeneral2_t      *pdmSMPReportGeneral2Resp;
707285242Sachim  dmExpander_t                 *oneExpander = agNULL;
708285242Sachim  dmIntPortContext_t           *onePortContext = agNULL;
709285242Sachim  dmDiscovery_t                *discovery;
710285242Sachim#ifndef DIRECT_SMP
711285242Sachim  dmSMPRequestBody_t           *dmSMPRequestBody;
712285242Sachim  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
713285242Sachim#endif
714285242Sachim  bit32                        ConfiguresOthers = agFALSE;
715285242Sachim  dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
716285242Sachim  dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
717285242Sachim
718285242Sachim
719285242Sachim  DM_DBG2(("dmReportGeneral2RespRcvd: start\n"));
720285242Sachim  DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
721285242Sachim  DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
722285242Sachim
723285242Sachim#ifndef DIRECT_SMP
724285242Sachim  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
725285242Sachim#endif
726285242Sachim  pdmSMPReportGeneral2Resp = &dmSMPReportGeneral2Resp;
727285242Sachim
728285242Sachim  dm_memset(&dmSMPReportGeneral2Resp, 0, sizeof(smpRespReportGeneral2_t));
729285242Sachim
730285242Sachim#ifdef DIRECT_SMP
731285242Sachim  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
732285242Sachim#else
733285242Sachim  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
734285242Sachim  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
735285242Sachim#endif
736285242Sachim
737285242Sachim  onePortContext = oneDeviceData->dmPortContext;
738285242Sachim  discovery = &(onePortContext->discovery);
739285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
740285242Sachim  {
741285242Sachim    DM_DBG1(("dmReportGeneral2RespRcvd: invalid port or aborted discovery!!!\n"));
742285242Sachim    return;
743285242Sachim  }
744285242Sachim
745285242Sachim/* ??? start here */
746285242Sachim  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
747285242Sachim  {
748285242Sachim    oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneral2Resp->numOfPhys;
749285242Sachim    oneExpander = oneDeviceData->dmExpander;
750285242Sachim    oneExpander->routingIndex = (bit16) SAS2_REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneral2Resp);
751285242Sachim    oneExpander->configReserved = 0;
752285242Sachim    oneExpander->configRouteTable = SAS2_REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneral2Resp) ? 1 : 0;
753285242Sachim    oneExpander->configuring = SAS2_REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneral2Resp) ? 1 : 0;
754285242Sachim    oneExpander->TTTSupported = SAS2_REPORT_GENERAL_IS_TABLE_TO_TABLE_SUPPORTED(pdmSMPReportGeneral2Resp) ? 1 : 0;
755285242Sachim    ConfiguresOthers = SAS2_REPORT_GENERAL_IS_CONFIGURES_OTHERS(pdmSMPReportGeneral2Resp) ? 1 : 0;
756285242Sachim
757285242Sachim    DM_DBG2(("dmReportGeneral2RespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
758285242Sachim    DM_DBG3(("dmReportGeneral2RespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
759285242Sachim    DM_DBG3(("dmReportGeneral2RespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
760285242Sachim
761285242Sachim
762285242Sachim    DM_DBG2(("dmReportGeneral2RespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
763285242Sachim      oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
764285242Sachim    DM_DBG2(("dmReportGeneral2RespRcvd: configRouteTable=%d configuring=%d\n",
765285242Sachim      oneExpander->configRouteTable, oneExpander->configuring));
766285242Sachim    if (ConfiguresOthers)
767285242Sachim    {
768285242Sachim      DM_DBG2(("dmReportGeneral2RespRcvd: ConfiguresOthers is true\n"));
769285242Sachim      discovery->ConfiguresOthers = agTRUE;
770285242Sachim    }
771285242Sachim    if (oneExpander->configuring == 1)
772285242Sachim    {
773285242Sachim      discovery->retries++;
774285242Sachim      if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
775285242Sachim      {
776285242Sachim        DM_DBG1(("dmReportGeneral2RespRcvd: retries are over!!!\n"));
777285242Sachim        DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
778285242Sachim
779285242Sachim        discovery->retries = 0;
780285242Sachim        /* failed the discovery */
781285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
782285242Sachim      }
783285242Sachim      else
784285242Sachim      {
785285242Sachim        DM_DBG2(("dmReportGeneral2RespRcvd: keep retrying\n"));
786285242Sachim        DM_DBG1(("dmReportGeneral2RespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
787285242Sachim        DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
788285242Sachim        // start timer for sending ReportGeneral
789285242Sachim        dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
790285242Sachim      }
791285242Sachim    }
792285242Sachim    else
793285242Sachim    {
794285242Sachim      discovery->retries = 0;
795285242Sachim      dmDiscoverSend(dmRoot, oneDeviceData);
796285242Sachim    }
797285242Sachim  }
798285242Sachim  else
799285242Sachim  {
800285242Sachim     DM_DBG2(("dmReportGeneral2RespRcvd: SMP failed, stopping discovery\n"));
801285242Sachim     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
802285242Sachim  }
803285242Sachim
804285242Sachim  return;
805285242Sachim}
806285242Sachim
807285242Sachim
808285242SachimosGLOBAL void
809285242SachimdmDiscoverSend(
810285242Sachim               dmRoot_t             *dmRoot,
811285242Sachim               dmDeviceData_t       *oneDeviceData
812285242Sachim              )
813285242Sachim{
814285242Sachim  dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
815285242Sachim  dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
816285242Sachim  agsaRoot_t                *agRoot = dmAllShared->agRoot;
817285242Sachim  smpReqDiscover_t          smpDiscoverReq;
818285242Sachim  dmExpander_t              *oneExpander;
819285242Sachim
820285242Sachim  DM_DBG3(("dmDiscoverSend: start\n"));
821285242Sachim  DM_DBG3(("dmDiscoverSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
822285242Sachim  oneExpander = oneDeviceData->dmExpander;
823285242Sachim  DM_DBG3(("dmDiscoverSend: oneExpander %p did %d\n", oneExpander, oneExpander->id));
824285242Sachim  DM_DBG3(("dmDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId));
825285242Sachim
826285242Sachim  dm_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t));
827285242Sachim
828285242Sachim  smpDiscoverReq.reserved1 = 0;
829285242Sachim  smpDiscoverReq.reserved2 = 0;
830285242Sachim  smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId;
831285242Sachim  smpDiscoverReq.reserved3 = 0;
832285242Sachim
833285242Sachim  dmSMPStart(
834285242Sachim             dmRoot,
835285242Sachim             agRoot,
836285242Sachim             oneDeviceData,
837285242Sachim             SMP_DISCOVER,
838285242Sachim             (bit8 *)&smpDiscoverReq,
839285242Sachim             sizeof(smpReqDiscover_t),
840285242Sachim             AGSA_SMP_INIT_REQ
841285242Sachim             );
842285242Sachim  return;
843285242Sachim}
844285242Sachim
845285242SachimosGLOBAL void
846285242SachimdmDiscoverRespRcvd(
847285242Sachim                   dmRoot_t              *dmRoot,
848285242Sachim                   agsaRoot_t            *agRoot,
849285242Sachim                   agsaIORequest_t       *agIORequest,
850285242Sachim                   dmDeviceData_t        *oneDeviceData,
851285242Sachim                   dmSMPFrameHeader_t    *frameHeader,
852285242Sachim                   agsaFrameHandle_t     frameHandle
853285242Sachim                  )
854285242Sachim{
855285242Sachim  dmIntPortContext_t           *onePortContext = agNULL;
856285242Sachim  dmDiscovery_t                *discovery;
857285242Sachim  smpRespDiscover_t            *pdmSMPDiscoverResp;
858285242Sachim#ifndef DIRECT_SMP
859285242Sachim  dmSMPRequestBody_t           *dmSMPRequestBody;
860285242Sachim  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
861285242Sachim#endif
862285242Sachim  dmExpander_t                 *oneExpander = agNULL;
863285242Sachim
864285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: start\n"));
865285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
866285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
867285242Sachim
868285242Sachim  onePortContext = oneDeviceData->dmPortContext;
869285242Sachim  oneExpander = oneDeviceData->dmExpander;
870285242Sachim  discovery = &(onePortContext->discovery);
871285242Sachim#ifndef DIRECT_SMP
872285242Sachim  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
873285242Sachim#endif
874285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
875285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
876285242Sachim
877285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
878285242Sachim  {
879285242Sachim    DM_DBG1(("dmDiscoverRespRcvd: invalid port or aborted discovery!!!\n"));
880285242Sachim    return;
881285242Sachim  }
882285242Sachim
883285242Sachim  pdmSMPDiscoverResp = &(discovery->SMPDiscoverResp);
884285242Sachim
885285242Sachim#ifdef DIRECT_SMP
886285242Sachim  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
887285242Sachim#else
888285242Sachim  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
889285242Sachim  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
890285242Sachim#endif
891285242Sachim
892285242Sachim  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
893285242Sachim  {
894285242Sachim    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
895285242Sachim    {
896285242Sachim      dmUpStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
897285242Sachim    }
898285242Sachim    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
899285242Sachim    {
900285242Sachim      dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
901285242Sachim    }
902285242Sachim    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
903285242Sachim    {
904285242Sachim      /* not done with configuring routing
905285242Sachim         1. set the timer
906285242Sachim         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
907285242Sachim      */
908285242Sachim      DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
909285242Sachim      DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
910285242Sachim      dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
911285242Sachim
912285242Sachim      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
913285242Sachim    }
914285242Sachim    else
915285242Sachim    {
916285242Sachim      /* nothing */
917285242Sachim    }
918285242Sachim  }
919285242Sachim  else if (frameHeader->smpFunctionResult == PHY_VACANT)
920285242Sachim  {
921285242Sachim    DM_DBG3(("dmDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
922285242Sachim    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
923285242Sachim    {
924285242Sachim      dmUpStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
925285242Sachim    }
926285242Sachim    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
927285242Sachim    {
928285242Sachim      dmDownStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
929285242Sachim    }
930285242Sachim    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
931285242Sachim    {
932285242Sachim      /* not done with configuring routing
933285242Sachim         1. set the timer
934285242Sachim         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
935285242Sachim      */
936285242Sachim      DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
937285242Sachim      DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
938285242Sachim      dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
939285242Sachim
940285242Sachim      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
941285242Sachim    }
942285242Sachim  }
943285242Sachim  else
944285242Sachim  {
945285242Sachim     DM_DBG1(("dmDiscoverRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n",
946285242Sachim               frameHeader->smpFunctionResult));
947285242Sachim     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
948285242Sachim  }
949285242Sachim
950285242Sachim
951285242Sachim
952285242Sachim  return;
953285242Sachim}
954285242Sachim
955285242SachimosGLOBAL void
956285242SachimdmDiscover2RespRcvd(
957285242Sachim                   dmRoot_t              *dmRoot,
958285242Sachim                   agsaRoot_t            *agRoot,
959285242Sachim                   agsaIORequest_t       *agIORequest,
960285242Sachim                   dmDeviceData_t        *oneDeviceData,
961285242Sachim                   dmSMPFrameHeader_t    *frameHeader,
962285242Sachim                   agsaFrameHandle_t     frameHandle
963285242Sachim                  )
964285242Sachim{
965285242Sachim  dmIntPortContext_t           *onePortContext = agNULL;
966285242Sachim  dmDiscovery_t                *discovery;
967285242Sachim  smpRespDiscover2_t           *pdmSMPDiscover2Resp;
968285242Sachim#ifndef DIRECT_SMP
969285242Sachim  dmSMPRequestBody_t           *dmSMPRequestBody;
970285242Sachim  dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
971285242Sachim#endif
972285242Sachim  dmExpander_t                 *oneExpander = agNULL;
973285242Sachim
974285242Sachim  DM_DBG2(("dmDiscover2RespRcvd: start\n"));
975285242Sachim  DM_DBG2(("dmDiscover2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
976285242Sachim  DM_DBG2(("dmDiscover2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
977285242Sachim
978285242Sachim  onePortContext = oneDeviceData->dmPortContext;
979285242Sachim  oneExpander = oneDeviceData->dmExpander;
980285242Sachim  discovery = &(onePortContext->discovery);
981285242Sachim#ifndef DIRECT_SMP
982285242Sachim  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
983285242Sachim#endif
984285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
985285242Sachim  DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
986285242Sachim
987285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
988285242Sachim  {
989285242Sachim    DM_DBG1(("dmDiscover2RespRcvd: invalid port or aborted discovery!!!\n"));
990285242Sachim    return;
991285242Sachim  }
992285242Sachim
993285242Sachim  pdmSMPDiscover2Resp = &(discovery->SMPDiscover2Resp);
994285242Sachim
995285242Sachim#ifdef DIRECT_SMP
996285242Sachim  saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
997285242Sachim#else
998285242Sachim  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
999285242Sachim  saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1000285242Sachim#endif
1001285242Sachim
1002285242Sachim  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
1003285242Sachim  {
1004285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: phyIdentifier %d\n", pdmSMPDiscover2Resp->phyIdentifier));
1005285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: NegotiatedSSCHWMuxingSupported %d\n", pdmSMPDiscover2Resp->NegotiatedSSCHWMuxingSupported));
1006285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: SAS2_MUXING_SUPPORTED %d\n", SAS2_DISCRSP_IS_MUXING_SUPPORTED(pdmSMPDiscover2Resp)));
1007285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: NegotiatedLogicalLinkRate %d\n", pdmSMPDiscover2Resp->NegotiatedLogicalLinkRate));
1008285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: ReasonNegotiatedPhysicalLinkRate %d\n", pdmSMPDiscover2Resp->ReasonNegotiatedPhysicalLinkRate));
1009285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LOGICAL_LINKRATE %d\n", SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pdmSMPDiscover2Resp)));
1010285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LINKRATE %d\n", SAS2_DISCRSP_GET_LINKRATE(pdmSMPDiscover2Resp)));
1011285242Sachim
1012285242Sachim//NegotiatedLogicalLinkRate 13
1013285242Sachim//ReasonNegotiatedPhysicalLinkRate 94
1014285242Sachim    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
1015285242Sachim    {
1016285242Sachim      dmUpStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
1017285242Sachim    }
1018285242Sachim    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
1019285242Sachim    {
1020285242Sachim      dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
1021285242Sachim    }
1022285242Sachim    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
1023285242Sachim    {
1024285242Sachim      /* not done with configuring routing
1025285242Sachim         1. set the timer
1026285242Sachim         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
1027285242Sachim      */
1028285242Sachim      DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
1029285242Sachim      DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
1030285242Sachim      dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1031285242Sachim      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
1032285242Sachim    }
1033285242Sachim    else
1034285242Sachim    {
1035285242Sachim      /* nothing */
1036285242Sachim    }
1037285242Sachim  }
1038285242Sachim  else if (frameHeader->smpFunctionResult == PHY_VACANT)
1039285242Sachim  {
1040285242Sachim    DM_DBG2(("dmDiscover2RespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
1041285242Sachim    if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
1042285242Sachim    {
1043285242Sachim      dmUpStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
1044285242Sachim    }
1045285242Sachim    else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
1046285242Sachim    {
1047285242Sachim      dmDownStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
1048285242Sachim    }
1049285242Sachim    else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
1050285242Sachim    {
1051285242Sachim      /* not done with configuring routing
1052285242Sachim         1. set the timer
1053285242Sachim         2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
1054285242Sachim      */
1055285242Sachim      DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
1056285242Sachim      DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
1057285242Sachim      dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
1058285242Sachim      dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
1059285242Sachim    }
1060285242Sachim    else
1061285242Sachim    {
1062285242Sachim      /* nothing */
1063285242Sachim    }
1064285242Sachim  }
1065285242Sachim  else
1066285242Sachim  {
1067285242Sachim     DM_DBG1(("dmDiscover2RespRcvd: Discovery Error SMP function return result error=0x%x\n",
1068285242Sachim               frameHeader->smpFunctionResult));
1069285242Sachim     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1070285242Sachim  }
1071285242Sachim  return;
1072285242Sachim}
1073285242Sachim
1074285242Sachim#ifdef NOT_YET
1075285242SachimosGLOBAL void
1076285242SachimtdsaDiscoverList2Send(
1077285242Sachim                 tiRoot_t             *tiRoot,
1078285242Sachim                 tdsaDeviceData_t     *oneDeviceData
1079285242Sachim                 )
1080285242Sachim{
1081285242Sachim  agsaRoot_t            *agRoot;
1082285242Sachim  tdsaExpander_t        *oneExpander;
1083285242Sachim  smpReqDiscoverList2_t smpDiscoverListReq;
1084285242Sachim
1085285242Sachim  DM_DBG1(("tdsaDiscoverList2Send: start\n"));
1086285242Sachim  DM_DBG1(("tdsaDiscoverList2Send: device %p did %d\n", oneDeviceData, oneDeviceData->id));
1087285242Sachim  agRoot = oneDeviceData->agRoot;
1088285242Sachim  oneExpander = oneDeviceData->dmExpander;
1089285242Sachim  DM_DBG1(("tdsaDiscoverList2Send: phyID 0x%x\n", oneExpander->discoveringPhyId));
1090285242Sachim
1091285242Sachim
1092285242Sachim  osti_memset(&smpDiscoverListReq, 0, sizeof(smpReqDiscoverList2_t));
1093285242Sachim
1094285242Sachim  smpDiscoverListReq.reserved1 = 0;
1095285242Sachim  smpDiscoverListReq.StartingPhyID = 0;
1096285242Sachim  smpDiscoverListReq.MaxNumDiscoverDesc = 40; /* 40 for SHORT FORMAT; 8 for Long Format; SAS2 p630 */
1097285242Sachim  smpDiscoverListReq.byte10 = 0x2; /* phy filter; all but "no device attached" */
1098285242Sachim  smpDiscoverListReq.byte11 = 0x1; /* descriptor type; SHORT FORMAT */
1099285242Sachim
1100285242Sachim
1101285242Sachim  dmSMPStart(
1102285242Sachim             dmRoot,
1103285242Sachim             agRoot,
1104285242Sachim             oneDeviceData,
1105285242Sachim             SMP_DISCOVER_LIST,
1106285242Sachim             (bit8 *)&smpDiscoverListReq,
1107285242Sachim             sizeof(smpReqDiscoverList2_t),
1108285242Sachim             AGSA_SMP_INIT_REQ,
1109285242Sachim             agNULL
1110285242Sachim             );
1111285242Sachim  return;
1112285242Sachim}
1113285242Sachim
1114285242SachimosGLOBAL void
1115285242SachimtdsaDiscoverList2RespRcvd(
1116285242Sachim                     tiRoot_t              *tiRoot,
1117285242Sachim                     agsaRoot_t            *agRoot,
1118285242Sachim                     tdsaDeviceData_t      *oneDeviceData,
1119285242Sachim                     tdssSMPFrameHeader_t  *frameHeader,
1120285242Sachim                     agsaFrameHandle_t     frameHandle
1121285242Sachim                     )
1122285242Sachim{
1123285242Sachim  return;
1124285242Sachim}
1125285242Sachim#endif /* not yet */
1126285242Sachim
1127285242Sachim/*****************************************************************************
1128285242Sachim*! \brief  dmReportPhySataSend
1129285242Sachim*
1130285242Sachim*  Purpose:  This function sends Report Phy SATA to a device.
1131285242Sachim*
1132285242Sachim*  \param   dmRoot: Pointer to the OS Specific module allocated dmRoot_t
1133285242Sachim*                   instance.
1134285242Sachim*  \param   oneDeviceData: Pointer to the device data.
1135285242Sachim*  \param   phyId: Phy Identifier.
1136285242Sachim*
1137285242Sachim*  \return:
1138285242Sachim*           None
1139285242Sachim*
1140285242Sachim*   \note:
1141285242Sachim*
1142285242Sachim*****************************************************************************/
1143285242SachimosGLOBAL void
1144285242SachimdmReportPhySataSend(
1145285242Sachim                    dmRoot_t           *dmRoot,
1146285242Sachim                    dmDeviceData_t     *oneDeviceData,
1147285242Sachim                    bit8               phyId
1148285242Sachim                    )
1149285242Sachim{
1150285242Sachim  dmIntRoot_t        *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
1151285242Sachim  dmIntContext_t     *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
1152285242Sachim  agsaRoot_t         *agRoot      = dmAllShared->agRoot;
1153285242Sachim  dmExpander_t       *oneExpander;
1154285242Sachim  smpReqReportPhySata_t  smpReportPhySataReq;
1155285242Sachim
1156285242Sachim  DM_DBG3(("dmReportPhySataSend: start\n"));
1157285242Sachim  DM_DBG3(("dmReportPhySataSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
1158285242Sachim  DM_DBG3(("dmReportPhySataSend: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1159285242Sachim  DM_DBG3(("dmReportPhySataSend: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1160285242Sachim
1161285242Sachim  oneExpander = oneDeviceData->dmExpander;
1162285242Sachim
1163285242Sachim  if (oneExpander == agNULL)
1164285242Sachim  {
1165285242Sachim    DM_DBG1(("dmReportPhySataSend: Error!!! expander is NULL\n"));
1166285242Sachim    return;
1167285242Sachim  }
1168285242Sachim  DM_DBG3(("dmReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
1169285242Sachim  DM_DBG3(("dmReportPhySataSend: phyid %d\n", phyId));
1170285242Sachim
1171285242Sachim  dm_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t));
1172285242Sachim
1173285242Sachim  smpReportPhySataReq.phyIdentifier = phyId;
1174285242Sachim
1175285242Sachim  dmSMPStart(
1176285242Sachim             dmRoot,
1177285242Sachim             agRoot,
1178285242Sachim             oneExpander->dmDevice,
1179285242Sachim             SMP_REPORT_PHY_SATA,
1180285242Sachim             (bit8 *)&smpReportPhySataReq,
1181285242Sachim             sizeof(smpReqReportPhySata_t),
1182285242Sachim             AGSA_SMP_INIT_REQ
1183285242Sachim             );
1184285242Sachim
1185285242Sachim  return;
1186285242Sachim}
1187285242Sachim/*****************************************************************************
1188285242Sachim*! \brief  dmReportPhySataRcvd
1189285242Sachim*
1190285242Sachim*  Purpose:  This function processes Report Phy SATA response.
1191285242Sachim*
1192285242Sachim*  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
1193285242Sachim*                   instance.
1194285242Sachim*  \param   agRoot: Pointer to chip/driver Instance.
1195285242Sachim*  \param   oneDeviceData: Pointer to the device data.
1196285242Sachim*  \param   frameHeader: Pointer to SMP frame header.
1197285242Sachim*  \param   frameHandle: A Handle used to refer to the response frame
1198285242Sachim*
1199285242Sachim*  \return:
1200285242Sachim*           None
1201285242Sachim*
1202285242Sachim*   \note:
1203285242Sachim*
1204285242Sachim*****************************************************************************/
1205285242Sachim
1206285242SachimosGLOBAL void
1207285242SachimdmReportPhySataRcvd(
1208285242Sachim                    dmRoot_t              *dmRoot,
1209285242Sachim                    agsaRoot_t            *agRoot,
1210285242Sachim                    agsaIORequest_t       *agIORequest,
1211285242Sachim                    dmDeviceData_t        *oneDeviceData,
1212285242Sachim                    dmSMPFrameHeader_t    *frameHeader,
1213285242Sachim                    agsaFrameHandle_t     frameHandle
1214285242Sachim                   )
1215285242Sachim{
1216285242Sachim  smpRespReportPhySata_t      SMPreportPhySataResp;
1217285242Sachim  smpRespReportPhySata_t      *pSMPReportPhySataResp;
1218285242Sachim  dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
1219285242Sachim  dmIntPortContext_t          *onePortContext = agNULL;
1220285242Sachim  agsaFisRegDeviceToHost_t    *fis;
1221285242Sachim  dmDeviceData_t              *SataDevice = agNULL;
1222285242Sachim#ifndef DIRECT_SMP
1223285242Sachim  dmSMPRequestBody_t          *tdSMPRequestBody;
1224285242Sachim#endif
1225285242Sachim  bit8                        sataDeviceType;
1226285242Sachim  bit8                        *bit8fis;
1227285242Sachim  bit8                        i = 0;
1228285242Sachim  bit32                       a = 0;
1229285242Sachim  bit8                        bit8fisarray[20];
1230285242Sachim
1231285242Sachim  DM_DBG3(("dmReportPhySataRcvd: start\n"));
1232285242Sachim  DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1233285242Sachim  DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1234285242Sachim
1235285242Sachim#ifndef DIRECT_SMP
1236285242Sachim  tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
1237285242Sachim#endif
1238285242Sachim  /* get the current sata device hanlde stored in the expander structure */
1239285242Sachim  if (oneExpander != agNULL)
1240285242Sachim  {
1241285242Sachim      SataDevice = oneExpander->dmDeviceToProcess;
1242285242Sachim  }
1243285242Sachim
1244285242Sachim  if (SataDevice != agNULL)
1245285242Sachim  {
1246285242Sachim    DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
1247285242Sachim    DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
1248285242Sachim  }
1249285242Sachim  else
1250285242Sachim  {
1251285242Sachim    DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
1252285242Sachim  }
1253285242Sachim
1254285242Sachim  pSMPReportPhySataResp = &SMPreportPhySataResp;
1255285242Sachim
1256285242Sachim#ifdef DIRECT_SMP
1257285242Sachim  saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1258285242Sachim#else
1259285242Sachim  saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1260285242Sachim#endif
1261285242Sachim
1262285242Sachim  /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
1263285242Sachim
1264285242Sachim#ifndef DIRECT_SMP
1265285242Sachim  ostiFreeMemory(
1266285242Sachim                 dmRoot,
1267285242Sachim                 tdSMPRequestBody->IndirectSMPReqosMemHandle,
1268285242Sachim                 tdSMPRequestBody->IndirectSMPReqLen
1269285242Sachim                );
1270285242Sachim  ostiFreeMemory(
1271285242Sachim                 dmRoot,
1272285242Sachim                 tdSMPRequestBody->IndirectSMPResposMemHandle,
1273285242Sachim                 tdSMPRequestBody->IndirectSMPRespLen
1274285242Sachim                );
1275285242Sachim#endif
1276285242Sachim
1277285242Sachim  onePortContext = oneDeviceData->dmPortContext;
1278285242Sachim
1279285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1280285242Sachim  {
1281285242Sachim    DM_DBG1(("dmReportPhySataRcvd: invalid port or aborted discovery!!!\n"));
1282285242Sachim    return;
1283285242Sachim  }
1284285242Sachim
1285285242Sachim  if (SataDevice == agNULL)
1286285242Sachim  {
1287285242Sachim    DM_DBG1(("dmReportPhySataRcvd: SataDevice is NULL, wrong\n"));
1288285242Sachim    dmDiscoverAbort(dmRoot, onePortContext);
1289285242Sachim    return;
1290285242Sachim  }
1291285242Sachim
1292285242Sachim  if (frameHeader->smpFunctionResult == PHY_VACANT )
1293285242Sachim  {
1294285242Sachim     DM_DBG1(("dmReportPhySataRcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
1295285242Sachim     return;
1296285242Sachim  }
1297285242Sachim
1298285242Sachim  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED  )
1299285242Sachim  {
1300285242Sachim    fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
1301285242Sachim    if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
1302285242Sachim    {
1303285242Sachim      /* save signature */
1304285242Sachim      DM_DBG3(("dmReportPhySataRcvd: saves the signature\n"));
1305285242Sachim      /* saves signature */
1306285242Sachim      SataDevice->satSignature[0] = fis->d.sectorCount;
1307285242Sachim      SataDevice->satSignature[1] = fis->d.lbaLow;
1308285242Sachim      SataDevice->satSignature[2] = fis->d.lbaMid;
1309285242Sachim      SataDevice->satSignature[3] = fis->d.lbaHigh;
1310285242Sachim      SataDevice->satSignature[4] = fis->d.device;
1311285242Sachim      SataDevice->satSignature[5] = 0;
1312285242Sachim      SataDevice->satSignature[6] = 0;
1313285242Sachim      SataDevice->satSignature[7] = 0;
1314285242Sachim
1315285242Sachim      DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1316285242Sachim       SataDevice->satSignature[0],
1317285242Sachim       SataDevice->satSignature[1],
1318285242Sachim       SataDevice->satSignature[2],
1319285242Sachim       SataDevice->satSignature[3],
1320285242Sachim       SataDevice->satSignature[4]));
1321285242Sachim
1322285242Sachim       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1323285242Sachim       if( sataDeviceType == SATA_ATAPI_DEVICE)
1324285242Sachim       {
1325285242Sachim          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1326285242Sachim       }
1327285242Sachim       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1328285242Sachim    }
1329285242Sachim    /* Handling DataDomain buggy FIS */
1330285242Sachim    else if (fis->h.error == REG_DEV_TO_HOST_FIS)
1331285242Sachim    {
1332285242Sachim      /* needs to flip fis to host order */
1333285242Sachim      bit8fis = (bit8*)fis;
1334285242Sachim      for (i=0;i<5;i++)
1335285242Sachim      {
1336285242Sachim        a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
1337285242Sachim        DM_DBG3(("dmReportPhySataRcvd: a 0x%8x\n", a));
1338285242Sachim        bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
1339285242Sachim        bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
1340285242Sachim        bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
1341285242Sachim        bit8fisarray[4*i+3] = (a & 0x000000FF);
1342285242Sachim        bit8fis = bit8fis + 4;
1343285242Sachim      }
1344285242Sachim      fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
1345285242Sachim      /* save signature */
1346285242Sachim      DM_DBG3(("dmReportPhySataRcvd: DataDomain ATAPI saves the signature\n"));
1347285242Sachim      /* saves signature */
1348285242Sachim      SataDevice->satSignature[0] = fis->d.sectorCount;
1349285242Sachim      SataDevice->satSignature[1] = fis->d.lbaLow;
1350285242Sachim      SataDevice->satSignature[2] = fis->d.lbaMid;
1351285242Sachim      SataDevice->satSignature[3] = fis->d.lbaHigh;
1352285242Sachim      SataDevice->satSignature[4] = fis->d.device;
1353285242Sachim      SataDevice->satSignature[5] = 0;
1354285242Sachim      SataDevice->satSignature[6] = 0;
1355285242Sachim      SataDevice->satSignature[7] = 0;
1356285242Sachim
1357285242Sachim      DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1358285242Sachim       SataDevice->satSignature[0],
1359285242Sachim       SataDevice->satSignature[1],
1360285242Sachim       SataDevice->satSignature[2],
1361285242Sachim       SataDevice->satSignature[3],
1362285242Sachim       SataDevice->satSignature[4]));
1363285242Sachim
1364285242Sachim       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1365285242Sachim       if( sataDeviceType == SATA_ATAPI_DEVICE)
1366285242Sachim       {
1367285242Sachim          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1368285242Sachim       }
1369285242Sachim       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1370285242Sachim    }
1371285242Sachim    else
1372285242Sachim    {
1373285242Sachim      DM_DBG3(("dmReportPhySataRcvd: getting next stp bride\n"));
1374285242Sachim    }
1375285242Sachim
1376285242Sachim    /* Continure to report this STP device to TD*/
1377285242Sachim    if (SataDevice->ExpDevice != agNULL)
1378285242Sachim    {
1379285242Sachim       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
1380285242Sachim    }
1381285242Sachim    else
1382285242Sachim    {
1383285242Sachim       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
1384285242Sachim    }
1385285242Sachim  }
1386285242Sachim  else
1387285242Sachim  {
1388285242Sachim    DM_DBG3(("dmReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n",
1389285242Sachim             frameHeader->smpFunctionResult));
1390285242Sachim    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1391285242Sachim  }
1392285242Sachim
1393285242Sachim  return;
1394285242Sachim}
1395285242Sachim
1396285242Sachim/*****************************************************************************
1397285242Sachim*! \brief  dmReportPhySata2Rcvd
1398285242Sachim*
1399285242Sachim*  Purpose:  This function processes SAS2.0 Report Phy SATA response.
1400285242Sachim*
1401285242Sachim*  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
1402285242Sachim*                   instance.
1403285242Sachim*  \param   agRoot: Pointer to chip/driver Instance.
1404285242Sachim*  \param   oneDeviceData: Pointer to the device data.
1405285242Sachim*  \param   frameHeader: Pointer to SMP frame header.
1406285242Sachim*  \param   frameHandle: A Handle used to refer to the response frame
1407285242Sachim*
1408285242Sachim*  \return:
1409285242Sachim*           None
1410285242Sachim*
1411285242Sachim*   \note:
1412285242Sachim*
1413285242Sachim*****************************************************************************/
1414285242SachimosGLOBAL void
1415285242SachimdmReportPhySata2Rcvd(
1416285242Sachim                    dmRoot_t              *dmRoot,
1417285242Sachim                    agsaRoot_t            *agRoot,
1418285242Sachim                    agsaIORequest_t       *agIORequest,
1419285242Sachim                    dmDeviceData_t        *oneDeviceData,
1420285242Sachim                    dmSMPFrameHeader_t    *frameHeader,
1421285242Sachim                    agsaFrameHandle_t     frameHandle
1422285242Sachim                   )
1423285242Sachim{
1424285242Sachim   smpRespReportPhySata2_t      SMPreportPhySataResp;
1425285242Sachim   smpRespReportPhySata2_t      *pSMPReportPhySataResp;
1426285242Sachim   dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
1427285242Sachim   dmIntPortContext_t          *onePortContext = agNULL;
1428285242Sachim   agsaFisRegDeviceToHost_t    *fis;
1429285242Sachim   dmDeviceData_t              *SataDevice = agNULL;
1430285242Sachim#ifndef DIRECT_SMP
1431285242Sachim   dmSMPRequestBody_t          *tdSMPRequestBody;
1432285242Sachim#endif
1433285242Sachim   bit8                         sataDeviceType = 0;
1434285242Sachim   bit8                        *bit8fis;
1435285242Sachim   bit8                        i = 0;
1436285242Sachim   bit32                       a = 0;
1437285242Sachim   bit8                        bit8fisarray[20];
1438285242Sachim
1439285242Sachim   DM_DBG3(("dmReportPhySata2Rcvd: start\n"));
1440285242Sachim   DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1441285242Sachim   DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1442285242Sachim
1443285242Sachim#ifndef DIRECT_SMP
1444285242Sachim   tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
1445285242Sachim#endif
1446285242Sachim   /* get the current sata device hanlde stored in the expander structure */
1447285242Sachim   if (oneExpander != agNULL)
1448285242Sachim   {
1449285242Sachim     SataDevice = oneExpander->dmDeviceToProcess;
1450285242Sachim   }
1451285242Sachim
1452285242Sachim   if (SataDevice != agNULL)
1453285242Sachim   {
1454285242Sachim     DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
1455285242Sachim     DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
1456285242Sachim   }
1457285242Sachim   else
1458285242Sachim   {
1459285242Sachim     DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
1460285242Sachim   }
1461285242Sachim
1462285242Sachim  pSMPReportPhySataResp = &SMPreportPhySataResp;
1463285242Sachim
1464285242Sachim#ifdef DIRECT_SMP
1465285242Sachim   saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1466285242Sachim#else
1467285242Sachim   saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
1468285242Sachim#endif
1469285242Sachim
1470285242Sachim   /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
1471285242Sachim
1472285242Sachim#ifndef DIRECT_SMP
1473285242Sachim   ostiFreeMemory(
1474285242Sachim                  dmRoot,
1475285242Sachim                  tdSMPRequestBody->IndirectSMPReqosMemHandle,
1476285242Sachim                  tdSMPRequestBody->IndirectSMPReqLen
1477285242Sachim                 );
1478285242Sachim   ostiFreeMemory(
1479285242Sachim                  dmRoot,
1480285242Sachim                  tdSMPRequestBody->IndirectSMPResposMemHandle,
1481285242Sachim                  tdSMPRequestBody->IndirectSMPRespLen
1482285242Sachim                 );
1483285242Sachim#endif
1484285242Sachim
1485285242Sachim   onePortContext = oneDeviceData->dmPortContext;
1486285242Sachim
1487285242Sachim   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1488285242Sachim   {
1489285242Sachim     DM_DBG1(("dmReportPhySata2Rcvd: invalid port or aborted discovery!!!\n"));
1490285242Sachim     return;
1491285242Sachim   }
1492285242Sachim
1493285242Sachim   if (SataDevice == agNULL)
1494285242Sachim   {
1495285242Sachim     DM_DBG1(("dmReportPhySata2Rcvd: SataDevice is NULL, wrong\n"));
1496285242Sachim     dmDiscoverAbort(dmRoot, onePortContext);
1497285242Sachim     return;
1498285242Sachim   }
1499285242Sachim
1500285242Sachim   if ( frameHeader->smpFunctionResult == PHY_VACANT )
1501285242Sachim   {
1502285242Sachim      DM_DBG1(("dmReportPhySata2Rcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
1503285242Sachim      return;
1504285242Sachim   }
1505285242Sachim
1506285242Sachim   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
1507285242Sachim   {
1508285242Sachim     fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
1509285242Sachim     if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
1510285242Sachim     {
1511285242Sachim       /* save signature */
1512285242Sachim       DM_DBG3(("dmReportPhySata2Rcvd: saves the signature\n"));
1513285242Sachim       /* saves signature */
1514285242Sachim       SataDevice->satSignature[0] = fis->d.sectorCount;
1515285242Sachim       SataDevice->satSignature[1] = fis->d.lbaLow;
1516285242Sachim       SataDevice->satSignature[2] = fis->d.lbaMid;
1517285242Sachim       SataDevice->satSignature[3] = fis->d.lbaHigh;
1518285242Sachim       SataDevice->satSignature[4] = fis->d.device;
1519285242Sachim       SataDevice->satSignature[5] = 0;
1520285242Sachim       SataDevice->satSignature[6] = 0;
1521285242Sachim       SataDevice->satSignature[7] = 0;
1522285242Sachim       DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1523285242Sachim        SataDevice->satSignature[0],
1524285242Sachim        SataDevice->satSignature[1],
1525285242Sachim        SataDevice->satSignature[2],
1526285242Sachim        SataDevice->satSignature[3],
1527285242Sachim        SataDevice->satSignature[4]));
1528285242Sachim       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1529285242Sachim       if( sataDeviceType == SATA_ATAPI_DEVICE)
1530285242Sachim       {
1531285242Sachim          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1532285242Sachim       }
1533285242Sachim       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1534285242Sachim    }
1535285242Sachim    /* Handling DataDomain buggy FIS */
1536285242Sachim    else if (fis->h.error == REG_DEV_TO_HOST_FIS)
1537285242Sachim    {
1538285242Sachim      /* needs to flip fis to host order */
1539285242Sachim      bit8fis = (bit8*)fis;
1540285242Sachim      for (i=0;i<5;i++)
1541285242Sachim      {
1542285242Sachim        a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
1543285242Sachim        DM_DBG3(("dmReportPhySata2Rcvd: a 0x%8x\n", a));
1544285242Sachim        bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
1545285242Sachim        bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
1546285242Sachim        bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
1547285242Sachim        bit8fisarray[4*i+3] = (a & 0x000000FF);
1548285242Sachim        bit8fis = bit8fis + 4;
1549285242Sachim      }
1550285242Sachim      fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
1551285242Sachim      /* save signature */
1552285242Sachim      DM_DBG3(("dmReportPhySata2Rcvd: DataDomain ATAPI saves the signature\n"));
1553285242Sachim      /* saves signature */
1554285242Sachim      SataDevice->satSignature[0] = fis->d.sectorCount;
1555285242Sachim      SataDevice->satSignature[1] = fis->d.lbaLow;
1556285242Sachim      SataDevice->satSignature[2] = fis->d.lbaMid;
1557285242Sachim      SataDevice->satSignature[3] = fis->d.lbaHigh;
1558285242Sachim      SataDevice->satSignature[4] = fis->d.device;
1559285242Sachim      SataDevice->satSignature[5] = 0;
1560285242Sachim      SataDevice->satSignature[6] = 0;
1561285242Sachim      SataDevice->satSignature[7] = 0;
1562285242Sachim      DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
1563285242Sachim       SataDevice->satSignature[0],
1564285242Sachim       SataDevice->satSignature[1],
1565285242Sachim       SataDevice->satSignature[2],
1566285242Sachim       SataDevice->satSignature[3],
1567285242Sachim       SataDevice->satSignature[4]));
1568285242Sachim
1569285242Sachim       sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
1570285242Sachim       if( sataDeviceType == SATA_ATAPI_DEVICE)
1571285242Sachim       {
1572285242Sachim          SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
1573285242Sachim       }
1574285242Sachim       SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
1575285242Sachim    }
1576285242Sachim    else
1577285242Sachim    {
1578285242Sachim      DM_DBG3(("dmReportPhySata2Rcvd: getting next stp bride\n"));
1579285242Sachim    }
1580285242Sachim
1581285242Sachim    /* Continue to report this STP device to TD*/
1582285242Sachim    if (SataDevice->ExpDevice != agNULL)
1583285242Sachim    {
1584285242Sachim       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
1585285242Sachim    }
1586285242Sachim    else
1587285242Sachim    {
1588285242Sachim       tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
1589285242Sachim    }
1590285242Sachim
1591285242Sachim   }
1592285242Sachim   else
1593285242Sachim   {
1594285242Sachim     DM_DBG3(("dmReportPhySata2Rcvd: siReportPhySataRcvd SMP function return result %x\n",
1595285242Sachim              frameHeader->smpFunctionResult));
1596285242Sachim     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1597285242Sachim   }
1598285242Sachim
1599285242Sachim   return;
1600285242Sachim}
1601285242Sachim
1602285242Sachim
1603285242Sachim
1604285242SachimosGLOBAL bit32
1605285242SachimdmRoutingEntryAdd(
1606285242Sachim                  dmRoot_t          *dmRoot,
1607285242Sachim                  dmExpander_t      *oneExpander,
1608285242Sachim                  bit32             phyId,
1609285242Sachim                  bit32             configSASAddressHi,
1610285242Sachim                  bit32             configSASAddressLo
1611285242Sachim                 )
1612285242Sachim{
1613285242Sachim  dmIntRoot_t                             *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
1614285242Sachim  dmIntContext_t                          *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
1615285242Sachim  agsaRoot_t                              *agRoot = dmAllShared->agRoot;
1616285242Sachim  bit32                                   ret = agTRUE;
1617285242Sachim  dmIntPortContext_t                      *onePortContext;
1618285242Sachim  smpReqConfigureRouteInformation_t       confRoutingInfo;
1619285242Sachim  bit32                                   i;
1620285242Sachim
1621285242Sachim  DM_DBG3(("dmRoutingEntryAdd: start\n"));
1622285242Sachim  DM_DBG3(("dmRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1623285242Sachim  DM_DBG3(("dmRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1624285242Sachim  DM_DBG3(("dmRoutingEntryAdd: phyid %d\n", phyId));
1625285242Sachim
1626285242Sachim  if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
1627285242Sachim      oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo
1628285242Sachim     )
1629285242Sachim  {
1630285242Sachim    DM_DBG3(("dmRoutingEntryAdd: unnecessary\n"));
1631285242Sachim    return ret;
1632285242Sachim  }
1633285242Sachim  if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE)
1634285242Sachim  {
1635285242Sachim    DM_DBG3(("dmRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId]));
1636285242Sachim    return ret;
1637285242Sachim  }
1638285242Sachim
1639285242Sachim  onePortContext = oneExpander->dmDevice->dmPortContext;
1640285242Sachim
1641285242Sachim  onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING;
1642285242Sachim
1643285242Sachim  /* reset smpReqConfigureRouteInformation_t */
1644285242Sachim  dm_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t));
1645285242Sachim  if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex )
1646285242Sachim  {
1647285242Sachim    DM_DBG3(("dmRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi));
1648285242Sachim    DM_DBG3(("dmRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo));
1649285242Sachim    DM_DBG3(("dmRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId]));
1650285242Sachim
1651285242Sachim    oneExpander->configSASAddressHi = configSASAddressHi;
1652285242Sachim    oneExpander->configSASAddressLo = configSASAddressLo;
1653285242Sachim    confRoutingInfo.reserved1[0] = 0;
1654285242Sachim    confRoutingInfo.reserved1[1] = 0;
1655285242Sachim    OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId]));
1656285242Sachim    confRoutingInfo.reserved2 = 0;
1657285242Sachim    confRoutingInfo.phyIdentifier = (bit8)phyId;
1658285242Sachim    confRoutingInfo.reserved3[0] = 0;
1659285242Sachim    confRoutingInfo.reserved3[1] = 0;
1660285242Sachim    confRoutingInfo.disabledBit_reserved4 = 0;
1661285242Sachim    confRoutingInfo.reserved5[0] = 0;
1662285242Sachim    confRoutingInfo.reserved5[1] = 0;
1663285242Sachim    confRoutingInfo.reserved5[2] = 0;
1664285242Sachim    OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi);
1665285242Sachim    OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo);
1666285242Sachim    for ( i = 0; i < 16; i ++ )
1667285242Sachim    {
1668285242Sachim      confRoutingInfo.reserved6[i] = 0;
1669285242Sachim    }
1670285242Sachim    dmSMPStart(dmRoot, agRoot, oneExpander->dmDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ);
1671285242Sachim
1672285242Sachim    oneExpander->currentIndex[phyId] ++;
1673285242Sachim  }
1674285242Sachim  else
1675285242Sachim  {
1676285242Sachim    DM_DBG3(("dmRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex));
1677285242Sachim    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1678285242Sachim
1679285242Sachim    ret = agFALSE;
1680285242Sachim  }
1681285242Sachim  return ret;
1682285242Sachim}
1683285242Sachim
1684285242Sachim
1685285242SachimosGLOBAL void
1686285242SachimdmConfigRoutingInfoRespRcvd(
1687285242Sachim                            dmRoot_t              *dmRoot,
1688285242Sachim                            agsaRoot_t            *agRoot,
1689285242Sachim                            agsaIORequest_t       *agIORequest,
1690285242Sachim                            dmDeviceData_t        *oneDeviceData,
1691285242Sachim                            dmSMPFrameHeader_t    *frameHeader,
1692285242Sachim                            agsaFrameHandle_t     frameHandle
1693285242Sachim                           )
1694285242Sachim{
1695285242Sachim  dmIntPortContext_t                    *onePortContext;
1696285242Sachim  dmExpander_t                          *oneExpander = oneDeviceData->dmExpander;
1697285242Sachim  dmExpander_t                          *UpStreamExpander;
1698285242Sachim  dmExpander_t                          *DownStreamExpander;
1699285242Sachim  dmExpander_t                          *ReturningExpander;
1700285242Sachim  dmExpander_t                          *ConfigurableExpander;
1701285242Sachim  dmDeviceData_t                        *ReturningExpanderDeviceData = agNULL;
1702285242Sachim  bit32                                 dupConfigSASAddr = agFALSE;
1703285242Sachim
1704285242Sachim
1705285242Sachim  DM_DBG3(("dmConfigRoutingInfoRespRcvd: start\n"));
1706285242Sachim  DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1707285242Sachim  DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1708285242Sachim
1709285242Sachim  onePortContext = oneDeviceData->dmPortContext;
1710285242Sachim
1711285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1712285242Sachim  {
1713285242Sachim    DM_DBG1(("dmConfigRoutingInfoRespRcvd: invalid port or aborted discovery!!!\n"));
1714285242Sachim    return;
1715285242Sachim  }
1716285242Sachim
1717285242Sachim  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
1718285242Sachim       frameHeader->smpFunctionResult == PHY_VACANT
1719285242Sachim     )
1720285242Sachim  {
1721285242Sachim    DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
1722285242Sachim    if (DownStreamExpander != agNULL)
1723285242Sachim    {
1724285242Sachim      DownStreamExpander->currentUpStreamPhyIndex ++;
1725285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1726285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
1727285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1728285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1729285242Sachim
1730285242Sachim    }
1731285242Sachim
1732285242Sachim    oneExpander->currentDownStreamPhyIndex++;
1733285242Sachim    DM_DBG3(("dmConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
1734285242Sachim
1735285242Sachim    if ( (DownStreamExpander != agNULL) &&
1736285242Sachim         (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
1737285242Sachim       )
1738285242Sachim    {
1739285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: first if\n"));
1740285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1741285242Sachim
1742285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
1743285242Sachim
1744285242Sachim      dmRoutingEntryAdd(dmRoot,
1745285242Sachim                           oneExpander,
1746285242Sachim                           DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
1747285242Sachim                           oneExpander->configSASAddressHi,
1748285242Sachim                           oneExpander->configSASAddressLo
1749285242Sachim                          );
1750285242Sachim    }
1751285242Sachim    else
1752285242Sachim    {
1753285242Sachim      /* traversing up till discovery Root onePortContext->discovery.RootExp */
1754285242Sachim      DM_DBG3(("dmConfigRoutingInfoRespRcvd: else\n"));
1755285242Sachim
1756285242Sachim      UpStreamExpander = oneExpander->dmUpStreamExpander;
1757285242Sachim      ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
1758285242Sachim      if (UpStreamExpander != agNULL)
1759285242Sachim      {
1760285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1761285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1762285242Sachim      }
1763285242Sachim      else
1764285242Sachim      {
1765285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n"));
1766285242Sachim      }
1767285242Sachim      dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
1768285242Sachim                                                  ConfigurableExpander,
1769285242Sachim                                                  oneExpander->configSASAddressHi,
1770285242Sachim                                                  oneExpander->configSASAddressLo
1771285242Sachim                                                  );
1772285242Sachim
1773285242Sachim      if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
1774285242Sachim      {
1775285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: else if\n"));
1776285242Sachim
1777285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
1778285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
1779285242Sachim
1780285242Sachim        if ( UpStreamExpander != agNULL)
1781285242Sachim        {
1782285242Sachim          UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
1783285242Sachim        }
1784285242Sachim        ConfigurableExpander->currentDownStreamPhyIndex =
1785285242Sachim                dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
1786285242Sachim        ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
1787285242Sachim        if ( DownStreamExpander != agNULL)
1788285242Sachim        {
1789285242Sachim          DownStreamExpander->currentUpStreamPhyIndex = 0;
1790285242Sachim        }
1791285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
1792285242Sachim
1793285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
1794285242Sachim        dmRoutingEntryAdd(dmRoot,
1795285242Sachim                             ConfigurableExpander,
1796285242Sachim                             ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
1797285242Sachim                             oneExpander->configSASAddressHi,
1798285242Sachim                             oneExpander->configSASAddressLo
1799285242Sachim                            );
1800285242Sachim      }
1801285242Sachim      else
1802285242Sachim      {
1803285242Sachim        /* going back to where it was */
1804285242Sachim        /* ConfigRoutingInfo is done for a target */
1805285242Sachim        DM_DBG3(("dmConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n"));
1806285242Sachim        ReturningExpander = oneExpander->dmReturnginExpander;
1807285242Sachim        if ( DownStreamExpander != agNULL)
1808285242Sachim        {
1809285242Sachim          DownStreamExpander->currentUpStreamPhyIndex = 0;
1810285242Sachim        }
1811285242Sachim        /* debugging */
1812285242Sachim        if (ReturningExpander != agNULL)
1813285242Sachim        {
1814285242Sachim          DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
1815285242Sachim          DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
1816285242Sachim          ReturningExpanderDeviceData = ReturningExpander->dmDevice;
1817285242Sachim        }
1818285242Sachim
1819285242Sachim        /* No longer in DISCOVERY_CONFIG_ROUTING */
1820285242Sachim        onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
1821285242Sachim
1822285242Sachim        if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
1823285242Sachim        {
1824285242Sachim      /* If not the last phy */
1825285242Sachim          if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
1826285242Sachim          {
1827285242Sachim            DM_DBG3(("dmConfigRoutingInfoRespRcvd: More Phys to discover\n"));
1828285242Sachim            /* continue discovery for the next phy */
1829285242Sachim            /* needs to send only one Discovery not multiple times */
1830285242Sachim            if (ReturningExpander->discoverSMPAllowed == agTRUE)
1831285242Sachim            {
1832285242Sachim              dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
1833285242Sachim            }
1834285242Sachim            if (ReturningExpander != agNULL)
1835285242Sachim            {
1836285242Sachim              ReturningExpander->discoverSMPAllowed = agFALSE;
1837285242Sachim            }
1838285242Sachim          }
1839285242Sachim          /* If the last phy */
1840285242Sachim          else
1841285242Sachim          {
1842285242Sachim            DM_DBG3(("dmConfigRoutingInfoRespRcvd: No More Phys\n"));
1843285242Sachim            ReturningExpander->discoverSMPAllowed = agTRUE;
1844285242Sachim
1845285242Sachim            /* remove the expander from the discovering list */
1846285242Sachim            dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
1847285242Sachim            /* continue downstream discovering */
1848285242Sachim            dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
1849285242Sachim
1850285242Sachim            //DownStreamExpander
1851285242Sachim          }
1852285242Sachim    }
1853285242Sachim      }
1854285242Sachim    }
1855285242Sachim  }
1856285242Sachim  else
1857285242Sachim  {
1858285242Sachim    DM_DBG1(("dmConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n", frameHeader->smpFunctionResult));
1859285242Sachim    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
1860285242Sachim  }
1861285242Sachim  return;
1862285242Sachim}
1863285242Sachim
1864285242SachimosGLOBAL void
1865285242SachimdmConfigRoutingInfo2RespRcvd(
1866285242Sachim                            dmRoot_t              *dmRoot,
1867285242Sachim                            agsaRoot_t            *agRoot,
1868285242Sachim                            agsaIORequest_t       *agIORequest,
1869285242Sachim                            dmDeviceData_t        *oneDeviceData,
1870285242Sachim                            dmSMPFrameHeader_t    *frameHeader,
1871285242Sachim                            agsaFrameHandle_t     frameHandle
1872285242Sachim                           )
1873285242Sachim{
1874285242Sachim  dmExpander_t                            *oneExpander = oneDeviceData->dmExpander;
1875285242Sachim  dmExpander_t                            *UpStreamExpander;
1876285242Sachim  dmExpander_t                            *DownStreamExpander;
1877285242Sachim  dmExpander_t                            *ReturningExpander;
1878285242Sachim  dmExpander_t                            *ConfigurableExpander;
1879285242Sachim
1880285242Sachim  dmIntPortContext_t                      *onePortContext;
1881285242Sachim  dmDeviceData_t                          *ReturningExpanderDeviceData = agNULL;
1882285242Sachim  bit32                                   dupConfigSASAddr = agFALSE;
1883285242Sachim
1884285242Sachim  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: start\n"));
1885285242Sachim  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
1886285242Sachim  DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
1887285242Sachim
1888285242Sachim  onePortContext = oneDeviceData->dmPortContext;
1889285242Sachim
1890285242Sachim  if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
1891285242Sachim  {
1892285242Sachim    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: invalid port or aborted discovery!!!\n"));
1893285242Sachim    return;
1894285242Sachim  }
1895285242Sachim
1896285242Sachim  if (frameHeader->smpFunctionResult == PHY_VACANT)
1897285242Sachim  {
1898285242Sachim    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: smpFunctionResult is PHY_VACANT\n"));
1899285242Sachim  }
1900285242Sachim
1901285242Sachim  if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
1902285242Sachim       frameHeader->smpFunctionResult == PHY_VACANT
1903285242Sachim     )
1904285242Sachim  {
1905285242Sachim    DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
1906285242Sachim    if (DownStreamExpander != agNULL)
1907285242Sachim    {
1908285242Sachim      DownStreamExpander->currentUpStreamPhyIndex ++;
1909285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1910285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
1911285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1912285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1913285242Sachim
1914285242Sachim    }
1915285242Sachim
1916285242Sachim    oneExpander->currentDownStreamPhyIndex++;
1917285242Sachim    DM_DBG2(("dmConfigRoutingInfo2RespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
1918285242Sachim
1919285242Sachim    if ( (DownStreamExpander != agNULL) &&
1920285242Sachim         (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
1921285242Sachim       )
1922285242Sachim    {
1923285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: first if\n"));
1924285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
1925285242Sachim
1926285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
1927285242Sachim
1928285242Sachim      dmRoutingEntryAdd(dmRoot,
1929285242Sachim                        oneExpander,
1930285242Sachim                        DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
1931285242Sachim                        oneExpander->configSASAddressHi,
1932285242Sachim                        oneExpander->configSASAddressLo
1933285242Sachim                       );
1934285242Sachim    }
1935285242Sachim    else
1936285242Sachim    {
1937285242Sachim      /* traversing up till discovery Root onePortContext->discovery.RootExp */
1938285242Sachim      DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else\n"));
1939285242Sachim
1940285242Sachim      UpStreamExpander = oneExpander->dmUpStreamExpander;
1941285242Sachim      ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
1942285242Sachim      if (UpStreamExpander != agNULL)
1943285242Sachim      {
1944285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
1945285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
1946285242Sachim      }
1947285242Sachim      else
1948285242Sachim      {
1949285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander is NULL\n"));
1950285242Sachim      }
1951285242Sachim      dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
1952285242Sachim                                                  ConfigurableExpander,
1953285242Sachim                                                  oneExpander->configSASAddressHi,
1954285242Sachim                                                  oneExpander->configSASAddressLo
1955285242Sachim                                                  );
1956285242Sachim
1957285242Sachim      if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
1958285242Sachim      {
1959285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else if\n"));
1960285242Sachim
1961285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
1962285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
1963285242Sachim
1964285242Sachim        if ( UpStreamExpander != agNULL)
1965285242Sachim        {
1966285242Sachim    UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
1967285242Sachim        }
1968285242Sachim        ConfigurableExpander->currentDownStreamPhyIndex =
1969285242Sachim                dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
1970285242Sachim        ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
1971285242Sachim        if ( DownStreamExpander != agNULL)
1972285242Sachim        {
1973285242Sachim          DownStreamExpander->currentUpStreamPhyIndex = 0;
1974285242Sachim        }
1975285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
1976285242Sachim
1977285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
1978285242Sachim        dmRoutingEntryAdd(dmRoot,
1979285242Sachim                          ConfigurableExpander,
1980285242Sachim                          ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
1981285242Sachim                          oneExpander->configSASAddressHi,
1982285242Sachim                          oneExpander->configSASAddressLo
1983285242Sachim                         );
1984285242Sachim      }
1985285242Sachim      else
1986285242Sachim      {
1987285242Sachim        /* going back to where it was */
1988285242Sachim        /* ConfigRoutingInfo is done for a target */
1989285242Sachim        DM_DBG2(("dmConfigRoutingInfo2RespRcvd: $$$$$$ my change $$$$$ \n"));
1990285242Sachim        ReturningExpander = oneExpander->dmReturnginExpander;
1991285242Sachim        if ( DownStreamExpander != agNULL)
1992285242Sachim        {
1993285242Sachim          DownStreamExpander->currentUpStreamPhyIndex = 0;
1994285242Sachim        }
1995285242Sachim        /* debugging */
1996285242Sachim        if (ReturningExpander != agNULL)
1997285242Sachim        {
1998285242Sachim           DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
1999285242Sachim           DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
2000285242Sachim           ReturningExpanderDeviceData = ReturningExpander->dmDevice;
2001285242Sachim        }
2002285242Sachim
2003285242Sachim        /* No longer in DISCOVERY_CONFIG_ROUTING */
2004285242Sachim        onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
2005285242Sachim
2006285242Sachim        if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
2007285242Sachim        {
2008285242Sachim      /* If not the last phy */
2009285242Sachim          if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
2010285242Sachim          {
2011285242Sachim            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: More Phys to discover\n"));
2012285242Sachim            /* continue discovery for the next phy */
2013285242Sachim            /* needs to send only one Discovery not multiple times */
2014285242Sachim            if (ReturningExpander->discoverSMPAllowed == agTRUE)
2015285242Sachim            {
2016285242Sachim              dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
2017285242Sachim            }
2018285242Sachim            if (ReturningExpander != agNULL)
2019285242Sachim            {
2020285242Sachim              ReturningExpander->discoverSMPAllowed = agFALSE;
2021285242Sachim            }
2022285242Sachim          }
2023285242Sachim          /* If the last phy */
2024285242Sachim          else
2025285242Sachim          {
2026285242Sachim            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: No More Phys\n"));
2027285242Sachim            ReturningExpander->discoverSMPAllowed = agTRUE;
2028285242Sachim
2029285242Sachim            /* remove the expander from the discovering list */
2030285242Sachim            dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
2031285242Sachim            /* continue downstream discovering */
2032285242Sachim            dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
2033285242Sachim
2034285242Sachim            //DownStreamExpander
2035285242Sachim          }
2036285242Sachim        }
2037285242Sachim      }
2038285242Sachim    }
2039285242Sachim  }
2040285242Sachim  else
2041285242Sachim  {
2042285242Sachim    DM_DBG1(("dmConfigRoutingInfo2RespRcvd: Discovery Error SMP function return result error=0x%x!!!\n", frameHeader->smpFunctionResult));
2043285242Sachim    dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2044285242Sachim  }
2045285242Sachim  return;
2046285242Sachim}
2047285242Sachim
2048285242Sachim
2049285242Sachim/* no task management case here for phyControl*/
2050285242Sachim
2051285242Sachim/* no task management case here for phyControl*/
2052285242SachimosGLOBAL void
2053285242SachimdmPhyControlRespRcvd(
2054285242Sachim                     dmRoot_t              *dmRoot,
2055285242Sachim                     agsaRoot_t            *agRoot,
2056285242Sachim                     agsaIORequest_t       *agIORequest,
2057285242Sachim                     dmDeviceData_t        *oneDeviceData,
2058285242Sachim                     dmSMPFrameHeader_t    *frameHeader,
2059285242Sachim                     agsaFrameHandle_t     frameHandle
2060285242Sachim                    )
2061285242Sachim{
2062285242Sachim  DM_DBG3(("dmPhyControlRespRcvd: start\n"));
2063285242Sachim  DM_DBG3(("dmPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2064285242Sachim  DM_DBG3(("dmPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2065285242Sachim
2066285242Sachim  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2067285242Sachim  {
2068285242Sachim    DM_DBG3(("dmPhyControlRespRcvd: SMP success\n"));
2069285242Sachim  }
2070285242Sachim  else
2071285242Sachim  {
2072285242Sachim    DM_DBG1(("dmPhyControlRespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
2073285242Sachim  }
2074285242Sachim
2075285242Sachim  return;
2076285242Sachim}
2077285242Sachim
2078285242Sachim/* no task management case here for phyControl*/
2079285242SachimosGLOBAL void
2080285242SachimdmPhyControl2RespRcvd(
2081285242Sachim                     dmRoot_t              *dmRoot,
2082285242Sachim                     agsaRoot_t            *agRoot,
2083285242Sachim                     agsaIORequest_t       *agIORequest,
2084285242Sachim                     dmDeviceData_t        *oneDeviceData,
2085285242Sachim                     dmSMPFrameHeader_t    *frameHeader,
2086285242Sachim                     agsaFrameHandle_t     frameHandle
2087285242Sachim                    )
2088285242Sachim{
2089285242Sachim  DM_DBG2(("dmPhyControl2RespRcvd: start\n"));
2090285242Sachim  DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2091285242Sachim  DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2092285242Sachim
2093285242Sachim  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2094285242Sachim  {
2095285242Sachim    DM_DBG2(("dmPhyControl2RespRcvd: SMP success\n"));
2096285242Sachim  }
2097285242Sachim  else
2098285242Sachim  {
2099285242Sachim    DM_DBG1(("dmPhyControl2RespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
2100285242Sachim  }
2101285242Sachim
2102285242Sachim  return;
2103285242Sachim}
2104285242Sachim
2105285242SachimosGLOBAL void
2106285242SachimdmPhyControlFailureRespRcvd(
2107285242Sachim                            dmRoot_t              *dmRoot,
2108285242Sachim                            agsaRoot_t            *agRoot,
2109285242Sachim                            dmDeviceData_t        *oneDeviceData,
2110285242Sachim                            dmSMPFrameHeader_t    *frameHeader,
2111285242Sachim                            agsaFrameHandle_t     frameHandle
2112285242Sachim                           )
2113285242Sachim{
2114285242Sachim  DM_DBG1(("dmPhyControlFailureRespRcvd: start\n"));
2115285242Sachim  return;
2116285242Sachim}
2117285242Sachim
2118285242SachimGLOBAL void dmSetDeviceInfoCB(
2119285242Sachim                                agsaRoot_t        *agRoot,
2120285242Sachim                                agsaContext_t     *agContext,
2121285242Sachim                                agsaDevHandle_t   *agDevHandle,
2122285242Sachim                                bit32             status,
2123285242Sachim                                bit32             option,
2124285242Sachim                                bit32             param
2125285242Sachim                                )
2126285242Sachim{
2127285242Sachim  dmRoot_t                  *dmRoot = agNULL;
2128285242Sachim  agsaIORequest_t           *agIORequest;
2129285242Sachim  bit32                     smstatus;
2130285242Sachim  agsaSASRequestBody_t      *agSASRequestBody;
2131285242Sachim  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
2132285242Sachim  dmIntPortContext_t        *onePortContext = agNULL;
2133285242Sachim  dmDeviceData_t            *oneDeviceData;
2134285242Sachim  bit8                      SMPRequestFunction;
2135285242Sachim  bit8                      devType_S_Rate;
2136285242Sachim  DM_DBG1(("dmSetDeviceInfoCB: start\n"));
2137285242Sachim  DM_DBG4(("dmSetDeviceInfoCB: status 0x%x\n", status));
2138285242Sachim  DM_DBG4(("dmSetDeviceInfoCB: option 0x%x\n", option));
2139285242Sachim  DM_DBG4(("dmSetDeviceInfoCB: param 0x%x\n", param));
2140285242Sachim  if (status != OSSA_SUCCESS)
2141285242Sachim  {
2142285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: status %d\n", status));
2143285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: option 0x%x\n", option));
2144285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: param 0x%x\n", param));
2145285242Sachim    if (option == 32) /* set connection rate */
2146285242Sachim    {
2147285242Sachim      DM_DBG1(("dmSetDeviceInfoCB: IO failure\n"));
2148285242Sachim      agIORequest = (agsaIORequest_t *)agContext->osData;
2149285242Sachim      dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2150285242Sachim      dmRoot = dmSMPRequestBody->dmRoot;
2151285242Sachim      oneDeviceData = dmSMPRequestBody->dmDevice;
2152285242Sachim      onePortContext = oneDeviceData->dmPortContext;
2153285242Sachim      SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2154285242Sachim      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2155285242Sachim          SMPRequestFunction == SMP_DISCOVER ||
2156285242Sachim          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2157285242Sachim          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2158285242Sachim        )
2159285242Sachim      {
2160285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2161285242Sachim      }
2162285242Sachim      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2163285242Sachim      {
2164285242Sachim        /* task management failure */
2165285242Sachim        dmPhyControlFailureRespRcvd(
2166285242Sachim                                    dmRoot,
2167285242Sachim                                    agRoot,
2168285242Sachim                                    oneDeviceData,
2169285242Sachim                                    agNULL,
2170285242Sachim                                    agNULL
2171285242Sachim                                   );
2172285242Sachim      }
2173285242Sachim    }
2174285242Sachim  }
2175285242Sachim  if (agDevHandle == agNULL)
2176285242Sachim  {
2177285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: agDevHandle is NULL\n"));
2178285242Sachim    return;
2179285242Sachim  }
2180285242Sachim
2181285242Sachim  /* retry SMP */
2182285242Sachim  if (option == 32) /* set connection rate */
2183285242Sachim  {
2184285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: set connection rate option\n"));
2185285242Sachim    agIORequest = (agsaIORequest_t *)agContext->osData;
2186285242Sachim    dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2187285242Sachim    dmRoot = dmSMPRequestBody->dmRoot;
2188285242Sachim    agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
2189285242Sachim    oneDeviceData = dmSMPRequestBody->dmDevice;
2190285242Sachim    onePortContext = oneDeviceData->dmPortContext;
2191285242Sachim    devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
2192285242Sachim    devType_S_Rate = (devType_S_Rate & 0xF0) | (param >> 28);
2193285242Sachim    oneDeviceData->agDeviceInfo.devType_S_Rate =  devType_S_Rate;
2194285242Sachim    SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2195285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: SMPRequestFunction 0x%x\n", SMPRequestFunction));
2196285242Sachim    DM_DBG1(("dmSetDeviceInfoCB: new rate is 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo)));
2197285242Sachim    smstatus = saSMPStart(
2198285242Sachim                          agRoot,
2199285242Sachim                          agIORequest,
2200285242Sachim                          0,
2201285242Sachim                          agDevHandle,
2202285242Sachim                          AGSA_SMP_INIT_REQ,
2203285242Sachim                          agSASRequestBody,
2204285242Sachim                          &dmsaSMPCompleted
2205285242Sachim                         );
2206285242Sachim    if (status == AGSA_RC_SUCCESS)
2207285242Sachim    {
2208285242Sachim      /* increment the number of pending SMP */
2209285242Sachim      onePortContext->discovery.pendingSMP++;
2210285242Sachim//          dmSMPRequestBody->retries++;
2211285242Sachim      if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2212285242Sachim          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2213285242Sachim          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2214285242Sachim         )
2215285242Sachim      {
2216285242Sachim        /* start discovery-related SMP timer */
2217285242Sachim        dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)SMPRequestFunction, dmSMPRequestBody);
2218285242Sachim      }
2219285242Sachim      return;
2220285242Sachim    }
2221285242Sachim    else if (status == AGSA_RC_BUSY)
2222285242Sachim    {
2223285242Sachim      onePortContext->discovery.pendingSMP++;
2224285242Sachim//          dmSMPRequestBody->retries++;
2225285242Sachim      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2226285242Sachim          SMPRequestFunction == SMP_DISCOVER ||
2227285242Sachim          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2228285242Sachim          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2229285242Sachim         )
2230285242Sachim      {
2231285242Sachim        dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
2232285242Sachim      }
2233285242Sachim      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2234285242Sachim      {
2235285242Sachim        /* For taskmanagement SMP, let's fail task management failure */
2236285242Sachim        dmPhyControlFailureRespRcvd(
2237285242Sachim                                    dmRoot,
2238285242Sachim                                    agRoot,
2239285242Sachim                                    oneDeviceData,
2240285242Sachim                                    agNULL,
2241285242Sachim                                    agNULL
2242285242Sachim                                   );
2243285242Sachim      }
2244285242Sachim      else
2245285242Sachim      {
2246285242Sachim      }
2247285242Sachim    }
2248285242Sachim    else /* AGSA_RC_FAILURE */
2249285242Sachim    {
2250285242Sachim      if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2251285242Sachim          SMPRequestFunction == SMP_DISCOVER ||
2252285242Sachim          SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2253285242Sachim          SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2254285242Sachim         )
2255285242Sachim      {
2256285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2257285242Sachim      }
2258285242Sachim      else if (SMPRequestFunction == SMP_PHY_CONTROL)
2259285242Sachim      {
2260285242Sachim        /* task management failure */
2261285242Sachim        dmPhyControlFailureRespRcvd(
2262285242Sachim                                    dmRoot,
2263285242Sachim                                    agRoot,
2264285242Sachim                                    oneDeviceData,
2265285242Sachim                                    agNULL,
2266285242Sachim                                    agNULL
2267285242Sachim                                   );
2268285242Sachim      }
2269285242Sachim      else
2270285242Sachim      {
2271285242Sachim      }
2272285242Sachim    }
2273285242Sachim  }
2274285242Sachim  return;
2275285242Sachim}
2276285242Sachim/* smp completion */
2277285242SachimosGLOBAL void
2278285242SachimdmSMPCompleted(
2279285242Sachim               agsaRoot_t            *agRoot,
2280285242Sachim               agsaIORequest_t       *agIORequest,
2281285242Sachim               bit32                 agIOStatus,
2282285242Sachim               bit32                 agIOInfoLen,
2283285242Sachim               agsaFrameHandle_t     agFrameHandle
2284285242Sachim              )
2285285242Sachim{
2286285242Sachim  dmIntRoot_t               *dmIntRoot    = agNULL;
2287285242Sachim  dmIntContext_t            *dmAllShared = agNULL;
2288285242Sachim  dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
2289285242Sachim  agsaSMPFrame_t            *agSMPFrame;
2290285242Sachim  dmRoot_t                  *dmRoot = agNULL;
2291285242Sachim  dmIntPortContext_t        *onePortContext = agNULL;
2292285242Sachim  dmIntPortContext_t        *oldonePortContext;
2293285242Sachim  dmExpander_t              *oneExpander = agNULL;
2294285242Sachim  dmDeviceData_t            *oneDeviceData;
2295285242Sachim  agsaDevHandle_t           *agDevHandle = agNULL;
2296285242Sachim  agsaSASRequestBody_t      *agSASRequestBody;
2297285242Sachim  bit8                      smpHeader[4];
2298285242Sachim  bit8                      SMPRequestFunction;
2299285242Sachim  dmSMPFrameHeader_t        *dmResponseSMPFrameHeader;
2300285242Sachim  dmSMPFrameHeader_t        *dmSMPFrameHeader;
2301285242Sachim  bit8                      *dmSMPPayload;
2302285242Sachim  smpReqPhyControl_t        *smpPhyControlReq;
2303285242Sachim  smpReqPhyControl2_t       *smpPhyControl2Req;
2304285242Sachim#ifndef DIRECT_SMP
2305285242Sachim  dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
2306285242Sachim  dmSMPFrameHeader_t        *dmRequestSMPFrameHeader;
2307285242Sachim  bit8                      smpRequestHeader[4];
2308285242Sachim#endif
2309285242Sachim  bit32                     status;
2310285242Sachim  bit32                     ConnRate = SAS_CONNECTION_RATE_12_0G;
2311285242Sachim  agsaContext_t             *agContext = agNULL;
2312285242Sachim
2313285242Sachim  DM_DBG3(("dmSMPCompleted: start\n"));
2314285242Sachim
2315285242Sachim  dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
2316285242Sachim
2317285242Sachim  dmRoot = dmSMPRequestBody->dmRoot;
2318285242Sachim  dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
2319285242Sachim  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
2320285242Sachim
2321285242Sachim  oneDeviceData = dmSMPRequestBody->dmDevice;
2322285242Sachim  agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
2323285242Sachim  agSMPFrame = &(agSASRequestBody->smpFrame);
2324285242Sachim
2325285242Sachim  if (oneDeviceData->valid == agFALSE &&
2326285242Sachim      oneDeviceData->valid2 == agFALSE &&
2327285242Sachim      oneDeviceData->dmPortContext == agNULL &&
2328285242Sachim      dmSMPRequestBody->dmPortContext->valid == agFALSE
2329285242Sachim      )
2330285242Sachim  {
2331285242Sachim    DM_DBG3(("dmSMPCompleted: port has been destroyed\n"));
2332285242Sachim    /* all device, port information have been reset
2333285242Sachim       just put smp to freeList
2334285242Sachim    */
2335285242Sachim    /* SMP request */
2336285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2337285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2338285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2339285242Sachim
2340285242Sachim#ifndef DIRECT_SMP
2341285242Sachim    /* SMP response */
2342285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2343285242Sachim    if (dmSMPResponseBody == agNULL)
2344285242Sachim    {
2345285242Sachim      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2346285242Sachim      return;
2347285242Sachim    }
2348285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2349285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2350285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2351285242Sachim#endif
2352285242Sachim    return;
2353285242Sachim  }
2354285242Sachim
2355285242Sachim  onePortContext = oneDeviceData->dmPortContext;
2356285242Sachim  oneExpander = oneDeviceData->dmExpander;
2357285242Sachim  agDevHandle = oneExpander->agDevHandle;
2358285242Sachim
2359285242Sachim
2360285242Sachim#ifdef DIRECT_SMP
2361285242Sachim  SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
2362285242Sachim#else
2363285242Sachim  saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpRequestHeader, 4);
2364285242Sachim  dmRequestSMPFrameHeader = (dmSMPFrameHeader_t *)smpRequestHeader;
2365285242Sachim  SMPRequestFunction = dmRequestSMPFrameHeader->smpFunction;
2366285242Sachim#endif
2367285242Sachim
2368285242Sachim#ifdef NOT_IN_USE
2369285242Sachim  /* for debugging; dump SMP request payload */
2370285242Sachim  dmhexdump("smp payload",
2371285242Sachim            (bit8 *)agSASRequestBody->smpFrame.outFrameBuf,
2372285242Sachim            agSASRequestBody->smpFrame.outFrameLen
2373285242Sachim           );
2374285242Sachim  dmhexdump("smp payload new",
2375285242Sachim            (bit8 *)dmSMPRequestBody->smpPayload,
2376285242Sachim            agSASRequestBody->smpFrame.outFrameLen
2377285242Sachim           );
2378285242Sachim#endif
2379285242Sachim
2380285242Sachim  /* sanity check */
2381285242Sachim  if (onePortContext != agNULL)
2382285242Sachim  {
2383285242Sachim    DM_DBG5(("dmSMPCompleted: pid %d\n", onePortContext->id));
2384285242Sachim  }
2385285242Sachim  else
2386285242Sachim  {
2387285242Sachim    DM_DBG1(("dmSMPCompleted: Wrong, onePortContext is NULL!!!\n"));
2388285242Sachim    /* SMP request */
2389285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2390285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2391285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2392285242Sachim
2393285242Sachim#ifndef DIRECT_SMP
2394285242Sachim    /* SMP response */
2395285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2396285242Sachim    if (dmSMPResponseBody == agNULL)
2397285242Sachim    {
2398285242Sachim      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2399285242Sachim      return;
2400285242Sachim    }
2401285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2402285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2403285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2404285242Sachim#endif
2405285242Sachim    return;
2406285242Sachim  }
2407285242Sachim
2408285242Sachim  oldonePortContext = dmSMPRequestBody->dmPortContext;
2409285242Sachim  if (oldonePortContext != agNULL)
2410285242Sachim  {
2411285242Sachim    DM_DBG5(("dmSMPCompleted: old pid %d\n", oldonePortContext->id));
2412285242Sachim  }
2413285242Sachim  else
2414285242Sachim  {
2415285242Sachim    DM_DBG1(("dmSMPCompleted: Wrong, oldonePortContext is NULL!!!\n"));
2416285242Sachim    /* SMP request */
2417285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2418285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2419285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2420285242Sachim
2421285242Sachim#ifndef DIRECT_SMP
2422285242Sachim    /* SMP response */
2423285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2424285242Sachim    if (dmSMPResponseBody == agNULL)
2425285242Sachim    {
2426285242Sachim      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2427285242Sachim      return;
2428285242Sachim    }
2429285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2430285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2431285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2432285242Sachim#endif
2433285242Sachim    return;
2434285242Sachim  }
2435285242Sachim
2436285242Sachim  /* decrement the number of pending SMP */
2437285242Sachim  onePortContext->discovery.pendingSMP--;
2438285242Sachim
2439285242Sachim
2440285242Sachim  /* for port invalid case;
2441285242Sachim     full discovery -> full discovery; incremental discovery -> full discovery
2442285242Sachim   */
2443285242Sachim  if (onePortContext != oldonePortContext)
2444285242Sachim  {
2445285242Sachim    DM_DBG1(("dmSMPCompleted: portcontext has changed!!!\n"));
2446285242Sachim    if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2447285242Sachim        SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2448285242Sachim        SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2449285242Sachim        )
2450285242Sachim    {
2451285242Sachim      /* stop SMP timer */
2452285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2453285242Sachim      if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2454285242Sachim      {
2455285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2456285242Sachim        dmKillTimer(
2457285242Sachim                      dmRoot,
2458285242Sachim                      &(onePortContext->discovery.DiscoverySMPTimer)
2459285242Sachim                     );
2460285242Sachim      }
2461285242Sachim      else
2462285242Sachim      {
2463285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2464285242Sachim      }
2465285242Sachim
2466285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2467285242Sachim      if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2468285242Sachim      {
2469285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2470285242Sachim        dmKillTimer(
2471285242Sachim                      dmRoot,
2472285242Sachim                      &(oldonePortContext->discovery.DiscoverySMPTimer)
2473285242Sachim                     );
2474285242Sachim      }
2475285242Sachim      else
2476285242Sachim      {
2477285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2478285242Sachim      }
2479285242Sachim    }
2480285242Sachim    /* clean up expanders data strucures; move to free exp when device is cleaned */
2481285242Sachim    dmCleanAllExp(dmRoot, oldonePortContext);
2482285242Sachim    /* remove devices */
2483285242Sachim    dmInternalRemovals(dmRoot, oldonePortContext);
2484285242Sachim
2485285242Sachim    /* SMP request */
2486285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2487285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2488285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2489285242Sachim
2490285242Sachim#ifndef DIRECT_SMP
2491285242Sachim    /* SMP response */
2492285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2493285242Sachim    if (dmSMPResponseBody == agNULL)
2494285242Sachim    {
2495285242Sachim      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2496285242Sachim      return;
2497285242Sachim    }
2498285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2499285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2500285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2501285242Sachim#endif
2502285242Sachim
2503285242Sachim
2504285242Sachim    return;
2505285242Sachim  }
2506285242Sachim
2507285242Sachim  if (onePortContext->valid == agFALSE ||
2508285242Sachim      onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
2509285242Sachim      onePortContext->discovery.status == DISCOVERY_SAS_DONE  ||
2510285242Sachim      onePortContext->DiscoveryAbortInProgress == agTRUE
2511285242Sachim     )
2512285242Sachim  {
2513285242Sachim    if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2514285242Sachim        SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2515285242Sachim        SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2516285242Sachim        )
2517285242Sachim    {
2518285242Sachim      /* stop SMP timer */
2519285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2520285242Sachim      if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2521285242Sachim      {
2522285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2523285242Sachim        dmKillTimer(
2524285242Sachim                    dmRoot,
2525285242Sachim                    &(onePortContext->discovery.DiscoverySMPTimer)
2526285242Sachim                   );
2527285242Sachim      }
2528285242Sachim      else
2529285242Sachim      {
2530285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2531285242Sachim      }
2532285242Sachim
2533285242Sachim
2534285242Sachim
2535285242Sachim      tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2536285242Sachim      if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2537285242Sachim      {
2538285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2539285242Sachim        dmKillTimer(
2540285242Sachim                    dmRoot,
2541285242Sachim                    &(oldonePortContext->discovery.DiscoverySMPTimer)
2542285242Sachim                   );
2543285242Sachim      }
2544285242Sachim      else
2545285242Sachim      {
2546285242Sachim        tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2547285242Sachim      }
2548285242Sachim    }
2549285242Sachim
2550285242Sachim    /* SMP request */
2551285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2552285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2553285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2554285242Sachim
2555285242Sachim#ifndef DIRECT_SMP
2556285242Sachim    /* SMP response */
2557285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2558285242Sachim    if (dmSMPResponseBody == agNULL)
2559285242Sachim    {
2560285242Sachim      DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2561285242Sachim      return;
2562285242Sachim    }
2563285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2564285242Sachim    DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2565285242Sachim    tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2566285242Sachim#endif
2567285242Sachim
2568285242Sachim    if (onePortContext->discovery.pendingSMP == 0)
2569285242Sachim    {
2570285242Sachim      DM_DBG1(("dmSMPCompleted: aborting discovery\n"));
2571285242Sachim      if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
2572285242Sachim          onePortContext->discovery.status == DISCOVERY_SAS_DONE ||
2573285242Sachim          onePortContext->DiscoveryAbortInProgress == agTRUE
2574285242Sachim         )
2575285242Sachim      {
2576285242Sachim        onePortContext->DiscoveryAbortInProgress = agFALSE;
2577285242Sachim        onePortContext->DiscoveryState = DM_DSTATE_COMPLETED;
2578285242Sachim        onePortContext->discovery.status = DISCOVERY_SAS_DONE;
2579285242Sachim        dmCleanAllExp(dmRoot, onePortContext);
2580285242Sachim        if ( onePortContext->DiscoveryAbortInProgress == agTRUE)
2581285242Sachim        {
2582285242Sachim          tddmDiscoverCB(
2583285242Sachim                         dmRoot,
2584285242Sachim                         onePortContext->dmPortContext,
2585285242Sachim                         dmDiscAborted
2586285242Sachim                  );
2587285242Sachim        }
2588285242Sachim      }
2589285242Sachim    }
2590285242Sachim    else
2591285242Sachim    {
2592285242Sachim      DM_DBG3(("dmSMPCompleted: not yet abort; non zero pendingSMP %d\n", onePortContext->discovery.pendingSMP));
2593285242Sachim    }
2594285242Sachim    return;
2595285242Sachim  }
2596285242Sachim
2597285242Sachim  if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2598285242Sachim      SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2599285242Sachim      SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2600285242Sachim      )
2601285242Sachim  {
2602285242Sachim    /* stop SMP timer */
2603285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2604285242Sachim    if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2605285242Sachim    {
2606285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2607285242Sachim      dmKillTimer(
2608285242Sachim                  dmRoot,
2609285242Sachim                  &(onePortContext->discovery.DiscoverySMPTimer)
2610285242Sachim                 );
2611285242Sachim    }
2612285242Sachim    else
2613285242Sachim    {
2614285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2615285242Sachim    }
2616285242Sachim
2617285242Sachim
2618285242Sachim    tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
2619285242Sachim    if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
2620285242Sachim    {
2621285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2622285242Sachim      dmKillTimer(
2623285242Sachim                  dmRoot,
2624285242Sachim                  &(oldonePortContext->discovery.DiscoverySMPTimer)
2625285242Sachim                 );
2626285242Sachim    }
2627285242Sachim    else
2628285242Sachim    {
2629285242Sachim      tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
2630285242Sachim    }
2631285242Sachim  }
2632285242Sachim
2633285242Sachim  if (oneExpander->SAS2 == 0)
2634285242Sachim  {
2635285242Sachim    DM_DBG3(("dmSMPCompleted: SAS 1.1\n"));
2636285242Sachim    if (agIOStatus == OSSA_IO_SUCCESS)
2637285242Sachim    {
2638285242Sachim      //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
2639285242Sachim      /* parsing SMP payload */
2640285242Sachim#ifdef DIRECT_SMP
2641285242Sachim      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2642285242Sachim#else
2643285242Sachim      dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2644285242Sachim      saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
2645285242Sachim#endif
2646285242Sachim      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2647285242Sachim
2648285242Sachim      /* SMP function dependent payload */
2649285242Sachim      switch (dmResponseSMPFrameHeader->smpFunction)
2650285242Sachim      {
2651285242Sachim      case SMP_REPORT_GENERAL:
2652285242Sachim        DM_DBG3(("dmSMPCompleted: report general\n"));
2653285242Sachim        if (agIOInfoLen != sizeof(smpRespReportGeneral_t) + 4 &&
2654285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2655285242Sachim        {
2656285242Sachim          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportGeneral_t) + 4));
2657285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2658285242Sachim
2659285242Sachim          /* SMP request */
2660285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2661285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2662285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2663285242Sachim
2664285242Sachim#ifndef DIRECT_SMP
2665285242Sachim          /* SMP response */
2666285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2667285242Sachim          if (dmSMPResponseBody == agNULL)
2668285242Sachim          {
2669285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2670285242Sachim            return;
2671285242Sachim          }
2672285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2673285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2674285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2675285242Sachim#endif
2676285242Sachim          return;
2677285242Sachim        }
2678285242Sachim        /* start here */
2679285242Sachim        dmReportGeneralRespRcvd(
2680285242Sachim                                dmRoot,
2681285242Sachim                                agRoot,
2682285242Sachim                                agIORequest,
2683285242Sachim                                oneDeviceData,
2684285242Sachim                                dmResponseSMPFrameHeader,
2685285242Sachim                                agFrameHandle
2686285242Sachim                                );
2687285242Sachim        break;
2688285242Sachim      case SMP_DISCOVER:
2689285242Sachim        DM_DBG3(("dmSMPCompleted: discover\n"));
2690285242Sachim        if (agIOInfoLen != sizeof(smpRespDiscover_t) + 4 &&
2691285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2692285242Sachim        {
2693285242Sachim          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespDiscover_t) + 4));
2694285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2695285242Sachim          /* SMP request */
2696285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2697285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2698285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2699285242Sachim
2700285242Sachim#ifndef DIRECT_SMP
2701285242Sachim          /* SMP response */
2702285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2703285242Sachim          if (dmSMPResponseBody == agNULL)
2704285242Sachim          {
2705285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2706285242Sachim            return;
2707285242Sachim          }
2708285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2709285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2710285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2711285242Sachim#endif
2712285242Sachim          return;
2713285242Sachim        }
2714285242Sachim        dmDiscoverRespRcvd(
2715285242Sachim                           dmRoot,
2716285242Sachim                           agRoot,
2717285242Sachim                           agIORequest,
2718285242Sachim                           oneDeviceData,
2719285242Sachim                           dmResponseSMPFrameHeader,
2720285242Sachim                           agFrameHandle
2721285242Sachim                           );
2722285242Sachim        break;
2723285242Sachim      case SMP_REPORT_PHY_SATA:
2724285242Sachim        DM_DBG3(("dmSMPCompleted: report phy sata\n"));
2725285242Sachim        if (agIOInfoLen != sizeof(smpRespReportPhySata_t) + 4 &&
2726285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2727285242Sachim        {
2728285242Sachim          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportPhySata_t) + 4));
2729285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2730285242Sachim          /* SMP request */
2731285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2732285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2733285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2734285242Sachim
2735285242Sachim#ifndef DIRECT_SMP
2736285242Sachim          /* SMP response */
2737285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2738285242Sachim          if (dmSMPResponseBody == agNULL)
2739285242Sachim          {
2740285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2741285242Sachim            return;
2742285242Sachim          }
2743285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2744285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2745285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2746285242Sachim#endif
2747285242Sachim          return;
2748285242Sachim        }
2749285242Sachim        dmReportPhySataRcvd(
2750285242Sachim                            dmRoot,
2751285242Sachim                            agRoot,
2752285242Sachim                            agIORequest,
2753285242Sachim                            oneDeviceData,
2754285242Sachim                            dmResponseSMPFrameHeader,
2755285242Sachim                            agFrameHandle
2756285242Sachim                            );
2757285242Sachim        break;
2758285242Sachim      case SMP_CONFIGURE_ROUTING_INFORMATION:
2759285242Sachim        DM_DBG3(("dmSMPCompleted: configure routing information\n"));
2760285242Sachim        if (agIOInfoLen != 4 &&
2761285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
2762285242Sachim        {
2763285242Sachim          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
2764285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2765285242Sachim          /* SMP request */
2766285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2767285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2768285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2769285242Sachim
2770285242Sachim#ifndef DIRECT_SMP
2771285242Sachim          /* SMP response */
2772285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2773285242Sachim          if (dmSMPResponseBody == agNULL)
2774285242Sachim          {
2775285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2776285242Sachim            return;
2777285242Sachim          }
2778285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2779285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2780285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2781285242Sachim#endif
2782285242Sachim          return;
2783285242Sachim        }
2784285242Sachim        dmConfigRoutingInfoRespRcvd(
2785285242Sachim                                    dmRoot,
2786285242Sachim                                    agRoot,
2787285242Sachim                                    agIORequest,
2788285242Sachim                                    oneDeviceData,
2789285242Sachim                                    dmResponseSMPFrameHeader,
2790285242Sachim                                    agFrameHandle
2791285242Sachim                                    );
2792285242Sachim
2793285242Sachim        break;
2794285242Sachim      case SMP_PHY_CONTROL:
2795285242Sachim        DM_DBG3(("dmSMPCompleted: phy control\n"));
2796285242Sachim        if (agIOInfoLen != 4 &&
2797285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */
2798285242Sachim        {
2799285242Sachim          DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
2800285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2801285242Sachim
2802285242Sachim          /* SMP request */
2803285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2804285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
2805285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2806285242Sachim
2807285242Sachim#ifndef DIRECT_SMP
2808285242Sachim          /* SMP response */
2809285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
2810285242Sachim          if (dmSMPResponseBody == agNULL)
2811285242Sachim          {
2812285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
2813285242Sachim            return;
2814285242Sachim          }
2815285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
2816285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
2817285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
2818285242Sachim#endif
2819285242Sachim          return;
2820285242Sachim        }
2821285242Sachim        dmPhyControlRespRcvd(
2822285242Sachim                             dmRoot,
2823285242Sachim                             agRoot,
2824285242Sachim                             agIORequest,
2825285242Sachim                             oneDeviceData,
2826285242Sachim                             dmResponseSMPFrameHeader,
2827285242Sachim                             agFrameHandle
2828285242Sachim                            );
2829285242Sachim        break;
2830285242Sachim      case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
2831285242Sachim      case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
2832285242Sachim      case SMP_PHY_TEST_FUNCTION: /* fall through */
2833285242Sachim      case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
2834285242Sachim      case SMP_READ_GPIO_REGISTER: /* fall through */
2835285242Sachim      case SMP_WRITE_GPIO_REGISTER: /* fall through */
2836285242Sachim      default:
2837285242Sachim        DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunction));
2838285242Sachim        DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x !!!\n", dmResponseSMPFrameHeader->smpFrameType));
2839285242Sachim        DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunctionResult));
2840285242Sachim        DM_DBG1(("dmSMPCompleted: smpReserved 0x%x !!!\n", dmResponseSMPFrameHeader->smpReserved));
2841285242Sachim        dmhexdump("dmSMPCompleted: SMP payload !!!", (bit8 *)agFrameHandle, agIOInfoLen);
2842285242Sachim        break;
2843285242Sachim      } /* switch */
2844285242Sachim    } /* OSSA_IO_SUCCESS */
2845285242Sachim    else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
2846285242Sachim    {
2847285242Sachim      /* no retry this case */
2848285242Sachim      DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
2849285242Sachim    }
2850285242Sachim    else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
2851285242Sachim    {
2852285242Sachim      DM_DBG3(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
2853285242Sachim      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2854285242Sachim      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2855285242Sachim
2856285242Sachim      status = saSMPStart(
2857285242Sachim                 agRoot,
2858285242Sachim                 agIORequest,
2859285242Sachim                 0,
2860285242Sachim                 agDevHandle,
2861285242Sachim                 AGSA_SMP_INIT_REQ,
2862285242Sachim                 agSASRequestBody,
2863285242Sachim                 &dmsaSMPCompleted
2864285242Sachim                 );
2865285242Sachim
2866285242Sachim      if (status == AGSA_RC_SUCCESS)
2867285242Sachim      {
2868285242Sachim        /* increment the number of pending SMP */
2869285242Sachim        onePortContext->discovery.pendingSMP++;
2870285242Sachim        if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
2871285242Sachim            SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2872285242Sachim            SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2873285242Sachim           )
2874285242Sachim        {
2875285242Sachim          /* start discovery-related SMP timer */
2876285242Sachim          dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
2877285242Sachim        }
2878285242Sachim        return;
2879285242Sachim      }
2880285242Sachim      else if (status == AGSA_RC_BUSY)
2881285242Sachim      {
2882285242Sachim        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
2883285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
2884285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
2885285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2886285242Sachim           )
2887285242Sachim        {
2888285242Sachim          dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
2889285242Sachim        }
2890285242Sachim        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
2891285242Sachim        {
2892285242Sachim          /* For taskmanagement SMP, let's fail task management failure */
2893285242Sachim          dmPhyControlFailureRespRcvd(
2894285242Sachim                                      dmRoot,
2895285242Sachim                                      agRoot,
2896285242Sachim                                      oneDeviceData,
2897285242Sachim                                      dmResponseSMPFrameHeader,
2898285242Sachim                                      agFrameHandle
2899285242Sachim                                     );
2900285242Sachim        }
2901285242Sachim        else
2902285242Sachim        {
2903285242Sachim        }
2904285242Sachim      }
2905285242Sachim      else /* AGSA_RC_FAILURE */
2906285242Sachim      {
2907285242Sachim        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
2908285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
2909285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
2910285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2911285242Sachim           )
2912285242Sachim        {
2913285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2914285242Sachim        }
2915285242Sachim        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
2916285242Sachim        {
2917285242Sachim          /* task management failure */
2918285242Sachim          dmPhyControlFailureRespRcvd(
2919285242Sachim                                      dmRoot,
2920285242Sachim                                      agRoot,
2921285242Sachim                                      oneDeviceData,
2922285242Sachim                                      dmResponseSMPFrameHeader,
2923285242Sachim                                      agFrameHandle
2924285242Sachim                                     );
2925285242Sachim        }
2926285242Sachim        else
2927285242Sachim        {
2928285242Sachim        }
2929285242Sachim      }
2930285242Sachim    }   /* OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE*/
2931285242Sachim    else
2932285242Sachim    {
2933285242Sachim      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
2934285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
2935285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
2936285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
2937285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
2938285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
2939285242Sachim          agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
2940285242Sachim      {
2941285242Sachim        DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
2942285242Sachim        saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
2943285242Sachim      }
2944285242Sachim      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
2945285242Sachim      {
2946285242Sachim        DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
2947285242Sachim        DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
2948285242Sachim        ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
2949285242Sachim        if (ConnRate == SAS_CONNECTION_RATE_1_5G)
2950285242Sachim        {
2951285242Sachim          /* no retry; failure ??? */
2952285242Sachim          if (SMPRequestFunction == SMP_REPORT_GENERAL ||
2953285242Sachim              SMPRequestFunction == SMP_DISCOVER ||
2954285242Sachim              SMPRequestFunction == SMP_REPORT_PHY_SATA ||
2955285242Sachim              SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
2956285242Sachim             )
2957285242Sachim          {
2958285242Sachim            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
2959285242Sachim          }
2960285242Sachim          else if (SMPRequestFunction == SMP_PHY_CONTROL)
2961285242Sachim          {
2962285242Sachim            /* task management failure */
2963285242Sachim            dmPhyControlFailureRespRcvd(
2964285242Sachim                                        dmRoot,
2965285242Sachim                                        agRoot,
2966285242Sachim                                        oneDeviceData,
2967285242Sachim                                        agNULL,
2968285242Sachim                                        agNULL
2969285242Sachim                                       );
2970285242Sachim          }
2971285242Sachim          else
2972285242Sachim          {
2973285242Sachim          }
2974285242Sachim        }
2975285242Sachim        else
2976285242Sachim        {
2977285242Sachim          ConnRate = ConnRate - 1;
2978285242Sachim        }
2979285242Sachim        agContext = &(dmSMPRequestBody->agContext);
2980285242Sachim        agContext->osData = agIORequest;
2981285242Sachim        saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
2982285242Sachim      }
2983285242Sachim      else
2984285242Sachim      {
2985285242Sachim        if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
2986285242Sachim        {
2987285242Sachim          /* retry the SMP again */
2988285242Sachim          DM_DBG1(("dmSMPCompleted: failed, but retries %d agIOStatus 0x%x %d agIOInfoLen %d !!!\n",
2989285242Sachim                   dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
2990285242Sachim          saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
2991285242Sachim          dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
2992285242Sachim          status = saSMPStart(
2993285242Sachim                              agRoot,
2994285242Sachim                              agIORequest,
2995285242Sachim                              0,
2996285242Sachim                              agDevHandle,
2997285242Sachim                              AGSA_SMP_INIT_REQ,
2998285242Sachim                              agSASRequestBody,
2999285242Sachim                              &dmsaSMPCompleted
3000285242Sachim                             );
3001285242Sachim          if (status == AGSA_RC_SUCCESS)
3002285242Sachim          {
3003285242Sachim            /* increment the number of pending SMP */
3004285242Sachim            onePortContext->discovery.pendingSMP++;
3005285242Sachim            dmSMPRequestBody->retries++;
3006285242Sachim            if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3007285242Sachim                SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3008285242Sachim                SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3009285242Sachim               )
3010285242Sachim            {
3011285242Sachim              /* start discovery-related SMP timer */
3012285242Sachim              dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3013285242Sachim            }
3014285242Sachim            return;
3015285242Sachim          }
3016285242Sachim          else if (status == AGSA_RC_BUSY)
3017285242Sachim          {
3018285242Sachim            onePortContext->discovery.pendingSMP++;
3019285242Sachim            dmSMPRequestBody->retries++;
3020285242Sachim            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3021285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3022285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3023285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3024285242Sachim               )
3025285242Sachim            {
3026285242Sachim              dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3027285242Sachim              return;
3028285242Sachim            }
3029285242Sachim            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3030285242Sachim            {
3031285242Sachim              /* For taskmanagement SMP, let's fail task management failure */
3032285242Sachim              dmPhyControlFailureRespRcvd(
3033285242Sachim                                          dmRoot,
3034285242Sachim                                          agRoot,
3035285242Sachim                                          oneDeviceData,
3036285242Sachim                                          dmResponseSMPFrameHeader,
3037285242Sachim                                          agFrameHandle
3038285242Sachim                                         );
3039285242Sachim            }
3040285242Sachim            else
3041285242Sachim            {
3042285242Sachim            }
3043285242Sachim          }
3044285242Sachim          else /* AGSA_RC_FAILURE */
3045285242Sachim          {
3046285242Sachim            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3047285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3048285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3049285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3050285242Sachim               )
3051285242Sachim            {
3052285242Sachim              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3053285242Sachim            }
3054285242Sachim            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3055285242Sachim            {
3056285242Sachim              /* task management failure */
3057285242Sachim              dmPhyControlFailureRespRcvd(
3058285242Sachim                                          dmRoot,
3059285242Sachim                                          agRoot,
3060285242Sachim                                          oneDeviceData,
3061285242Sachim                                          dmResponseSMPFrameHeader,
3062285242Sachim                                          agFrameHandle
3063285242Sachim                                         );
3064285242Sachim            }
3065285242Sachim            else
3066285242Sachim            {
3067285242Sachim            }
3068285242Sachim          }
3069285242Sachim        }
3070285242Sachim        else
3071285242Sachim        {
3072285242Sachim          dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
3073285242Sachim          dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
3074285242Sachim          DM_DBG1(("dmSMPCompleted: failed. no more retry. agIOStatus 0x%x %d !!!\n", agIOStatus, agIOStatus));
3075285242Sachim          if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
3076285242Sachim          {
3077285242Sachim            DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
3078285242Sachim          }
3079285242Sachim          if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
3080285242Sachim          {
3081285242Sachim            DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_IN_RECOVERY!!!\n"));
3082285242Sachim          }
3083285242Sachim          if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3084285242Sachim              dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3085285242Sachim              dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3086285242Sachim              dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3087285242Sachim             )
3088285242Sachim          {
3089285242Sachim            /* discovery failure */
3090285242Sachim            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3091285242Sachim            DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3092285242Sachim            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3093285242Sachim          }
3094285242Sachim          else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3095285242Sachim          {
3096285242Sachim            DM_DBG3(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
3097285242Sachim            smpPhyControlReq = (smpReqPhyControl_t *)dmSMPPayload;
3098285242Sachim            if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
3099285242Sachim            {
3100285242Sachim              DM_DBG3(("dmSMPCompleted: discover done with error\n"));
3101285242Sachim              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3102285242Sachim            }
3103285242Sachim            else
3104285242Sachim            {
3105285242Sachim              DM_DBG3(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControlReq->phyOperation));
3106285242Sachim            }
3107285242Sachim          } /* SMP_PHY_CONTROL */
3108285242Sachim          else
3109285242Sachim          {
3110285242Sachim            DM_DBG3(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3111285242Sachim          }
3112285242Sachim        } /* else */
3113285242Sachim      } /* for RateAdjust */
3114285242Sachim    } /* outer else */
3115285242Sachim  } /* SAS 1.1 */
3116285242Sachim  /************************************     SAS 2     ***********************************************/
3117285242Sachim  else
3118285242Sachim  {
3119285242Sachim    DM_DBG2(("dmSMPCompleted: SAS 2\n"));
3120285242Sachim    if (agIOStatus == OSSA_IO_SUCCESS)
3121285242Sachim    {
3122285242Sachim      //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
3123285242Sachim      /* parsing SMP payload */
3124285242Sachim#ifdef DIRECT_SMP
3125285242Sachim    saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3126285242Sachim#else
3127285242Sachim    dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3128285242Sachim    saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
3129285242Sachim#endif
3130285242Sachim    dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3131285242Sachim
3132285242Sachim      /* SMP function dependent payload */
3133285242Sachim      switch (dmResponseSMPFrameHeader->smpFunction)
3134285242Sachim      {
3135285242Sachim      case SMP_REPORT_GENERAL:
3136285242Sachim        DM_DBG2(("dmSMPCompleted: report general\n"));
3137285242Sachim        if ((agIOInfoLen != sizeof(smpRespReportGeneral2_t) + 4) &&
3138285242Sachim             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3139285242Sachim           )
3140285242Sachim        {
3141285242Sachim          DM_DBG1(("dmSMPCompleted: report general mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportGeneral2_t) + 4));
3142285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3143285242Sachim
3144285242Sachim          /* SMP request */
3145285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3146285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3147285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3148285242Sachim
3149285242Sachim#ifndef DIRECT_SMP
3150285242Sachim          /* SMP response */
3151285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3152285242Sachim          if (dmSMPResponseBody == agNULL)
3153285242Sachim          {
3154285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3155285242Sachim            return;
3156285242Sachim          }
3157285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3158285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3159285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3160285242Sachim#endif
3161285242Sachim
3162285242Sachim          return;
3163285242Sachim        }
3164285242Sachim
3165285242Sachim        dmReportGeneral2RespRcvd(
3166285242Sachim                                  dmRoot,
3167285242Sachim                                  agRoot,
3168285242Sachim                                  agIORequest,
3169285242Sachim                                  oneDeviceData,
3170285242Sachim                                  dmResponseSMPFrameHeader,
3171285242Sachim                                  agFrameHandle
3172285242Sachim                                  );
3173285242Sachim        break;
3174285242Sachim      case SMP_DISCOVER:
3175285242Sachim        DM_DBG2(("dmSMPCompleted: discover\n"));
3176285242Sachim        if ((agIOInfoLen != sizeof(smpRespDiscover2_t) + 4) &&
3177285242Sachim             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3178285242Sachim           )
3179285242Sachim        {
3180285242Sachim          DM_DBG1(("dmSMPCompleted: discover mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespDiscover2_t) + 4));
3181285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3182285242Sachim
3183285242Sachim          /* SMP request */
3184285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3185285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3186285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3187285242Sachim
3188285242Sachim#ifndef DIRECT_SMP
3189285242Sachim          /* SMP response */
3190285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3191285242Sachim          if (dmSMPResponseBody == agNULL)
3192285242Sachim          {
3193285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3194285242Sachim            return;
3195285242Sachim          }
3196285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3197285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3198285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3199285242Sachim#endif
3200285242Sachim
3201285242Sachim          return;
3202285242Sachim        }
3203285242Sachim        dmDiscover2RespRcvd(
3204285242Sachim                             dmRoot,
3205285242Sachim                             agRoot,
3206285242Sachim                             agIORequest,
3207285242Sachim                                oneDeviceData,
3208285242Sachim                             dmResponseSMPFrameHeader,
3209285242Sachim                             agFrameHandle
3210285242Sachim                             );
3211285242Sachim        break;
3212285242Sachim      case SMP_REPORT_PHY_SATA:
3213285242Sachim        DM_DBG2(("dmSMPCompleted: report phy sata\n"));
3214285242Sachim        if ((agIOInfoLen != sizeof(smpRespReportPhySata2_t) + 4) &&
3215285242Sachim             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3216285242Sachim           )
3217285242Sachim        {
3218285242Sachim          DM_DBG1(("dmSMPCompleted: report phy sata mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportPhySata2_t) + 4));
3219285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3220285242Sachim
3221285242Sachim          /* SMP request */
3222285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3223285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3224285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3225285242Sachim
3226285242Sachim#ifndef DIRECT_SMP
3227285242Sachim          /* SMP response */
3228285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3229285242Sachim          if (dmSMPResponseBody == agNULL)
3230285242Sachim          {
3231285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3232285242Sachim            return;
3233285242Sachim          }
3234285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3235285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3236285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3237285242Sachim#endif
3238285242Sachim
3239285242Sachim          return;
3240285242Sachim        }
3241285242Sachim        dmReportPhySata2Rcvd(
3242285242Sachim                              dmRoot,
3243285242Sachim                              agRoot,
3244285242Sachim                              agIORequest,
3245285242Sachim                              oneDeviceData,
3246285242Sachim                              dmResponseSMPFrameHeader,
3247285242Sachim                              agFrameHandle
3248285242Sachim                              );
3249285242Sachim        break;
3250285242Sachim      case SMP_CONFIGURE_ROUTING_INFORMATION:
3251285242Sachim        DM_DBG2(("dmSMPCompleted: configure routing information\n"));
3252285242Sachim        if (agIOInfoLen != 4 &&
3253285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3254285242Sachim           )
3255285242Sachim        {
3256285242Sachim          DM_DBG1(("dmSMPCompleted: configure routing information mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
3257285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3258285242Sachim
3259285242Sachim          /* SMP request */
3260285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3261285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3262285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3263285242Sachim
3264285242Sachim#ifndef DIRECT_SMP
3265285242Sachim          /* SMP response */
3266285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3267285242Sachim          if (dmSMPResponseBody == agNULL)
3268285242Sachim          {
3269285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3270285242Sachim            return;
3271285242Sachim          }
3272285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3273285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3274285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3275285242Sachim#endif
3276285242Sachim
3277285242Sachim          return;
3278285242Sachim        }
3279285242Sachim        dmConfigRoutingInfo2RespRcvd(
3280285242Sachim                                      dmRoot,
3281285242Sachim                                      agRoot,
3282285242Sachim                                      agIORequest,
3283285242Sachim                                      oneDeviceData,
3284285242Sachim                                      dmResponseSMPFrameHeader,
3285285242Sachim                                      agFrameHandle
3286285242Sachim                                      );
3287285242Sachim
3288285242Sachim        break;
3289285242Sachim      case SMP_PHY_CONTROL:
3290285242Sachim        DM_DBG2(("dmSMPCompleted: phy control\n"));
3291285242Sachim        if (agIOInfoLen != 4 &&
3292285242Sachim            dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
3293285242Sachim           ) /*zero length is expected */
3294285242Sachim        {
3295285242Sachim          DM_DBG1(("dmSMPCompleted: phy control mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
3296285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3297285242Sachim
3298285242Sachim          /* SMP request */
3299285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3300285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3301285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3302285242Sachim
3303285242Sachim#ifndef DIRECT_SMP
3304285242Sachim          /* SMP response */
3305285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3306285242Sachim          if (dmSMPResponseBody == agNULL)
3307285242Sachim          {
3308285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3309285242Sachim            return;
3310285242Sachim          }
3311285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3312285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3313285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3314285242Sachim#endif
3315285242Sachim
3316285242Sachim          return;
3317285242Sachim        }
3318285242Sachim        dmPhyControl2RespRcvd(
3319285242Sachim                               dmRoot,
3320285242Sachim                               agRoot,
3321285242Sachim                               agIORequest,
3322285242Sachim             oneDeviceData,
3323285242Sachim                               dmResponseSMPFrameHeader,
3324285242Sachim                               agFrameHandle
3325285242Sachim            );
3326285242Sachim
3327285242Sachim
3328285242Sachim        break;
3329285242Sachim#ifdef NOT_YET
3330285242Sachim      case SMP_DISCOVER_LIST:
3331285242Sachim        DM_DBG1(("dmSMPCompleted: SMP_DISCOVER_LIST\n"));
3332285242Sachim        DM_DBG1(("dmSMPCompleted: agIOInfoLen 0x%x \n", agIOInfoLen));
3333285242Sachim        tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
3334285242Sachim        dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3335285242Sachim
3336285242Sachim          /* SMP request */
3337285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3338285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3339285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3340285242Sachim
3341285242Sachim#ifndef DIRECT_SMP
3342285242Sachim          /* SMP response */
3343285242Sachim          dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3344285242Sachim          if (dmSMPResponseBody == agNULL)
3345285242Sachim          {
3346285242Sachim            DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3347285242Sachim            return;
3348285242Sachim          }
3349285242Sachim          tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3350285242Sachim          DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3351285242Sachim          tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3352285242Sachim#endif
3353285242Sachim
3354285242Sachim        return;
3355285242Sachim        break;
3356285242Sachim#endif
3357285242Sachim      case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
3358285242Sachim      case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
3359285242Sachim      case SMP_PHY_TEST_FUNCTION: /* fall through */
3360285242Sachim      case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
3361285242Sachim      case SMP_READ_GPIO_REGISTER: /* fall through */
3362285242Sachim      case SMP_WRITE_GPIO_REGISTER: /* fall through */
3363285242Sachim      default:
3364285242Sachim        DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x\n", dmResponseSMPFrameHeader->smpFunction));
3365285242Sachim        DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x\n", dmResponseSMPFrameHeader->smpFrameType));
3366285242Sachim        DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x\n", dmResponseSMPFrameHeader->smpFunctionResult));
3367285242Sachim        DM_DBG1(("dmSMPCompleted: smpReserved 0x%x\n", dmResponseSMPFrameHeader->smpReserved));
3368285242Sachim        dmhexdump("dmSMPCompleted: SMP payload", (bit8 *)agFrameHandle, agIOInfoLen);
3369285242Sachim        break;
3370285242Sachim      }
3371285242Sachim    } /* agIOStatus == OSSA_IO_SUCCESS */
3372285242Sachim    else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
3373285242Sachim    {
3374285242Sachim      /* no retry this case */
3375285242Sachim      DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
3376285242Sachim    }
3377285242Sachim    else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
3378285242Sachim    {
3379285242Sachim      DM_DBG1(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
3380285242Sachim      saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3381285242Sachim      dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3382285242Sachim
3383285242Sachim      status = saSMPStart(
3384285242Sachim                          agRoot,
3385285242Sachim                          agIORequest,
3386285242Sachim                          0,
3387285242Sachim                          agDevHandle,
3388285242Sachim                          AGSA_SMP_INIT_REQ,
3389285242Sachim                          agSASRequestBody,
3390285242Sachim                          &dmsaSMPCompleted
3391285242Sachim                         );
3392285242Sachim
3393285242Sachim
3394285242Sachim      if (status == AGSA_RC_SUCCESS)
3395285242Sachim      {
3396285242Sachim        /* increment the number of pending SMP */
3397285242Sachim        onePortContext->discovery.pendingSMP++;
3398285242Sachim        if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3399285242Sachim            SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3400285242Sachim            SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3401285242Sachim           )
3402285242Sachim        {
3403285242Sachim          /* start discovery-related SMP timer */
3404285242Sachim          dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3405285242Sachim        }
3406285242Sachim        return;
3407285242Sachim      }
3408285242Sachim      else if (status == AGSA_RC_BUSY)
3409285242Sachim      {
3410285242Sachim        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3411285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3412285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3413285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3414285242Sachim           )
3415285242Sachim        {
3416285242Sachim          dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3417285242Sachim        }
3418285242Sachim        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3419285242Sachim        {
3420285242Sachim          /* For taskmanagement SMP, let's fail task management failure */
3421285242Sachim          dmPhyControlFailureRespRcvd(
3422285242Sachim                                      dmRoot,
3423285242Sachim                                      agRoot,
3424285242Sachim                                      oneDeviceData,
3425285242Sachim                                      dmResponseSMPFrameHeader,
3426285242Sachim                                      agFrameHandle
3427285242Sachim                                     );
3428285242Sachim        }
3429285242Sachim        else
3430285242Sachim        {
3431285242Sachim        }
3432285242Sachim      }
3433285242Sachim      else /* AGSA_RC_FAILURE */
3434285242Sachim      {
3435285242Sachim        if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3436285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3437285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3438285242Sachim            dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3439285242Sachim      )
3440285242Sachim        {
3441285242Sachim          dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3442285242Sachim        }
3443285242Sachim        else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3444285242Sachim        {
3445285242Sachim          /* task management failure */
3446285242Sachim          dmPhyControlFailureRespRcvd(
3447285242Sachim                                      dmRoot,
3448285242Sachim                                      agRoot,
3449285242Sachim                                      oneDeviceData,
3450285242Sachim                                      dmResponseSMPFrameHeader,
3451285242Sachim                                      agFrameHandle
3452285242Sachim                                     );
3453285242Sachim        }
3454285242Sachim        else
3455285242Sachim        {
3456285242Sachim        }
3457285242Sachim      }
3458285242Sachim    }
3459285242Sachim    else if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION)
3460285242Sachim    {
3461285242Sachim      DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
3462285242Sachim      /*
3463285242Sachim         skip to the next expander
3464285242Sachim      */
3465285242Sachim      dmHandleZoneViolation(
3466285242Sachim                           dmRoot,
3467285242Sachim                           agRoot,
3468285242Sachim                           agIORequest,
3469285242Sachim                           oneDeviceData,
3470285242Sachim                           agNULL,
3471285242Sachim                           agFrameHandle
3472285242Sachim                           );
3473285242Sachim    }
3474285242Sachim    else
3475285242Sachim    {
3476285242Sachim      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
3477285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
3478285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
3479285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
3480285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
3481285242Sachim          agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
3482285242Sachim          agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
3483285242Sachim      {
3484285242Sachim        DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
3485285242Sachim        saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
3486285242Sachim      }
3487285242Sachim      if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
3488285242Sachim      {
3489285242Sachim        DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
3490285242Sachim        DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
3491285242Sachim        ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
3492285242Sachim        if (ConnRate == SAS_CONNECTION_RATE_1_5G)
3493285242Sachim        {
3494285242Sachim          /* no retry; failure ??? */
3495285242Sachim          if (SMPRequestFunction == SMP_REPORT_GENERAL ||
3496285242Sachim              SMPRequestFunction == SMP_DISCOVER ||
3497285242Sachim              SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3498285242Sachim              SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3499285242Sachim             )
3500285242Sachim          {
3501285242Sachim            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3502285242Sachim          }
3503285242Sachim          else if (SMPRequestFunction == SMP_PHY_CONTROL)
3504285242Sachim          {
3505285242Sachim            /* task management failure */
3506285242Sachim            dmPhyControlFailureRespRcvd(
3507285242Sachim                                        dmRoot,
3508285242Sachim                                        agRoot,
3509285242Sachim                                        oneDeviceData,
3510285242Sachim                                        agNULL,
3511285242Sachim                                        agNULL
3512285242Sachim                                       );
3513285242Sachim          }
3514285242Sachim          else
3515285242Sachim          {
3516285242Sachim          }
3517285242Sachim        }
3518285242Sachim        else
3519285242Sachim        {
3520285242Sachim          ConnRate = ConnRate - 1;
3521285242Sachim        }
3522285242Sachim        agContext = &(dmSMPRequestBody->agContext);
3523285242Sachim        agContext->osData = agIORequest;
3524285242Sachim        saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
3525285242Sachim      }
3526285242Sachim      else
3527285242Sachim      {
3528285242Sachim        if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
3529285242Sachim        {
3530285242Sachim          /* retry the SMP again */
3531285242Sachim          DM_DBG1(("dmSMPCompleted: failed! but retries %d agIOStatus 0x%x %d agIOInfoLen %d\n",
3532285242Sachim                   dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
3533285242Sachim          saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
3534285242Sachim          dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
3535285242Sachim          status = saSMPStart(
3536285242Sachim                              agRoot,
3537285242Sachim                              agIORequest,
3538285242Sachim                              0,
3539285242Sachim                              agDevHandle,
3540285242Sachim                              AGSA_SMP_INIT_REQ,
3541285242Sachim                              agSASRequestBody,
3542285242Sachim                              &dmsaSMPCompleted
3543285242Sachim                             );
3544285242Sachim
3545285242Sachim          if (status == AGSA_RC_SUCCESS)
3546285242Sachim          {
3547285242Sachim            /* increment the number of pending SMP */
3548285242Sachim            onePortContext->discovery.pendingSMP++;
3549285242Sachim            dmSMPRequestBody->retries++;
3550285242Sachim            if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
3551285242Sachim                SMPRequestFunction == SMP_REPORT_PHY_SATA ||
3552285242Sachim                SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3553285242Sachim               )
3554285242Sachim            {
3555285242Sachim              /* start discovery-related SMP timer */
3556285242Sachim              dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
3557285242Sachim            }
3558285242Sachim            return;
3559285242Sachim          }
3560285242Sachim          else if (status == AGSA_RC_BUSY)
3561285242Sachim          {
3562285242Sachim            onePortContext->discovery.pendingSMP++;
3563285242Sachim            dmSMPRequestBody->retries++;
3564285242Sachim            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3565285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3566285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3567285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3568285242Sachim               )
3569285242Sachim            {
3570285242Sachim              dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
3571285242Sachim              return;
3572285242Sachim            }
3573285242Sachim            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3574285242Sachim            {
3575285242Sachim              /* For taskmanagement SMP, let's fail task management failure */
3576285242Sachim              dmPhyControlFailureRespRcvd(
3577285242Sachim                                          dmRoot,
3578285242Sachim                                          agRoot,
3579285242Sachim                                          oneDeviceData,
3580285242Sachim                                          dmResponseSMPFrameHeader,
3581285242Sachim                                          agFrameHandle
3582285242Sachim                                         );
3583285242Sachim            }
3584285242Sachim            else
3585285242Sachim            {
3586285242Sachim            }
3587285242Sachim          }
3588285242Sachim          else /* AGSA_RC_FAILURE */
3589285242Sachim          {
3590285242Sachim            if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3591285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3592285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3593285242Sachim                dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3594285242Sachim               )
3595285242Sachim            {
3596285242Sachim              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3597285242Sachim            }
3598285242Sachim            else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3599285242Sachim            {
3600285242Sachim              /* task management failure */
3601285242Sachim              dmPhyControlFailureRespRcvd(
3602285242Sachim                                          dmRoot,
3603285242Sachim                                          agRoot,
3604285242Sachim                                          oneDeviceData,
3605285242Sachim                                          dmResponseSMPFrameHeader,
3606285242Sachim                                          agFrameHandle
3607285242Sachim                                         );
3608285242Sachim            }
3609285242Sachim            else
3610285242Sachim            {
3611285242Sachim            }
3612285242Sachim          }
3613285242Sachim        }
3614285242Sachim        else
3615285242Sachim        {
3616285242Sachim          dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
3617285242Sachim          dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
3618285242Sachim          DM_DBG1(("dmSMPCompleted: failed! no more retry! agIOStatus 0x%x %d\n", agIOStatus, agIOStatus));
3619285242Sachim          if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
3620285242Sachim          {
3621285242Sachim            DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_NON_OPERATIONAL\n"));
3622285242Sachim          }
3623285242Sachim          if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
3624285242Sachim          {
3625285242Sachim            DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_IN_RECOVERY\n"));
3626285242Sachim          }
3627285242Sachim          if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
3628285242Sachim              dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
3629285242Sachim              dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
3630285242Sachim              dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
3631285242Sachim             )
3632285242Sachim          {
3633285242Sachim            /* discovery failure */
3634285242Sachim            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3635285242Sachim            DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3636285242Sachim            dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3637285242Sachim          }
3638285242Sachim          else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
3639285242Sachim          {
3640285242Sachim            DM_DBG1(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
3641285242Sachim            smpPhyControl2Req = (smpReqPhyControl2_t *)dmSMPPayload;
3642285242Sachim            if (smpPhyControl2Req->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
3643285242Sachim            {
3644285242Sachim              DM_DBG1(("dmSMPCompleted: discover done with error\n"));
3645285242Sachim              dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
3646285242Sachim            }
3647285242Sachim            else
3648285242Sachim            {
3649285242Sachim              DM_DBG1(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControl2Req->phyOperation));
3650285242Sachim            }
3651285242Sachim          } /* SMP_PHY_CONTROL */
3652285242Sachim          else
3653285242Sachim          {
3654285242Sachim            DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
3655285242Sachim          }
3656285242Sachim        } /* else */
3657285242Sachim      } /* for RateAdjust */
3658285242Sachim    } /* outer else */
3659285242Sachim  } /* SAS 2 else */
3660285242Sachim
3661285242Sachim  /* SMP request */
3662285242Sachim  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3663285242Sachim  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3664285242Sachim  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3665285242Sachim
3666285242Sachim#ifndef DIRECT_SMP
3667285242Sachim  /* SMP response */
3668285242Sachim  dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
3669285242Sachim  if (dmSMPResponseBody == agNULL)
3670285242Sachim  {
3671285242Sachim    DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
3672285242Sachim    return;
3673285242Sachim  }
3674285242Sachim  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3675285242Sachim  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
3676285242Sachim  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3677285242Sachim#endif
3678285242Sachim
3679285242Sachim  return;
3680285242Sachim}
3681285242Sachim
3682285242SachimosGLOBAL void
3683285242SachimdmSMPAbortCB(
3684285242Sachim             agsaRoot_t           *agRoot,
3685285242Sachim             agsaIORequest_t      *agIORequest,
3686285242Sachim             bit32                flag,
3687285242Sachim             bit32                status)
3688285242Sachim{
3689285242Sachim  dmRoot_t             *dmRoot = agNULL;
3690285242Sachim  dmIntRoot_t          *dmIntRoot    = agNULL;
3691285242Sachim  dmIntContext_t       *dmAllShared = agNULL;
3692285242Sachim  dmSMPRequestBody_t   *dmSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
3693285242Sachim
3694285242Sachim  DM_DBG5(("dmSMPAbortCB: start\n"));
3695285242Sachim
3696285242Sachim  if (dmSMPRequestBody == agNULL)
3697285242Sachim  {
3698285242Sachim    DM_DBG1(("dmSMPAbortCB: pSMPRequestBody is NULL!!! \n"));
3699285242Sachim    return;
3700285242Sachim  }
3701285242Sachim
3702285242Sachim  dmRoot = dmSMPRequestBody->dmRoot;
3703285242Sachim  dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
3704285242Sachim  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
3705285242Sachim
3706285242Sachim
3707285242Sachim  /* put back into free smplist */
3708285242Sachim  tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
3709285242Sachim  DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
3710285242Sachim  tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
3711285242Sachim
3712285242Sachim  /* start here */
3713285242Sachim  if (flag == 2)
3714285242Sachim  {
3715285242Sachim    /* abort all per port */
3716285242Sachim    DM_DBG1(("dmSMPAbortCB: abort per port; not used!!!\n"));
3717285242Sachim  }
3718285242Sachim  else if (flag == 1)
3719285242Sachim  {
3720285242Sachim    /* abort all */
3721285242Sachim    DM_DBG1(("dmSMPAbortCB: abort all; not used!!!\n"));
3722285242Sachim  }
3723285242Sachim  else if (flag == 0)
3724285242Sachim  {
3725285242Sachim    /* abort one */
3726285242Sachim    DM_DBG1(("ossaSMPAbortCB: abort one\n"));
3727285242Sachim    if (status != OSSA_IO_SUCCESS)
3728285242Sachim    {
3729285242Sachim      DM_DBG1(("dmSMPAbortCB: abort one, status 0x%x\n", status));
3730285242Sachim    }
3731285242Sachim  }
3732285242Sachim  else
3733285242Sachim  {
3734285242Sachim    DM_DBG1(("dmSMPAbortCB: not allowed case, flag 0x%x!!!\n", flag));
3735285242Sachim  }
3736285242Sachim
3737285242Sachim  return;
3738285242Sachim}
3739285242Sachim
3740285242Sachim
3741285242Sachim#endif /* FDS_DM */
3742285242Sachim
3743285242Sachim
3744