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