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 /*! \file saphy.c
24 * \brief The file implements the functions to Start, Stop a phy
25 *
26 *
27 */
28 /******************************************************************************/
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 #include <dev/pms/config.h>
32
33 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
34 #ifdef SA_ENABLE_TRACE_FUNCTIONS
35 #ifdef siTraceFileID
36 #undef siTraceFileID
37 #endif
38 #define siTraceFileID 'K'
39 #endif
40
41
42 extern bit32 gFPGA_TEST;
43 /******************************************************************************/
44 /*! \brief Start a Phy
45 *
46 * Start a Phy
47 *
48 * \param agRoot handles for this instance of SAS/SATA hardware
49 * \param agContext
50 * \param phyId the phy id of the link will be started
51 * \param agPhyConfig the phy configuration
52 * \param agSASIdentify the SAS identify frame will be sent by the phy
53 *
54 * \return If phy is started successfully
55 * - \e AGSA_RC_SUCCESS phy is started successfully
56 * - \e AGSA_RC_BUSY phy is already started or starting
57 * - \e AGSA_RC_FAILURE phy is not started successfully
58 */
59 /*******************************************************************************/
60 GLOBAL bit32 saPhyStart(
61 agsaRoot_t *agRoot,
62 agsaContext_t *agContext,
63 bit32 queueNum,
64 bit32 phyId,
65 agsaPhyConfig_t *agPhyConfig,
66 agsaSASIdentify_t *agSASIdentify
67 )
68 {
69 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
70 agsaIORequestDesc_t *pRequest;
71 bit32 ret = AGSA_RC_SUCCESS;
72 bit32 using_reserved = agFALSE;
73
74 smTraceFuncEnter(hpDBG_VERY_LOUD, "7a");
75
76 /* sanity check */
77 SA_ASSERT((agNULL != agRoot), "");
78 SA_ASSERT((agNULL != agSASIdentify), "");
79
80 SA_DBG3(("saPhyStart: phy%d started with ID %08X:%08X\n",
81 phyId,
82 SA_IDFRM_GET_SAS_ADDRESSHI(agSASIdentify),
83 SA_IDFRM_GET_SAS_ADDRESSLO(agSASIdentify)));
84
85 /* If phyId is invalid, return failure */
86 if ( phyId >= saRoot->phyCount )
87 {
88 ret = AGSA_RC_FAILURE;
89 }
90 /* If phyId is valid */
91 else
92 {
93 /* Get request from free IORequests */
94 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
95 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */
96 /* If no LL Control request entry available */
97 if ( agNULL == pRequest )
98 {
99 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
100 /* If no LL Control request entry available */
101 if(agNULL != pRequest)
102 {
103 using_reserved = agTRUE;
104 SA_DBG1(("saPhyStart, using saRoot->freeReservedRequests\n"));
105 }
106 else
107 {
108 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
109 SA_DBG1(("saPhyStart, No request from free list Not using saRoot->freeReservedRequests\n"));
110 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7a");
111 return AGSA_RC_BUSY;
112 }
113 }
114 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
115 pRequest->valid = agTRUE;
116 /* If LL Control request entry avaliable */
117 if( using_reserved )
118 {
119 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
120 }
121 else
122 {
123 /* Remove the request from free list */
124 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
125 }
126 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
127
128 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
129 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
130 saRoot->IOMap[pRequest->HTag].agContext = agContext;
131 pRequest->valid = agTRUE;
132
133 /* Build the Phy Start IOMB command and send to SPC */
134
135 smTrace(hpDBG_VERY_LOUD,"P2", phyId);
136 /* TP:P2 phyId */
137
138 ret = mpiPhyStartCmd(agRoot, pRequest->HTag, phyId, agPhyConfig, agSASIdentify, queueNum);
139 if (AGSA_RC_SUCCESS != ret)
140 {
141 /* remove the request from IOMap */
142 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
143 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
144 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
145 pRequest->valid = agFALSE;
146
147 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
148 /* return the request to free pool */
149 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
150 {
151 SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest));
152 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
153 }
154 else
155 {
156 /* return the request to free pool */
157 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
158 }
159 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
160 SA_DBG1(("saPhyStart, sending IOMB failed\n" ));
161 }
162 }
163
164 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7a");
165
166 return ret;
167 }
168
169 /******************************************************************************/
170 /*! \brief Stop a Phy
171 *
172 * Stop a Phy
173 *
174 * \param agRoot handles for this instance of SAS/SATA hardware
175 * \param agContext the context of this API
176 * \param phyId the phy id of the link will be stopped
177 *
178 * \return If phy is stopped successfully
179 * - \e AGSA_RC_SUCCESS phy is stopped successfully
180 * - \e AGSA_RC_FAILURE phy is not stopped successfully
181 */
182 /*******************************************************************************/
183 GLOBAL bit32 saPhyStop(
184 agsaRoot_t *agRoot,
185 agsaContext_t *agContext,
186 bit32 queueNum,
187 bit32 phyId
188 )
189 {
190 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
191 agsaIORequestDesc_t *pRequest;
192 bit32 ret = AGSA_RC_SUCCESS;
193 bit32 using_reserved = agFALSE;
194
195 smTraceFuncEnter(hpDBG_VERY_LOUD,"7b");
196
197 /* sanity check */
198 SA_ASSERT((agNULL != agRoot), "");
199
200 SA_DBG2(("saPhyStop: phy%d stop\n", phyId));
201
202 if(1)
203 {
204 mpiOCQueue_t *circularQ;
205 int i;
206 SA_DBG4(("saPhyStop:\n"));
207 for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ )
208 {
209 circularQ = &saRoot->outboundQueue[i];
210 OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0);
211 if(circularQ->producerIdx != circularQ->consumerIdx)
212 {
213 SA_DBG1(("saPhyStop: PI 0x%03x CI 0x%03x\n",circularQ->producerIdx, circularQ->consumerIdx ));
214 }
215 }
216 }
217
218 if(smIS_SPC(agRoot))
219 {
220 phyId &= 0xF;
221 }
222 /* If phyId is invalid, return failure */
223 if ( (phyId & 0xF) >= saRoot->phyCount )
224 {
225 ret = AGSA_RC_FAILURE;
226 SA_DBG1(("saPhyStop: phy%d - failure with phyId\n", phyId));
227 }
228 else
229 {
230 /* If phyId is valid */
231 /* Get request from free IORequests */
232 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
233 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
234 /* If no LL Control request entry available */
235 if ( agNULL == pRequest )
236 {
237 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
238 /* If no LL Control request entry available */
239 if(agNULL != pRequest)
240 {
241 using_reserved = agTRUE;
242 SA_DBG1(("saPhyStop: using saRoot->freeReservedRequests\n"));
243 }
244 else
245 {
246 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
247 SA_DBG1(("saPhyStop, No request from free list Not using saRoot->freeReservedRequests\n"));
248 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7b");
249 return AGSA_RC_BUSY;
250 }
251 }
252 /* Remove the request from free list */
253 if( using_reserved )
254 {
255 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
256 }
257 else
258 {
259 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
260 }
261 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
262 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
263 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
264 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
265 saRoot->IOMap[pRequest->HTag].agContext = agContext;
266 pRequest->valid = agTRUE;
267
268 /* build IOMB command and send to SPC */
269 ret = mpiPhyStopCmd(agRoot, pRequest->HTag, phyId, queueNum);
270 if (AGSA_RC_SUCCESS != ret)
271 {
272 /* remove the request from IOMap */
273 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
274 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
275 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
276
277 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
278 /* return the request to free pool */
279 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
280 {
281 SA_DBG2(("saPhyStop: saving pRequest (%p) for later use\n", pRequest));
282 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
283 }
284 else
285 {
286 /* return the request to free pool */
287 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
288 }
289 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
290 SA_DBG1(("saPhyStop, sending IOMB failed\n" ));
291 }
292 }
293
294 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7b");
295
296 return ret;
297 }
298
299 /******************************************************************************/
300 /*! \brief CallBack Routine to stop a Phy
301 *
302 * CallBack for Stop a Phy
303 *
304 * \param agRoot handles for this instance of SAS/SATA hardware
305 * \param phyId the phy id of the link will be stopped
306 * \param status the status of the phy
307 * \param agContext the context of the saPhyStop
308 *
309 * \return If phy is stopped successfully
310 * - \e AGSA_RC_SUCCESS phy is stopped successfully
311 * - \e AGSA_RC_FAILURE phy is not stopped successfully
312 */
313 /*******************************************************************************/
314 GLOBAL bit32 siPhyStopCB(
315 agsaRoot_t *agRoot,
316 bit32 phyId,
317 bit32 status,
318 agsaContext_t *agContext,
319 bit32 portId,
320 bit32 npipps
321 )
322 {
323 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
324 agsaPhy_t *pPhy;
325 agsaPort_t *pPort;
326 bit32 ret = AGSA_RC_SUCCESS;
327 bit32 iomb_status = status;
328
329 smTraceFuncEnter(hpDBG_VERY_LOUD,"7c");
330
331 /* sanity check */
332 SA_ASSERT((agNULL != agRoot), "");
333
334 /* If phyId is invalid, return failure */
335 if ( phyId >= saRoot->phyCount )
336 {
337 ret = AGSA_RC_FAILURE;
338 SA_DBG1(("siPhyStopCB: phy%d - failure with phyId\n", phyId));
339 /* makeup for CB */
340 status = (status << SHIFT8) | phyId;
341 status |= ((npipps & PORT_STATE_MASK) << SHIFT16);
342 ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
343 }
344 /* If phyId is valid */
345 else
346 {
347 pPhy = &(saRoot->phys[phyId]);
348
349 /* get the port of the phy */
350 pPort = pPhy->pPort;
351
352 /* makeup for CB */
353 status = (status << SHIFT8) | phyId;
354 status |= ((npipps & PORT_STATE_MASK) << SHIFT16);
355 /* Callback to stop phy */
356 if ( agNULL != pPort )
357 {
358 if ( iomb_status == OSSA_SUCCESS && (OSSA_PORT_INVALID == (npipps & PORT_STATE_MASK) ))
359 {
360 SA_DBG1(("siPhyStopCB: phy%d invalidating port\n", phyId));
361 /* invalid port state, remove the port */
362 pPort->status |= PORT_INVALIDATING;
363 saRoot->PortMap[portId].PortStatus |= PORT_INVALIDATING;
364 /* invalid the port */
365 siPortInvalid(agRoot, pPort);
366 /* map out the portmap */
367 saRoot->PortMap[pPort->portId].PortContext = agNULL;
368 saRoot->PortMap[pPort->portId].PortID = PORT_MARK_OFF;
369 saRoot->PortMap[pPort->portId].PortStatus |= PORT_INVALIDATING;
370 }
371 ossaHwCB(agRoot, &(pPort->portContext), OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
372 }
373 else
374 {
375 SA_DBG1(("siPhyStopCB: phy%d - Port is not established\n", phyId));
376 ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL);
377 }
378
379 /* set PHY_STOPPED status */
380 PHY_STATUS_SET(pPhy, PHY_STOPPED);
381
382 /* Exclude the phy from a port */
383 if ( agNULL != pPort )
384 {
385 /* Acquire port list lock */
386 ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK);
387
388 /* Delete the phy from the port */
389 pPort->phyMap[phyId] = agFALSE;
390 saRoot->phys[phyId].pPort = agNULL;
391
392 /* Release port list lock */
393 ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK);
394 }
395 }
396
397 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7c");
398
399 /* return */
400 return ret;
401 }
402
403 /******************************************************************************/
404 /*! \brief Initiate a Local PHY control command
405 *
406 * This function is called to initiate a PHY control command to the local PHY.
407 * The completion of this function is reported in ossaLocalPhyControlCB()
408
409 *
410 * \param agRoot handles for this instance of SAS/SATA hardware
411 * \param agContext the context of this API
412 * \param phyId phy number
413 * \param phyOperation
414 * one of AGSA_PHY_LINK_RESET, AGSA_PHY_HARD_RESET, AGSA_PHY_ENABLE_SPINUP
415 *
416 * \return
417 * - none
418 */
419 /*******************************************************************************/
420 GLOBAL bit32 saLocalPhyControl(
421 agsaRoot_t *agRoot,
422 agsaContext_t *agContext,
423 bit32 queueNum,
424 bit32 phyId,
425 bit32 phyOperation,
426 ossaLocalPhyControlCB_t agCB
427 )
428 {
429 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
430 agsaIORequestDesc_t *pRequest;
431 agsaPhyErrCounters_t errorParam;
432 bit32 ret = AGSA_RC_SUCCESS;
433 bit32 value, value1, value2, copyPhyId;
434 bit32 count = 100;
435 bit32 using_reserved = agFALSE;
436
437
438 /* sanity check */
439 SA_ASSERT((agNULL != saRoot), "");
440 if(saRoot == agNULL)
441 {
442 SA_DBG1(("saLocalPhyControl: saRoot == agNULL\n"));
443 return(AGSA_RC_FAILURE);
444 }
445 smTraceFuncEnter(hpDBG_VERY_LOUD,"7d");
446
447 si_memset(&errorParam,0,sizeof(agsaPhyErrCounters_t));
448 SA_DBG2(("saLocalPhyControl: phy%d operation %08X\n", phyId, phyOperation));
449
450 switch(phyOperation)
451 {
452 case AGSA_PHY_LINK_RESET:
453 case AGSA_PHY_HARD_RESET:
454 case AGSA_PHY_NOTIFY_ENABLE_SPINUP:
455 case AGSA_PHY_BROADCAST_ASYNCH_EVENT:
456 case AGSA_PHY_COMINIT_OOB:
457 {
458 /* Get request from free IORequests */
459 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
460 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
461
462 /* If no LL Control request entry available */
463 if ( agNULL == pRequest )
464 {
465 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
466 /* If no LL Control request entry available */
467 if(agNULL != pRequest)
468 {
469 using_reserved = agTRUE;
470 SA_DBG1(("saLocalPhyControl, using saRoot->freeReservedRequests\n"));
471 }
472 else
473 {
474 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
475 SA_DBG1(("saLocalPhyControl, No request from free list Not using saRoot->freeReservedRequests\n"));
476 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7d");
477 return AGSA_RC_BUSY;
478 }
479 }
480 if( using_reserved )
481 {
482 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
483 }
484 else
485 {
486 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
487 }
488 /* Remove the request from free list */
489 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
490 pRequest->completionCB = (void*)agCB;
491 // pRequest->abortCompletionCB = agCB;
492 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
493 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
494 saRoot->IOMap[pRequest->HTag].agContext = agContext;
495 pRequest->valid = agTRUE;
496 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
497
498 /* Build the local phy control IOMB command and send to SPC */
499 ret = mpiLocalPhyControlCmd(agRoot, pRequest->HTag, phyId, phyOperation, queueNum);
500 if (AGSA_RC_SUCCESS != ret)
501 {
502 /* remove the request from IOMap */
503 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
504 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
505 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
506 pRequest->valid = agFALSE;
507
508 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
509 /* return the request to free pool */
510 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
511 {
512 SA_DBG1(("saLocalPhyControl: saving pRequest (%p) for later use\n", pRequest));
513 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
514 }
515 else
516 {
517 /* return the request to free pool */
518 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
519 }
520 SA_DBG1(("saLocalPhyControl, sending IOMB failed\n" ));
521 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
522 return ret;
523 }
524 }
525 break;
526 case AGSA_PHY_GET_ERROR_COUNTS:
527 {
528 if(smIS_SPCV(agRoot))
529 {
530
531 SA_ASSERT((smIS_SPC(agRoot)), "SPC only");
532 SA_DBG1(("saLocalPhyControl: V AGSA_PHY_GET_ERROR_COUNTS\n" ));
533 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7d");
534 return AGSA_RC_FAILURE;
535 }
536 /* If phyId is invalid, return failure */
537 if ( phyId >= saRoot->phyCount )
538 {
539 ret = AGSA_RC_FAILURE;
540 si_memset(&errorParam, 0, sizeof(agsaPhyErrCounters_t));
541 SA_DBG1(("saLocalPhyControl: phy%d - failure with phyId\n", phyId));
542 /* call back with the status */
543
544 if( agCB == agNULL )
545 {
546 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
547 }
548 else
549 {
550 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
551 }
552 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "7d");
553 return ret;
554 }
555 /* save phyId */
556 copyPhyId = phyId;
557 /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register */
558 if (phyId < 4)
559 {
560 /* for phyId = 0, 1, 2, 3 */
561 value = 0x030000;
562 }
563 else
564 {
565 /* for phyId = 4, 5, 6, 7 */
566 phyId = phyId - 4;
567 value = 0x040000;
568 }
569
570 /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 0 */
571 value1 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK);
572
573 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value1));
574 /* If LCLK_CLEAR bit set then disable it */
575 if (value1 & DEVICE_LCLK_CLEAR)
576 {
577 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value1 & 0xFFFFFFBF) );
578 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value1 & 0xFFFFFFBF)));
579 }
580
581 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value))
582 {
583 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", value));
584 phyId = copyPhyId;
585 /* call back with the status */
586
587 if( agCB == agNULL )
588 {
589 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
590 }
591 else
592 {
593 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
594 }
595
596 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "7d");
597 return AGSA_RC_FAILURE;
598 }
599
600 /* set LCLK = 1 and LCLK_CLEAR = 0 */
601 SPC_WRITE_COUNTER_CNTL(phyId, LCLK);
602
603 /* LCLK bit should be low to be able to read error registers */
604 while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK)
605 {
606 if(--count == 0)
607 {
608 SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value));
609 ret = AGSA_RC_FAILURE;
610 break;
611 }
612 } /* while */
613
614 value = SPC_READ_COUNTER_CNTL(phyId);
615 SA_DBG3(("saLocalPhyControl: SPC_COUNTER_CNTL value = %08X\n", value));
616
617 /* invalidDword */
618 errorParam.invalidDword = SPC_READ_INV_DW_COUNT(phyId);
619 /* runningDisparityError */
620 errorParam.runningDisparityError = SPC_READ_DISP_ERR_COUNT(phyId);
621 /* lossOfDwordSynch */
622 errorParam.lossOfDwordSynch = SPC_READ_LOSS_DW_COUNT(phyId);
623 /* phyResetProblem */
624 errorParam.phyResetProblem = SPC_READ_PHY_RESET_COUNT(phyId);
625 /* codeViolation */
626 errorParam.codeViolation = SPC_READ_CODE_VIO_COUNT(phyId);
627 /* never occurred in SPC8x6G */
628 errorParam.elasticityBufferOverflow = 0;
629 errorParam.receivedErrorPrimitive = 0;
630 errorParam.inboundCRCError = 0;
631
632 SA_DBG3(("saLocalPhyControl:INV_DW_COUNT 0x%x\n", SPC_READ_INV_DW_COUNT(phyId)));
633 SA_DBG3(("saLocalPhyControl:DISP_ERR_COUNT 0x%x\n", SPC_READ_DISP_ERR_COUNT(phyId)));
634 SA_DBG3(("saLocalPhyControl:LOSS_DW_COUNT 0x%x\n", SPC_READ_LOSS_DW_COUNT(phyId)));
635 SA_DBG3(("saLocalPhyControl:PHY_RESET_COUNT 0x%x\n", SPC_READ_PHY_RESET_COUNT(phyId)));
636 SA_DBG3(("saLocalPhyControl:CODE_VIOLATION_COUNT 0x%x\n", SPC_READ_CODE_VIO_COUNT(phyId)));
637
638 /* Shift back to BAR4 original address */
639 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
640 {
641 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0));
642 ret = AGSA_RC_FAILURE;
643 }
644
645 /* restore back the Top Device LCLK generation register value */
646 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value1);
647
648 /* restore phyId */
649 phyId = copyPhyId;
650 /* call back with the status */
651
652 if (AGSA_RC_SUCCESS == ret)
653 {
654 if( agCB == agNULL )
655 {
656 ossaLocalPhyControlCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam);
657 }
658 else
659 {
660 agCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam);
661 }
662 }
663 else
664 {
665 if( agCB == agNULL )
666 {
667 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
668 }
669 else
670 {
671 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
672 }
673 }
674 break;
675 }
676 case AGSA_PHY_CLEAR_ERROR_COUNTS:
677 {
678 if(smIS_SPCV(agRoot))
679 {
680
681 SA_ASSERT((smIS_SPC(agRoot)), "SPC only");
682 SA_DBG1(("saLocalPhyControl: V AGSA_PHY_CLEAR_ERROR_COUNTS\n" ));
683 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "7d");
684 return AGSA_RC_FAILURE;
685 }
686 /* If phyId is invalid, return failure */
687 if ( phyId >= saRoot->phyCount )
688 {
689 si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t));
690 SA_DBG3(("saLocalPhyControl(CLEAR): phy%d - failure with phyId\n", phyId));
691 /* call back with the status */
692 if( agCB == agNULL )
693 {
694 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
695 }
696 else
697 {
698 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
699 }
700 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "7d");
701 return AGSA_RC_FAILURE;
702 }
703 /* save phyId */
704 copyPhyId = phyId;
705 /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register */
706 if (phyId < 4)
707 {
708 /* for phyId = 0, 1, 2, 3 */
709 value = 0x030000;
710 }
711 else
712 {
713 /* for phyId = 4, 5, 6, 7 */
714 phyId = phyId - 4;
715 value = 0x040000;
716 }
717 /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 1 */
718 value2 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK);
719
720 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value2));
721 /* If LCLK_CLEAR bit not set then set it */
722 if ((value2 & DEVICE_LCLK_CLEAR) == 0)
723 {
724 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value2 | DEVICE_LCLK_CLEAR) );
725 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value2 & 0xFFFFFFBF)));
726 }
727
728 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value))
729 {
730 SA_DBG1(("saLocalPhyControl(CLEAR):Shift Bar4 to 0x%x failed\n", value));
731 phyId = copyPhyId;
732 /* call back with the status */
733 if( agCB == agNULL )
734 {
735 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
736 }
737 else
738 {
739 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
740 }
741 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "7d");
742 return AGSA_RC_FAILURE;
743 }
744
745 /* read Counter Control register */
746 value1 = SPC_READ_COUNTER_CNTL(phyId);
747 SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value1));
748 /* set LCLK and LCLK_CLEAR */
749 SPC_WRITE_COUNTER_CNTL(phyId, (LCLK_CLEAR | LCLK));
750 /* read back the value of register */
751 /* poll LCLK bit = 0 */
752 while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK)
753 {
754 if(--count == 0)
755 {
756 SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value));
757 ret = AGSA_RC_FAILURE;
758 break;
759 }
760 } /* while */
761
762 value = SPC_READ_COUNTER_CNTL(phyId);
763 SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value));
764
765 /* restore the value */
766 SPC_WRITE_COUNTER_CNTL(phyId, value1);
767
768 /* Shift back to BAR4 original address */
769 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
770 {
771 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0));
772 ret = AGSA_RC_FAILURE;
773 }
774
775 /* restore back the Top Device LCLK generation register value */
776 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value2);
777
778 /* restore phyId */
779 phyId = copyPhyId;
780 /* call back with the status */
781 if (AGSA_RC_SUCCESS == ret)
782 {
783 if( agCB == agNULL )
784 {
785 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL);
786 }
787 else
788 {
789 agCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL);
790 }
791 }
792 else
793 {
794 if( agCB == agNULL )
795 {
796 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
797 }
798 else
799 {
800 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam);
801 }
802 }
803 break;
804 }
805 case AGSA_PHY_GET_BW_COUNTS:
806 {
807 SA_ASSERT((smIS_SPC(agRoot)), "SPCv only");
808 SA_DBG1(("saLocalPhyControl: AGSA_PHY_GET_BW_COUNTS\n" ));
809 break;
810 }
811
812 default:
813 ret = AGSA_RC_FAILURE;
814 SA_ASSERT(agFALSE, "(saLocalPhyControl) Unknown operation");
815 break;
816 }
817
818 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "7d");
819 return ret;
820 }
821
822
823 GLOBAL bit32 saGetPhyProfile(
824 agsaRoot_t *agRoot,
825 agsaContext_t *agContext,
826 bit32 queueNum,
827 bit32 ppc,
828 bit32 phyId
829 )
830 {
831 bit32 ret = AGSA_RC_SUCCESS;
832
833 agsaLLRoot_t *saRoot = agNULL;
834 agsaPhyErrCountersPage_t errorParam;
835
836 ossaLocalPhyControlCB_t agCB = ossaGetPhyProfileCB;
837
838 /* sanity check */
839 SA_ASSERT((agNULL != agRoot), "");
840 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
841 SA_ASSERT((agNULL != saRoot), "");
842
843 if(saRoot == agNULL)
844 {
845 SA_DBG3(("saGetPhyProfile : saRoot is NULL"));
846 return AGSA_RC_FAILURE;
847 }
848
849 SA_DBG1(("saGetPhyProfile: ppc 0x%x phyID %d\n", ppc,phyId));
850
851 switch(ppc)
852 {
853 case AGSA_SAS_PHY_ERR_COUNTERS_PAGE:
854 {
855 if(smIS_SPCV(agRoot))
856 {
857
858 SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_PAGE\n" ));
859
860 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
861 smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "7d");
862 return ret;
863 }
864 }
865 case AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE:
866 {
867 /* If phyId is invalid, return failure */
868 if ( phyId >= saRoot->phyCount )
869 {
870 si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t));
871 SA_DBG3(("saGetPhyProfile(CLEAR): phy%d - failure with phyId\n", phyId));
872 /* call back with the status */
873 ossaGetPhyProfileCB(agRoot, agContext, phyId, ppc, OSSA_FAILURE, (void *)&errorParam);
874 smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "7d");
875 return AGSA_RC_FAILURE;
876 }
877 if(smIS_SPCV(agRoot))
878 {
879 SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE\n" ));
880
881 ret = mpiGetPhyProfileCmd( agRoot,agContext, ppc,phyId,agCB);
882 smTraceFuncExit(hpDBG_VERY_LOUD, 'k', "7d");
883 return ret;
884 }
885
886 }
887 case AGSA_SAS_PHY_BW_COUNTERS_PAGE:
888 {
889 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_BW_COUNTERS_PAGE\n" ));
890 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
891 break;
892 }
893 case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE:
894 {
895 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" ));
896 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
897 break;
898 }
899
900 case AGSA_SAS_PHY_GENERAL_STATUS_PAGE:
901 {
902 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_GENERAL_STATUS_PAGE\n" ));
903 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
904 break;
905 }
906 case AGSA_PHY_SNW3_PAGE:
907 {
908 SA_DBG1(("saGetPhyProfile: AGSA_PHY_SNW3_PAGE\n" ));
909 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
910 break;
911 }
912 case AGSA_PHY_RATE_CONTROL_PAGE:
913 {
914 SA_DBG1(("saGetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" ));
915 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
916 break;
917 }
918 case AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE:
919 {
920 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE\n" ));
921 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB);
922 break;
923 }
924
925 default:
926 SA_DBG1(("saGetPhyProfile: Unknown operation 0x%X\n",ppc ));
927 SA_ASSERT(agFALSE, "saGetPhyProfile Unknown operation " );
928 break;
929
930 }
931 return ret;
932
933 }
934
935
936 GLOBAL bit32 saSetPhyProfile (
937 agsaRoot_t *agRoot,
938 agsaContext_t *agContext,
939 bit32 queueNum,
940 bit32 ppc,
941 bit32 length,
942 void *buffer,
943 bit32 phyID
944 )
945 {
946 bit32 ret = AGSA_RC_SUCCESS;
947
948 SA_DBG1(("saSetPhyProfile: ppc 0x%x length 0x%x phyID %d\n", ppc,length,phyID));
949
950 switch(ppc)
951 {
952 case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE:
953 {
954 SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" ));
955 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
956 break;
957 }
958 case AGSA_PHY_SNW3_PAGE:
959 {
960 SA_DBG1(("saSetPhyProfile: AGSA_PHY_SNW3_PAGE\n" ));
961 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
962 break;
963 }
964 case AGSA_PHY_RATE_CONTROL_PAGE:
965 {
966 SA_DBG1(("saSetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" ));
967 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
968 break;
969 }
970 case AGSA_SAS_PHY_MISC_PAGE:
971 {
972 SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_MISC_PAGE\n"));
973 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer);
974 break;
975 }
976
977 default:
978 SA_DBG1(("saSetPhyProfile: Unknown operation 0x%X\n",ppc ));
979 SA_ASSERT(agFALSE, "saSetPhyProfile Unknown operation " );
980 ret = AGSA_RC_FAILURE;
981 break;
982 }
983 return ret;
984 }
985
986
987 /******************************************************************************/
988 /*! \brief Initiate a HW Event Ack command
989 *
990 * This function is called to initiate a HW Event Ack command to the SPC.
991 * The completion of this function is reported in ossaHwEventAckCB().
992 *
993 * \param agRoot handles for this instance of SAS/SATA hardware
994 * \param agContext the context of this API
995 * \param queueNum queue number
996 * \param eventSource point to the event source structure
997 * \param param0
998 * \param param1
999 *
1000 * \return
1001 * - none
1002 */
1003 /*******************************************************************************/
1004 GLOBAL bit32 saHwEventAck(
1005 agsaRoot_t *agRoot,
1006 agsaContext_t *agContext,
1007 bit32 queueNum,
1008 agsaEventSource_t *eventSource,
1009 bit32 param0,
1010 bit32 param1
1011 )
1012 {
1013 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1014 agsaIORequestDesc_t *pRequest;
1015 agsaPortContext_t *agPortContext;
1016 agsaPort_t *pPort = agNULL;
1017 agsaSASHwEventAckCmd_t payload;
1018 bit32 phyportid;
1019 bit32 ret = AGSA_RC_SUCCESS;
1020 bit32 using_reserved = agFALSE;
1021
1022 smTraceFuncEnter(hpDBG_VERY_LOUD,"7e");
1023
1024 /* sanity check */
1025 SA_ASSERT((agNULL != saRoot), "");
1026 if(saRoot == agNULL)
1027 {
1028 SA_DBG1(("saHwEventAck: saRoot == agNULL\n"));
1029 return(AGSA_RC_FAILURE);
1030 }
1031
1032 SA_DBG2(("saHwEventAck: agContext %p eventSource %p\n", agContext, eventSource));
1033 SA_DBG1(("saHwEventAck: event 0x%x param0 0x%x param1 0x%x\n", eventSource->event, param0, param1));
1034
1035 agPortContext = eventSource->agPortContext;
1036
1037 /* Get request from free IORequests */
1038 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1039 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
1040
1041 /* If no LL Control request entry available */
1042 if ( agNULL == pRequest )
1043 {
1044 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1045 if(agNULL != pRequest)
1046 {
1047 using_reserved = agTRUE;
1048 SA_DBG1(("saHwEventAck, using saRoot->freeReservedRequests\n"));
1049 }
1050 else
1051 {
1052 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1053 /* If no LL Control request entry available */
1054 SA_DBG1(("saHwEventAck, No request from free list Not using saRoot->freeReservedRequests\n"));
1055 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7e");
1056 return AGSA_RC_BUSY;
1057 }
1058 }
1059 if( using_reserved )
1060 {
1061 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1062 }
1063 else
1064 {
1065 /* Remove the request from free list */
1066 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1067 }
1068 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1069 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1070
1071 SA_DBG2(("saHwEventAck: queueNum 0x%x HTag 0x%x\n",queueNum ,pRequest->HTag));
1072
1073 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1074 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1075 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1076 pRequest->valid = agTRUE;
1077
1078 /* build IOMB command and send to SPC */
1079 /* set payload to zeros */
1080 si_memset(&payload, 0, sizeof(agsaSASHwEventAckCmd_t));
1081
1082 /* find port id */
1083 if (agPortContext)
1084 {
1085 pPort = (agsaPort_t *) (agPortContext->sdkData);
1086 if (pPort)
1087 {
1088 if(eventSource->event == OSSA_HW_EVENT_PHY_DOWN)
1089 {
1090 pPort->tobedeleted = agTRUE;
1091 }
1092 SA_DBG3(("saHwEventAck,pPort->portId %X\n",pPort->portId));
1093
1094 if(smIS_SPC(agRoot))
1095 {
1096 /* fillup PORT_ID field */
1097 phyportid = pPort->portId & 0xF;
1098 }
1099 else
1100 {
1101 /* fillup PORT_ID field */
1102 phyportid = pPort->portId & 0xFF;
1103
1104 }
1105 }
1106 else
1107 {
1108 /* pPort is NULL - set PORT_ID to not intialized */
1109 if(smIS_SPC(agRoot))
1110 {
1111 phyportid = 0xF;
1112 }
1113 else
1114 {
1115 phyportid = 0xFF;
1116 }
1117 }
1118 }
1119 else
1120 {
1121 /* agPortContext is NULL - set PORT_ID to not intialized */
1122 if(smIS_SPC(agRoot))
1123 {
1124 phyportid = 0xF;
1125 }
1126 else
1127 {
1128 phyportid = 0xFF;
1129 }
1130 }
1131
1132 pRequest->pPort = pPort;
1133
1134 SA_DBG3(("saHwEventAck,eventSource->param 0x%X\n",eventSource->param));
1135 SA_DBG3(("saHwEventAck,eventSource->event 0x%X\n",eventSource->event));
1136
1137 if(smIS_SPC(agRoot))
1138 {
1139 /* fillup up PHY_ID */
1140 phyportid |= ((eventSource->param & 0x0000000F) << 4);
1141 /* fillup SEA field */
1142 phyportid |= (eventSource->event & 0x0000FFFF) << 8;
1143 SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xF,
1144 eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF));
1145 }
1146 else
1147 {
1148 /* fillup up PHY_ID */
1149 phyportid |= ((eventSource->param & 0x000000FF) << SHIFT24);
1150 /* fillup SEA field */
1151 phyportid |= (eventSource->event & 0x00FFFFFF) << SHIFT8;
1152 SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xFF,
1153 eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF));
1154 }
1155
1156 pRequest->HwAckType = (bit16)phyportid;
1157
1158 SA_DBG1(("saHwEventAck,phyportid 0x%X HwAckType 0x%X\n",phyportid,pRequest->HwAckType));
1159 /* set tag */
1160 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, tag), pRequest->HTag);
1161 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, sEaPhyIdPortId), phyportid);
1162 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param0), param0);
1163 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param1), param1);
1164
1165 /* build IOMB command and send to SPC */
1166
1167 if(smIS_SPC(agRoot))
1168 {
1169 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum);
1170 }
1171 else
1172 {
1173 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum);
1174 }
1175
1176 if (AGSA_RC_SUCCESS != ret)
1177 {
1178 /* remove the request from IOMap */
1179 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1180 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1181 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1182 pRequest->valid = agFALSE;
1183
1184 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1185 /* return the request to free pool */
1186 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1187 {
1188 SA_DBG1(("saHwEventAck: saving pRequest (%p) for later use\n", pRequest));
1189 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1190 }
1191 else
1192 {
1193 /* return the request to free pool */
1194 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1195 }
1196 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1197 SA_DBG1(("saHwEventAck, sending IOMB failed\n" ));
1198 }
1199 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7e");
1200
1201 return ret;
1202 }
1203
1204
1205 GLOBAL bit32 saVhistCapture(
1206 agsaRoot_t *agRoot,
1207 agsaContext_t *agContext,
1208 bit32 queueNum,
1209 bit32 Channel,
1210 bit32 NumBitLo,
1211 bit32 NumBitHi,
1212 bit32 PcieAddrLo,
1213 bit32 PcieAddrHi,
1214 bit32 ByteCount )
1215 {
1216
1217 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1218 agsaIORequestDesc_t *pRequest;
1219 bit32 ret = AGSA_RC_SUCCESS;
1220 bit32 using_reserved = agFALSE;
1221
1222 smTraceFuncEnter(hpDBG_VERY_LOUD,"3N");
1223
1224 /* sanity check */
1225 SA_ASSERT((agNULL != agRoot), "");
1226
1227 SA_DBG1(("saVhistCapture:Channel 0x%08X 0x%08X%08X 0x%08X%08X count 0x%X\n",Channel, NumBitHi, NumBitLo ,PcieAddrHi,PcieAddrLo,ByteCount));
1228
1229 {
1230 /* Get request from free IORequests */
1231 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1232 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */
1233 /* If no LL Control request entry available */
1234 if ( agNULL == pRequest )
1235 {
1236 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
1237 /* If no LL Control request entry available */
1238 if(agNULL != pRequest)
1239 {
1240 using_reserved = agTRUE;
1241 SA_DBG1((", using saRoot->freeReservedRequests\n"));
1242 }
1243 else
1244 {
1245 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1246 SA_DBG1(("saVhistCapture: No request from free list Not using saRoot->freeReservedRequests\n"));
1247 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3N");
1248 return AGSA_RC_BUSY;
1249 }
1250 }
1251 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1252 pRequest->valid = agTRUE;
1253 /* If LL Control request entry avaliable */
1254 if( using_reserved )
1255 {
1256 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1257 }
1258 else
1259 {
1260 /* Remove the request from free list */
1261 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1262 }
1263 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1264
1265 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1266 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1267 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1268 pRequest->valid = agTRUE;
1269
1270 /* Build the VhisCapture IOMB command and send to SPCv */
1271
1272 ret = mpiVHistCapCmd(agRoot,agContext, queueNum, Channel, NumBitLo, NumBitHi ,PcieAddrLo, PcieAddrHi, ByteCount);
1273 if (AGSA_RC_SUCCESS != ret)
1274 {
1275 /* remove the request from IOMap */
1276 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1277 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1278 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1279 pRequest->valid = agFALSE;
1280
1281 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1282 /* return the request to free pool */
1283 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1284 {
1285 SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest));
1286 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1287 }
1288 else
1289 {
1290 /* return the request to free pool */
1291 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1292 }
1293 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1294 SA_DBG1(("saVhistCapture: sending IOMB failed\n" ));
1295 }
1296 }
1297
1298 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3N");
1299
1300 return ret;
1301 }
1302
Cache object: e5c44520fb23e2f918847e1174e98ff8
|