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