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