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