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 sampicmd.c
24 * \brief The file implements the functions of MPI Inbound IOMB/Command to SPC
25 *
26 */
27 /******************************************************************************/
28 #include <sys/cdefs.h>
29 #include <dev/pms/config.h>
30
31 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
32 #ifdef SA_ENABLE_TRACE_FUNCTIONS
33 #ifdef siTraceFileID
34 #undef siTraceFileID
35 #endif
36 #define siTraceFileID 'I'
37 #endif
38
39 /******************************************************************************/
40 /*! \brief SAS/SATA LL API ECHO Command
41 *
42 * This command used to test that MPI between host and SPC IOP is operational.
43 *
44 * \param agRoot Handles for this instance of SAS/SATA hardware
45 * \param agContext Context of SPC FW Flash Update Command
46 * \param queueNum Inbound/outbound queue number
47 * \param echoPayload Pointer of Echo payload of IOMB
48 *
49 * \return If the MPI command is sent to SPC successfully
50 * - \e AGSA_RC_SUCCESS the MPI command is successfully
51 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
52 * - \e AGSA_RC_FAILURE the MPI command is failure
53 *
54 */
55 /*******************************************************************************/
saEchoCommand(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,void * echoPayload)56 GLOBAL bit32 saEchoCommand(
57 agsaRoot_t *agRoot,
58 agsaContext_t *agContext,
59 bit32 queueNum,
60 void *echoPayload
61 )
62 {
63 bit32 ret = AGSA_RC_SUCCESS;
64
65 smTraceFuncEnter(hpDBG_VERY_LOUD, "xa");
66
67 /* setup IOMB payload */
68 ret = mpiEchoCmd(agRoot, queueNum, agContext, echoPayload);
69
70 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xa");
71
72 return ret;
73 }
74
75 /******************************************************************************/
76 /*! \brief Build a IOMB command and send to SPC
77 *
78 * Build an IOMB if there is a free message buffer and Send it to SPC
79 *
80 * \param agRoot Handles for this instance of SAS/SATA hardware
81 * \param payload Pointer of payload in the IOMB
82 * \param category Category of IOMB
83 * \param opcode Opcode of IOMB
84 * \param size Size of IOMB
85 * \param queueNum Inbound/outbound queue number
86 *
87 * \return If the MPI command is sent to SPC successfully
88 * - \e AGSA_RC_SUCCESS the MPI command is successfully
89 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
90 * - \e AGSA_RC_FAILURE the MPI command is failure
91 */
92 /*******************************************************************************/
mpiBuildCmd(agsaRoot_t * agRoot,bit32 * payload,mpiMsgCategory_t category,bit16 opcode,bit16 size,bit32 queueNum)93 GLOBAL bit32 mpiBuildCmd(
94 agsaRoot_t *agRoot,
95 bit32 *payload,
96 mpiMsgCategory_t category,
97 bit16 opcode,
98 bit16 size,
99 bit32 queueNum
100 )
101 {
102 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
103 mpiICQueue_t *circularQ;
104 void *pMessage;
105 bit32 ret = AGSA_RC_SUCCESS;
106 bit32 retVal;
107 bit8 inq, outq;
108
109 smTraceFuncEnter(hpDBG_VERY_LOUD, "xb");
110
111 inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
112 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
113 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
114 SA_ASSERT((AGSA_MAX_OUTBOUND_Q > outq), "The OBQ Number is out of range.");
115
116 #ifdef SA_USE_MAX_Q
117 outq = saRoot->QueueConfig.numOutboundQueues -1;
118 SA_DBG1(("mpiBuildCmd, set OBQ to %d\n",outq));
119 #endif /* SA_USE_MAX_Q */
120 /* get a free inbound queue entry */
121
122 #ifdef SA_LL_IBQ_PROTECT
123 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
124 #endif /* SA_LL_IBQ_PROTECT */
125
126 circularQ = &saRoot->inboundQueue[inq];
127 retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
128
129 /* return FAILURE if error happened */
130 if (AGSA_RC_FAILURE == retVal)
131 {
132 #ifdef SA_LL_IBQ_PROTECT
133 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
134 #endif /* SA_LL_IBQ_PROTECT */
135 /* the message size exceeds the inbound queue message size */
136 SA_DBG1(("mpiBuildCmd, failure\n"));
137 ret = AGSA_RC_FAILURE;
138 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xb");
139 return ret;
140 }
141
142 /* return BUSY if no more inbound queue entry available */
143 if (AGSA_RC_BUSY == retVal)
144 {
145 SA_DBG1(("mpiBuildCmd, no more IOMB\n"));
146 ret = AGSA_RC_BUSY;
147 }
148 else
149 {
150 /* copy payload if it is necessary */
151 if (agNULL != payload)
152 {
153 si_memcpy(pMessage, payload, (size - sizeof(mpiMsgHeader_t)));
154 }
155
156 /* post the message to SPC */
157 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, category, opcode, outq, (bit8)circularQ->priority))
158 {
159 ret = AGSA_RC_FAILURE;
160 }
161 }
162
163 #ifdef SA_LL_IBQ_PROTECT
164 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
165 #endif /* SA_LL_IBQ_PROTECT */
166
167 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xb");
168 return ret;
169 }
170
171 /******************************************************************************/
172 /*! \brief SPC MPI ECHO Command
173 *
174 * This command used to test that MPI between host and SPC IOP is operational.
175 *
176 * \param agRoot Handles for this instance of SAS/SATA LLL
177 * \param queueNum Inbound/outbound queue number
178 * \param tag Tag of this IOMB
179 * \param echoPayload Pointer to the ECHO payload of inbound IOMB
180 *
181 * \return If the MPI command is sent to SPC successfully
182 * - \e AGSA_RC_SUCCESS the MPI command is successfully
183 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
184 * - \e AGSA_RC_FAILURE the MPI command is failure
185 *
186 */
187 /*******************************************************************************/
mpiEchoCmd(agsaRoot_t * agRoot,bit32 queueNum,agsaContext_t * agContext,void * echoPayload)188 GLOBAL bit32 mpiEchoCmd(
189 agsaRoot_t *agRoot,
190 bit32 queueNum,
191 agsaContext_t *agContext,
192 void *echoPayload
193 )
194 {
195 bit32 ret = AGSA_RC_SUCCESS;
196 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
197 agsaIORequestDesc_t *pRequest;
198 agsaEchoCmd_t payload;
199
200 smTraceFuncEnter(hpDBG_VERY_LOUD, "xc");
201
202 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
203 /* Get request from free IORequests */
204 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
205
206 /* If no LL Control request entry available */
207 if ( agNULL == pRequest )
208 {
209 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
210 SA_DBG1(("mpiEchoCmd, No request from free list\n" ));
211 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xc");
212 return AGSA_RC_BUSY;
213 }
214 /* If LL Control request entry avaliable */
215 else
216 {
217 /* Remove the request from free list */
218 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
219 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
220 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
221 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
222 saRoot->IOMap[pRequest->HTag].agContext = agContext;
223 pRequest->valid = agTRUE;
224
225 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
226
227
228 /* build IOMB command and send to SPC */
229 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaEchoCmd_t, tag), pRequest->HTag);
230 /* copy Echo payload */
231 si_memcpy(&payload.payload[0], echoPayload, (sizeof(agsaEchoCmd_t) - 4));
232 /* build IOMB command and send to SPC */
233 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_ECHO, IOMB_SIZE64, queueNum);
234 SA_DBG3(("mpiEchoCmd, return value = %d\n", ret));
235 if (AGSA_RC_SUCCESS != ret)
236 {
237 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
238 /* remove the request from IOMap */
239 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
240 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
241 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
242 pRequest->valid = agFALSE;
243 /* return the request to free pool */
244 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
245
246 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
247
248 SA_DBG1(("mpiEchoCmd, sending IOMB failed\n" ));
249 }
250 #ifdef SALL_API_TEST
251 else
252 {
253 saRoot->LLCounters.IOCounter.numEchoSent++;
254 }
255 #endif
256
257 }
258
259 /* return value */
260 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xc");
261 return ret;
262 }
263
264
265 /******************************************************************************/
266 /*! \brief Get Phy Profile Command SPCv
267 *
268 * This command is get # of phys and support speeds from SPCV.
269 *
270 * \param agRoot Handles for this instance of SAS/SATA LLL
271 * \param agDevHandle Handle of device
272 *
273 * \return If the MPI command is sent to SPC successfully
274 * - \e AGSA_RC_SUCCESS the MPI command is successfully
275 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
276 * - \e AGSA_RC_FAILURE the MPI command is failure
277 *
278 */
279 /*******************************************************************************/
280
281
mpiGetPhyProfileCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 Operation,bit32 PhyId,void * agCB)282 GLOBAL bit32 mpiGetPhyProfileCmd(
283 agsaRoot_t *agRoot,
284 agsaContext_t *agContext,
285 bit32 Operation,
286 bit32 PhyId,
287 void *agCB
288 )
289 {
290 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
291 agsaIORequestDesc_t *pRequest;
292 bit32 ret = AGSA_RC_SUCCESS;
293 agsaGetPhyProfileCmd_V_t payload;
294
295 smTraceFuncEnter(hpDBG_VERY_LOUD, "xd");
296
297 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
298 /* Get request from free IORequests */
299 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
300
301 SA_DBG1(("mpiGetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId ));
302
303 /* If no LL Control request entry avalibale */
304 if ( agNULL == pRequest )
305 {
306 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
307 SA_DBG1(("mpiGetPhyProfileCmd, No request from free list\n" ));
308 return AGSA_RC_BUSY;
309 }
310 /* If LL Control request entry avaliable */
311 else
312 {
313 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
314
315 /* Remove the request from free list */
316 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
317 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
318 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
319 saRoot->IOMap[pRequest->HTag].agContext = agContext;
320
321 pRequest->valid = agTRUE;
322 pRequest->completionCB = agCB;
323 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
324
325
326 /* set payload to zeros */
327 si_memset(&payload, 0, sizeof(agsaGetPhyProfileCmd_V_t));
328
329 /* set tag field */
330 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetPhyProfileCmd_V_t, tag), pRequest->HTag);
331 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetPhyProfileCmd_V_t, Reserved_Ppc_SOP_PHYID), (((Operation & 0xF) << SHIFT8 ) | (PhyId & 0xFF) ) );
332 /* build IOMB command and send to SPC */
333 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_PHY_PROFILE, IOMB_SIZE128, 0);
334 if (AGSA_RC_SUCCESS != ret)
335 {
336 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
337 pRequest->valid = agFALSE;
338 /* return the request to free pool */
339 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
340 /* remove the request from IOMap */
341 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
342 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
343 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
344 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
345
346 SA_DBG1(("mpiGetPhyProfileCmd, sending IOMB failed\n" ));
347 }
348 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret));
349 }
350
351 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xd");
352 /* return value */
353 return ret;
354 }
355
356
mpiVHistCapCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 Channel,bit32 NumBitLo,bit32 NumBitHi,bit32 PcieAddrLo,bit32 PcieAddrHi,bit32 ByteCount)357 GLOBAL bit32 mpiVHistCapCmd(
358 agsaRoot_t *agRoot,
359 agsaContext_t *agContext,
360 bit32 queueNum,
361 bit32 Channel,
362 bit32 NumBitLo,
363 bit32 NumBitHi,
364 bit32 PcieAddrLo,
365 bit32 PcieAddrHi,
366 bit32 ByteCount )
367 {
368 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
369 agsaIORequestDesc_t *pRequest= agNULL;
370 bit32 ret = AGSA_RC_SUCCESS;
371 agsaGetVHistCap_V_t payload;
372
373 smTraceFuncEnter(hpDBG_VERY_LOUD,"3C");
374 SA_DBG1(("mpiVHistCapCmd\n"));
375
376 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
377 /* Get request from free IORequests */
378 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
379 /* If no LL Control request entry avalibale */
380 if ( agNULL == pRequest )
381 {
382 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
383 SA_DBG1((", No request from free list\n" ));
384 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3C");
385 return AGSA_RC_BUSY;
386 }
387 /* If LL Control request entry avaliable */
388 else
389 {
390 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
391 /* Remove the request from free list */
392 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
393 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
394 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
395 saRoot->IOMap[pRequest->HTag].agContext = agContext;
396
397 pRequest->valid = agTRUE;
398 pRequest->completionCB = (void *)ossaGetPhyProfileCB;
399 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
400
401 /* set payload to zeros */
402 si_memset(&payload, 0, sizeof(agsaGetVHistCap_V_t));
403
404 /* set tag field */
405 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, tag), pRequest->HTag);
406 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, Channel), Channel );
407 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, NumBitLo), NumBitLo);
408 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, NumBitHi), NumBitHi);
409 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, PcieAddrLo),PcieAddrLo);
410 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, PcieAddrHi),PcieAddrHi);
411 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, ByteCount), ByteCount );
412
413
414 /* build IOMB command and send to SPC */
415 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_VHIST_CAP, IOMB_SIZE128,queueNum );
416 if (AGSA_RC_SUCCESS != ret)
417 {
418 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
419 pRequest->valid = agFALSE;
420 /* return the request to free pool */
421 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
422 /* remove the request from IOMap */
423 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
424 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
425 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
426 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
427
428 SA_DBG1(("mpiVHistCapCmd, sending IOMB failed\n" ));
429 }
430 SA_DBG3(("mpiVHistCapCmd, return value = %d\n", ret));
431 }
432
433 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3C");
434 /* return value */
435
436 return(ret);
437 }
438
mpiSetPhyProfileCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 Operation,bit32 PhyId,bit32 length,void * buffer)439 GLOBAL bit32 mpiSetPhyProfileCmd(
440 agsaRoot_t *agRoot,
441 agsaContext_t *agContext,
442 bit32 Operation,
443 bit32 PhyId,
444 bit32 length,
445 void * buffer
446 )
447 {
448 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
449 agsaIORequestDesc_t *pRequest;
450 bit32 ret = AGSA_RC_SUCCESS;
451 bit32 i;
452 agsaSetPhyProfileCmd_V_t payload;
453 bit32 * PageData =(bit32 * )buffer;
454
455 smTraceFuncEnter(hpDBG_VERY_LOUD,"2P");
456
457 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
458 /* Get request from free IORequests */
459 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
460
461 SA_DBG1(("mpiSetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId ));
462
463 /* If no LL Control request entry avalibale */
464 if ( agNULL == pRequest )
465 {
466 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
467 SA_DBG1(("mpiSetPhyProfileCmd, No request from free list\n" ));
468 return AGSA_RC_BUSY;
469 }
470 /* If LL Control request entry avaliable */
471 else
472 {
473 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
474 /* Remove the request from free list */
475 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
476 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
477 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
478 saRoot->IOMap[pRequest->HTag].agContext = agContext;
479
480 pRequest->valid = agTRUE;
481 pRequest->SOP = (bit16) Operation;
482 pRequest->completionCB = (void *)ossaGetPhyProfileCB;
483 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
484
485
486 /* set payload to zeros */
487 si_memset(&payload, 0, sizeof(agsaSetPhyProfileCmd_V_t));
488
489 /* set tag field */
490 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, tag), pRequest->HTag);
491 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, Reserved_Ppc_SOP_PHYID), (((Operation & 0xF) << SHIFT8 ) | (PhyId & 0xFF) ) );
492
493 for(i=0; i < (length / sizeof(bit32)); i++)
494 {
495 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, PageSpecificArea[i]),* (PageData+i) );
496 }
497
498 /* build IOMB command and send to SPC */
499 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_PHY_PROFILE, IOMB_SIZE128, 0);
500 if (AGSA_RC_SUCCESS != ret)
501 {
502 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
503 pRequest->valid = agFALSE;
504 /* return the request to free pool */
505 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
506 /* remove the request from IOMap */
507 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
508 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
509 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
510 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
511
512 SA_DBG1(("mpiSetPhyProfileCmd, sending IOMB failed\n" ));
513 }
514 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret));
515 }
516
517 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2P");
518 /* return value */
519 return ret;
520 }
521
522
523 /******************************************************************************/
524 /*! \brief Get Device Information Command
525 *
526 * This command is get # of phys and support speeds from SPC.
527 *
528 * \param agRoot Handles for this instance of SAS/SATA LLL
529 * \param agDevHandle Handle of device
530 * \param deviceid Device Id
531 * \param opton oprion
532 *
533 * \return If the MPI command is sent to SPC successfully
534 * - \e AGSA_RC_SUCCESS the MPI command is successfully
535 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
536 * - \e AGSA_RC_FAILURE the MPI command is failure
537 *
538 */
539 /*******************************************************************************/
mpiGetDeviceInfoCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 deviceid,bit32 option,bit32 queueNum)540 GLOBAL bit32 mpiGetDeviceInfoCmd(
541 agsaRoot_t *agRoot,
542 agsaContext_t *agContext,
543 bit32 deviceid,
544 bit32 option,
545 bit32 queueNum
546 )
547 {
548 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
549 agsaIORequestDesc_t *pRequest;
550 bit32 ret = AGSA_RC_SUCCESS;
551 agsaGetDevInfoCmd_t payload;
552
553 SA_ASSERT((agNULL !=saRoot ), "");
554 if(saRoot == agNULL)
555 {
556 SA_DBG1(("mpiGetDeviceInfoCmd: saRoot == agNULL\n"));
557 return(AGSA_RC_FAILURE);
558 }
559 smTraceFuncEnter(hpDBG_VERY_LOUD,"2K");
560
561 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
562 /* Get request from free IORequests */
563 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
564
565 /* If no LL Control request entry available */
566 if ( agNULL == pRequest )
567 {
568 SA_DBG1(("mpiGetDeviceInfoCmd, No request from free list\n" ));
569 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2K");
570 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
571 return AGSA_RC_BUSY;
572 }
573 /* If LL Control request entry avaliable */
574 else
575 {
576 /* Remove the request from free list */
577 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
578 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
579 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
580 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
581 saRoot->IOMap[pRequest->HTag].agContext = agContext;
582 pRequest->valid = agTRUE;
583 pRequest->DeviceInfoCmdOption = (bit8)option;
584 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
585
586
587 /* set payload to zeros */
588 si_memset(&payload, 0, sizeof(agsaGetDevInfoCmd_t));
589
590 /* set tag field */
591 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevInfoCmd_t, tag), pRequest->HTag);
592 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevInfoCmd_t, DeviceId), deviceid);
593 /* build IOMB command and send to SPC */
594 if( smIS_SPC(agRoot))
595 {
596 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_GET_DEV_INFO, IOMB_SIZE64, queueNum);
597 }
598 else
599 {
600 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEV_INFO, IOMB_SIZE64, queueNum);
601 }
602 if (AGSA_RC_SUCCESS != ret)
603 {
604 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
605 /* remove the request from IOMap */
606 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
607 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
608 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
609 pRequest->valid = agFALSE;
610 /* return the request to free pool */
611 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
612 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
613
614 SA_DBG1(("mpiGetDeviceInfoCmd, sending IOMB failed\n" ));
615 }
616 SA_DBG3(("mpiGetDeviceInfoCmd, return value = %d\n", ret));
617 }
618
619 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2K");
620 /* return value */
621 return ret;
622 }
623
624 /******************************************************************************/
625 /*! \brief Set Device Information Command
626 *
627 * This command is Set Device Information to SPC.
628 *
629 * \param agRoot Handles for this instance of SAS/SATA LLL
630 * \param agDevHandle Handle of device
631 * \param deviceid Device Id
632 * \param opton oprion
633 *
634 * \return If the MPI command is sent to SPC successfully
635 * - \e AGSA_RC_SUCCESS the MPI command is successfully
636 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
637 * - \e AGSA_RC_FAILURE the MPI command is failure
638 *
639 */
640 /*******************************************************************************/
mpiSetDeviceInfoCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 deviceid,bit32 option,bit32 queueNum,bit32 param,ossaSetDeviceInfoCB_t agCB)641 GLOBAL bit32 mpiSetDeviceInfoCmd(
642 agsaRoot_t *agRoot,
643 agsaContext_t *agContext,
644 bit32 deviceid,
645 bit32 option,
646 bit32 queueNum,
647 bit32 param,
648 ossaSetDeviceInfoCB_t agCB
649 )
650 {
651 agsaLLRoot_t *saRoot = agNULL;
652 agsaIORequestDesc_t *pRequest = agNULL;
653 bit32 ret = AGSA_RC_SUCCESS;
654 agsaSetDevInfoCmd_t payload;
655
656 smTraceFuncEnter(hpDBG_VERY_LOUD,"xe");
657
658 /* sanity check */
659 SA_ASSERT((agNULL != agRoot), "");
660 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
661 SA_ASSERT((agNULL != saRoot), "");
662
663 /* Get request from free IORequests */
664 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
665 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
666
667 SA_DBG2(("mpiSetDeviceInfoCmd, param 0x%08X option 0x%08X\n",param,option ));
668
669 /* If no LL Control request entry available */
670 if ( agNULL == pRequest )
671 {
672 SA_DBG1(("mpiSetDeviceInfoCmd, No request from free list\n" ));
673 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xe");
674 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
675 return AGSA_RC_BUSY;
676 }
677 /* If LL Control request entry avaliable */
678 else
679 {
680 /* Remove the request from free list */
681 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
682 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
683 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
684 saRoot->IOMap[pRequest->HTag].agContext = agContext;
685 pRequest->valid = agTRUE;
686 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
687 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
688
689 /* set payload to zeros */
690 si_memset(&payload, 0, sizeof(agsaSetDevInfoCmd_t));
691
692 /* set tag field */
693
694 if(smIS_SPC(agRoot))
695 {
696 option &= SET_DEV_INFO_SPC_DW3_MASK;
697 param &= SET_DEV_INFO_SPC_DW4_MASK;
698 }
699 else
700 {
701 option &= SET_DEV_INFO_V_DW3_MASK;
702 param &= SET_DEV_INFO_V_DW4_MASK;
703 }
704
705 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, tag), pRequest->HTag);
706 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, deviceId), deviceid);
707 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, SA_SR_SI), option);
708 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, DEVA_MCN_R_ITNT), param );
709
710 /* build IOMB command and send to SPC */
711 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_DEV_INFO, IOMB_SIZE64, queueNum);
712 if (AGSA_RC_SUCCESS != ret)
713 {
714 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
715 /* remove the request from IOMap */
716 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
717 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
718 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
719 pRequest->valid = agFALSE;
720
721 /* return the request to free pool */
722 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
723 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
724
725 SA_DBG1(("mpiSetDeviceInfoCmd, sending IOMB failed\n" ));
726 }
727 SA_DBG3(("mpiSetDeviceInfoCmd, return value = %d\n", ret));
728 }
729
730 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xe");
731 /* return value */
732
733 return ret;
734 }
735
736 /******************************************************************************/
737 /*! \brief SPC MPI Phy Start Command
738 *
739 * This command sends to SPC for the I/O.
740 *
741 * \param agRoot Handles for this instance of SAS/SATA LLL
742 * \param tag tage for IOMB
743 * \param phyId the phy id of the link will be started
744 * \param agPhyConfig the phy properity
745 * \param agSASIdentify the SAS identify frame will be sent by the phy
746 *
747 * \return If the MPI command is sent to SPC successfully
748 * - \e AGSA_RC_SUCCESS the MPI command is successfully
749 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
750 * - \e AGSA_RC_FAILURE the MPI command is failure
751 *
752 */
753 /*******************************************************************************/
mpiPhyStartCmd(agsaRoot_t * agRoot,bit32 tag,bit32 phyId,agsaPhyConfig_t * agPhyConfig,agsaSASIdentify_t * agSASIdentify,bit32 queueNum)754 GLOBAL bit32 mpiPhyStartCmd(
755 agsaRoot_t *agRoot,
756 bit32 tag,
757 bit32 phyId,
758 agsaPhyConfig_t *agPhyConfig,
759 agsaSASIdentify_t *agSASIdentify,
760 bit32 queueNum
761 )
762 {
763 bit32 ret = AGSA_RC_SUCCESS;
764 agsaPhyStartCmd_t payload;
765 bit32 *pValue;
766 bit32 *ptemp;
767 bit32 index;
768 bit32 dw2 = 0;
769
770 #if defined(SALLSDK_DEBUG)
771 bit32 Sscd;
772 #endif /* SALLSDK_DEBUG */
773 smTraceFuncEnter(hpDBG_VERY_LOUD,"xg");
774
775 /* set payload to zeros */
776 si_memset(&payload, 0, sizeof(agsaPhyStartCmd_t));
777
778 pValue = (bit32 *)agSASIdentify;
779 ptemp = (bit32 *)&payload.sasIdentify;
780 index = (agPhyConfig->phyProperties & 0x0ff00) >> SHIFT8;
781
782 #if defined(SALLSDK_DEBUG)
783 Sscd = (agPhyConfig->phyProperties & 0xf0000) >> SHIFT16;
784 #endif /* SALLSDK_DEBUG */
785
786 SA_DBG1(("mpiPhyStartCmd,phyId = %d dw 2 0x%08X\n",phyId ,((phyId & SM_PHYID_MASK) | ((agPhyConfig->phyProperties & 0xfff) << SHIFT8) | (agPhyConfig->phyProperties & 0xf0000) )));
787
788
789 SA_DBG2(("mpiPhyStartCmd,phyId 0x%x phyProperties 0x%x index 0x%x Sscd 0x%x\n",phyId, agPhyConfig->phyProperties,index,Sscd));
790
791 dw2 = ((phyId & SM_PHYID_MASK) | /* PHY id */
792 ((agPhyConfig->phyProperties & 0x000000FF) << SHIFT8)| /* SLR Mode */
793 (agPhyConfig->phyProperties & 0x000f0000) | /* SSCD */
794 (agPhyConfig->phyProperties & 0x00700000) | /* setting bit20, bit21 and bit22 for optical mode */
795 (agPhyConfig->phyProperties & 0x00800000) ); /* bit23 active cable mode BCT Disable 12g only*/
796
797 /* Haileah Phy analogsetting bit enable*/
798 if(smIS_SPC(agRoot))
799 {
800 if( smIS_spc8081(agRoot))
801 {
802 dw2 = dw2 | 0x08000;
803 }
804 }
805
806 SA_DBG1(("mpiPhyStartCmd,dw2 0x%08x\n",dw2));
807 SA_ASSERT(((agSASIdentify->sasAddressHi[0] || agSASIdentify->sasAddressHi[1] ||
808 agSASIdentify->sasAddressHi[2] || agSASIdentify->sasAddressHi[3] ||
809 agSASIdentify->sasAddressLo[0] || agSASIdentify->sasAddressLo[1] ||
810 agSASIdentify->sasAddressLo[2] || agSASIdentify->sasAddressLo[3])), "SAS Address Zero");
811
812 SA_DBG1(("mpiPhyStartCmd,SAS addr Hi 0x%02X%02X%02X%02X Lo 0x%02X%02X%02X%02X\n",
813 agSASIdentify->sasAddressHi[0],agSASIdentify->sasAddressHi[1],
814 agSASIdentify->sasAddressHi[2],agSASIdentify->sasAddressHi[3],
815 agSASIdentify->sasAddressLo[0],agSASIdentify->sasAddressLo[1],
816 agSASIdentify->sasAddressLo[2],agSASIdentify->sasAddressLo[3]));
817
818 /* setup phy ID field */
819 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, SscdAseSHLmMlrPhyId),dw2);
820
821 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, tag), tag);
822
823 /* setup analog setting index field */
824 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, analogSetupIdx), index);
825 /* copy SASIdentify to payload of IOMB */
826 si_memcpy(ptemp, pValue, sizeof(agsaSASIdentify_t));
827
828 /* build IOMB command and send to SPC */
829 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PHYSTART, IOMB_SIZE64, queueNum);
830
831 SA_DBG3(("mpiPhyStartCmd, return value = %d\n", ret));
832
833 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xg");
834 return ret;
835 }
836
837 /******************************************************************************/
838 /*! \brief SPC MPI Phy Stop Command
839 *
840 * This command sends to SPC for the I/O.
841 *
842 * \param agRoot Handles for this instance of SAS/SATA LLL
843 * \param tag tag of IOMB
844 * \param phyId To stop the phyId
845 *
846 * \return If the MPI command is sent to SPC successfully
847 * - \e AGSA_RC_SUCCESS the MPI command is successfully
848 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
849 * - \e AGSA_RC_FAILURE the MPI command is failure
850 *
851 */
852 /*******************************************************************************/
mpiPhyStopCmd(agsaRoot_t * agRoot,bit32 tag,bit32 phyId,bit32 queueNum)853 GLOBAL bit32 mpiPhyStopCmd(
854 agsaRoot_t *agRoot,
855 bit32 tag,
856 bit32 phyId,
857 bit32 queueNum
858 )
859 {
860 bit32 ret = AGSA_RC_SUCCESS;
861 agsaPhyStopCmd_t payload;
862
863 smTraceFuncEnter(hpDBG_VERY_LOUD,"xh");
864
865 /* set payload to zeros */
866 si_memset(&payload, 0, sizeof(agsaPhyStopCmd_t));
867
868 /* set tag */
869 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStopCmd_t, tag), tag);
870 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStopCmd_t, phyId), (phyId & SM_PHYID_MASK ));
871 /* build IOMB command and send to SPC */
872 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PHYSTOP, IOMB_SIZE64, queueNum);
873
874 SA_DBG3(("mpiPhyStopCmd, return value = %d\n", ret));
875
876 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xh");
877
878 return ret;
879 }
880
881 /******************************************************************************/
882 /*! \brief SPC MPI SMP Request Command
883 *
884 * This command sends to SPC for the SMP.
885 *
886 * \param agRoot Handles for this instance of SAS/SATA LLL
887 * \param pIomb pointer of IOMB
888 * \param opcode opcode of IOMB
889 * \param payload pointer of payload
890 * \param inq inbound queue number
891 * \param outq outbound queue number
892 *
893 * \return If the MPI command is sent to SPC successfully
894 * - \e AGSA_RC_SUCCESS the MPI command is successfully
895 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
896 * - \e AGSA_RC_FAILURE the MPI command is failure
897 *
898 */
899 /*******************************************************************************/
mpiSMPCmd(agsaRoot_t * agRoot,void * pIomb,bit16 opcode,agsaSMPCmd_t * payload,bit8 inq,bit8 outq)900 GLOBAL bit32 mpiSMPCmd(
901 agsaRoot_t *agRoot,
902 void *pIomb,
903 bit16 opcode,
904 agsaSMPCmd_t *payload,
905 bit8 inq,
906 bit8 outq
907 )
908 {
909 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
910 mpiICQueue_t *circularQ;
911 bit32 ret = AGSA_RC_SUCCESS;
912 #if defined(SALLSDK_DEBUG)
913 mpiMsgHeader_t *msgHeader;
914 bit32 bc;
915 #endif /* SALLSDK_DEBUG */
916 smTraceFuncEnter(hpDBG_VERY_LOUD,"xi");
917
918 SA_DBG6(("mpiSMPCmd: start\n"));
919
920 #if defined(SALLSDK_DEBUG)
921 msgHeader = (mpiMsgHeader_t*)(((bit8*)pIomb) - sizeof(mpiMsgHeader_t));
922 bc = (((msgHeader->Header) >> SHIFT24) & BC_MASK);
923 #endif /* SALLSDK_DEBUG */
924 SA_DBG6(("mpiSMPCmd: before msgHeader bc %d\n", bc));
925
926 /* copy payload if it is necessary */
927 if (agNULL != payload)
928 {
929 si_memcpy(pIomb, payload, sizeof(agsaSMPCmd_t));
930 }
931
932 SA_DBG6(("mpiSMPCmd: after msgHeader bc %d\n", bc));
933
934 /* post the IOMB to SPC */
935 circularQ = &saRoot->inboundQueue[inq];
936 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pIomb, MPI_CATEGORY_SAS_SATA, opcode, outq, (bit8)circularQ->priority))
937 ret = AGSA_RC_FAILURE;
938
939 SA_DBG3(("mpiSMPCmd, return value = %d\n", ret));
940
941 /* return value */
942 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xi");
943 return ret;
944 }
945
946 /******************************************************************************/
947 /*! \brief SPC MPI Deregister Device Handle Command
948 *
949 * This command used to deregister(remove) the device handle.
950 *
951 * \param agRoot Handles for this instance of SAS/SATA LLL
952 * \param agDevHandle Device Handle
953 * \param deviceId index of device
954 * \param portId index of port
955 * \param queueNum IQ/OQ number
956 *
957 * \return If the MPI command is sent to SPC successfully
958 * - \e AGSA_RC_SUCCESS the MPI command is successfully
959 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
960 * - \e AGSA_RC_FAILURE the MPI command is failure
961 *
962 */
963 /*******************************************************************************/
mpiDeregDevHandleCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaDeviceDesc_t * pDevice,bit32 deviceId,bit32 portId,bit32 queueNum)964 GLOBAL bit32 mpiDeregDevHandleCmd(
965 agsaRoot_t *agRoot,
966 agsaContext_t *agContext,
967 agsaDeviceDesc_t *pDevice,
968 bit32 deviceId,
969 bit32 portId,
970 bit32 queueNum
971 )
972 {
973 bit32 ret = AGSA_RC_SUCCESS;
974 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
975 agsaIORequestDesc_t *pRequest;
976 agsaDeregDevHandleCmd_t payload;
977
978 smTraceFuncEnter(hpDBG_VERY_LOUD,"xp");
979
980 /* Get request from free IORequests */
981 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
982 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
983
984 /* If no LL Control request entry available */
985 if ( agNULL == pRequest )
986 {
987 SA_DBG1(("mpiDeregDevHandleCmd, No request from free list\n" ));
988 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xp");
989 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
990 return AGSA_RC_BUSY;
991 }
992 /* If LL Control request entry avaliable */
993 else
994 {
995 pRequest->pDevice = pDevice;
996 /* Remove the request from free list */
997 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
998 pRequest->valid = agTRUE;
999 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1000 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1001 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1002 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1003 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1004
1005 /* clean the payload to zeros */
1006 si_memset(&payload, 0, sizeof(agsaDeregDevHandleCmd_t));
1007
1008 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDeregDevHandleCmd_t, tag), pRequest->HTag);
1009 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDeregDevHandleCmd_t, deviceId), deviceId);
1010
1011 /* build IOMB command and send it to SPC */
1012 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DEREG_DEV_HANDLE, IOMB_SIZE64, queueNum);
1013 if (AGSA_RC_SUCCESS != ret)
1014 {
1015 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1016 /* remove the request from IOMap */
1017 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1018 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1019 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1020 pRequest->valid = agFALSE;
1021
1022 /* return the request to free pool */
1023 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1024
1025 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1026 SA_DBG1(("mpiSetVPDCmd, sending IOMB failed\n" ));
1027 }
1028 SA_DBG3(("mpiDeregDevHandleCmd, return value = %d\n", ret));
1029 }
1030
1031 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xp");
1032
1033 /* return value */
1034 return ret;
1035 }
1036
1037 /******************************************************************************/
1038 /*! \brief SPC MPI Get Device Handle Command
1039 *
1040 * This command used to get device handle.
1041 *
1042 * \param agRoot Handles for this instance of SAS/SATA LLL
1043 * \param agContext Context of Device Handle Command
1044 * \param portId index of port
1045 * \param flags flags
1046 * \param maxDevs Maximum Device Handles
1047 * \param queueNum IQ/OQ number
1048 * \param skipCount skip device entry count
1049 *
1050 * \return If the MPI command is sent to SPC successfully
1051 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1052 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1053 * - \e AGSA_RC_FAILURE the MPI command is failure
1054 *
1055 */
1056 /*******************************************************************************/
mpiGetDeviceHandleCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 portId,bit32 flags,bit32 maxDevs,bit32 queueNum,bit32 skipCount)1057 GLOBAL bit32 mpiGetDeviceHandleCmd(
1058 agsaRoot_t *agRoot,
1059 agsaContext_t *agContext,
1060 bit32 portId,
1061 bit32 flags,
1062 bit32 maxDevs,
1063 bit32 queueNum,
1064 bit32 skipCount
1065 )
1066 {
1067 bit32 ret = AGSA_RC_SUCCESS;
1068 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1069 agsaIORequestDesc_t *pRequest;
1070 agsaGetDevHandleCmd_t payload;
1071 bit32 using_reserved = agFALSE;
1072
1073 smTraceFuncEnter(hpDBG_VERY_LOUD,"xj");
1074
1075 /* Get request from free CntrlRequests */
1076 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1077 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1078
1079 /* If no LL Control request entry available */
1080 if ( agNULL == pRequest )
1081 {
1082 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1083 if(agNULL != pRequest)
1084 {
1085 using_reserved = agTRUE;
1086 SA_DBG1(("mpiGetDeviceHandleCmd, using saRoot->freeReservedRequests\n"));
1087 }
1088 else
1089 {
1090 SA_DBG1(("mpiGetDeviceHandleCmd, No request from free list Not using saRoot->freeReservedRequests\n"));
1091 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xj");
1092 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1093 return AGSA_RC_BUSY;
1094 }
1095 }
1096
1097 /* Remove the request from free list */
1098 if( using_reserved )
1099 {
1100 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1101 }
1102 else
1103 {
1104 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1105 }
1106 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1107 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1108 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1109 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1110 pRequest->valid = agTRUE;
1111 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1112
1113
1114 /* clean the payload to zeros */
1115 si_memset(&payload, 0, sizeof(agsaGetDevHandleCmd_t));
1116 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, tag), pRequest->HTag);
1117 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, DevADevTMaxDIDportId),
1118 ((portId & PORTID_MASK) | (maxDevs << SHIFT8) | (flags << SHIFT24)));
1119 /* set starting Number */
1120 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, skipCount), skipCount);
1121
1122 /* build IOMB command and send it to SPC */
1123 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEV_HANDLE, IOMB_SIZE64, queueNum);
1124 if (AGSA_RC_SUCCESS != ret)
1125 {
1126 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1127 /* remove the request from IOMap */
1128 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1129 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1130 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1131 pRequest->valid = agFALSE;
1132 /* return the request to free pool */
1133 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1134 {
1135 SA_DBG1(("mpiGetDeviceHandleCmd: saving pRequest (%p) for later use\n", pRequest));
1136 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1137 }
1138 else
1139 {
1140 /* return the request to free pool */
1141 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1142 }
1143 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1144
1145 SA_DBG1(("mpiGetDeviceHandleCmd, sending IOMB failed\n" ));
1146 }
1147 SA_DBG3(("mpiGetDeviceHandleCmd, return value = %d\n", ret));
1148
1149 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xj");
1150
1151 return ret;
1152 }
1153
1154 /******************************************************************************/
1155 /*! \brief SPC MPI LOCAL PHY CONTROL Command
1156 *
1157 * This command used to do the SPC Phy operation.
1158 *
1159 * \param agRoot Handles for this instance of SAS/SATA LLL
1160 * \param tag tag of IOMB
1161 * \param phyId PHY Id
1162 * \param operation operation of PHY control
1163 * \param queueNum IQ/OQ number
1164 *
1165 * \return If the MPI command is sent to SPC successfully
1166 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1167 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1168 * - \e AGSA_RC_FAILURE the MPI command is failure
1169 *
1170 */
1171 /*******************************************************************************/
mpiLocalPhyControlCmd(agsaRoot_t * agRoot,bit32 tag,bit32 phyId,bit32 operation,bit32 queueNum)1172 GLOBAL bit32 mpiLocalPhyControlCmd(
1173 agsaRoot_t *agRoot,
1174 bit32 tag,
1175 bit32 phyId,
1176 bit32 operation,
1177 bit32 queueNum
1178 )
1179 {
1180 bit32 ret = AGSA_RC_SUCCESS;
1181 agsaLocalPhyCntrlCmd_t payload;
1182 smTraceFuncEnter(hpDBG_VERY_LOUD,"xl");
1183
1184 SA_DBG3(("mpiLocalPhyControlCmd, phyId 0x%X operation 0x%x dw2 0x%x\n",phyId, operation,(((operation & BYTE_MASK) << SHIFT8) | (phyId & SM_PHYID_MASK))));
1185
1186 /* clean the payload field */
1187 si_memset(&payload, 0, sizeof(agsaLocalPhyCntrlCmd_t));
1188
1189 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaLocalPhyCntrlCmd_t, phyOpPhyId),
1190 (((operation & BYTE_MASK) << SHIFT8) | (phyId & SM_PHYID_MASK)));
1191 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaLocalPhyCntrlCmd_t, tag), tag);
1192 /* build IOMB command and send to SPC */
1193 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_LOCAL_PHY_CONTROL, IOMB_SIZE64, queueNum);
1194
1195 SA_DBG3(("mpiLocalPhyControlCmd, return value = %d\n", ret));
1196
1197 /* return value */
1198 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xl");
1199 return ret;
1200 }
1201
1202 /******************************************************************************/
1203 /*! \brief Device Handle Accept Command
1204 *
1205 * This command is Device Handle Accept IOMB to SPC.
1206 *
1207 * \param agRoot Handles for this instance of SAS/SATA LLL
1208 * \param agContext Context for the set VPD command
1209 * \param ctag controller tag
1210 * \param deviceId device Id
1211 * \param action action
1212 * \param queueNum queue Number
1213 *
1214 * \return If the MPI command is sent to SPC successfully
1215 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1216 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1217 * - \e AGSA_RC_FAILURE the MPI command is failure
1218 *
1219 */
1220 /*******************************************************************************/
mpiDevHandleAcceptCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 ctag,bit32 deviceId,bit32 action,bit32 flag,bit32 itlnx,bit32 queueNum)1221 GLOBAL bit32 mpiDevHandleAcceptCmd(
1222 agsaRoot_t *agRoot,
1223 agsaContext_t *agContext,
1224 bit32 ctag,
1225 bit32 deviceId,
1226 bit32 action,
1227 bit32 flag,
1228 bit32 itlnx,
1229 bit32 queueNum
1230 )
1231 {
1232 bit32 ret = AGSA_RC_SUCCESS;
1233 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1234 agsaIORequestDesc_t *pRequest;
1235 agsaDevHandleAcceptCmd_t payload;
1236 bit32 DW4 =0;
1237 bit32 mcn =0;
1238 bit32 awt =0;
1239 bit32 ha =0;
1240
1241 smTraceFuncEnter(hpDBG_VERY_LOUD,"xt");
1242
1243 if(deviceId & 0xFFFF0000)
1244 {
1245 ha = 1;
1246 }
1247 /* Get request from free IORequests */
1248 ossaSingleThreadedEnter(agRoot,LL_IOREQ_LOCKEQ_LOCK );
1249 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1250
1251 SA_DBG2(("mpiDevHandleAcceptCmd, deviceId 0x%x action 0x%x flag 0x%x itlnx 0x%x\n",deviceId,action,flag,itlnx ));
1252
1253 /* If no LL Control request entry available */
1254 if ( agNULL == pRequest )
1255 {
1256 ossaSingleThreadedLeave(agRoot,LL_IOREQ_LOCKEQ_LOCK );
1257 SA_DBG1(("mpiDevHandleAcceptCmd, No request from free list\n" ));
1258 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xt");
1259 return AGSA_RC_BUSY;
1260 }
1261 /* If LL Control request entry avaliable */
1262 else
1263 {
1264 /* Remove the request from free list */
1265 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1266 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1267 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1268 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1269 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1270 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1271
1272 /* Do not mark as valid at this IOMB does not complete in OBQ */
1273
1274 /* set payload to zeros */
1275 si_memset(&payload, 0, sizeof(agsaDevHandleAcceptCmd_t));
1276
1277 /* set tag field */
1278 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, tag), pRequest->HTag);
1279 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, deviceId), deviceId);
1280 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, Ctag), ctag);
1281 mcn = (flag & 0xF0000) >>SHIFT16;
1282 awt = (flag & 2)>>SHIFT1;
1283 DW4 = (action << SHIFT24) | \
1284 mcn << SHIFT20 | \
1285 awt << SHIFT17 | \
1286 ha << SHIFT16 | \
1287 itlnx;
1288 SA_DBG2(("mpiDevHandleAcceptCmd,DW4 0x%x\n",DW4 ));
1289 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, DevA_MCN_R_R_HA_ITNT),DW4);
1290 }
1291
1292 /* build IOMB command and send to SPC */
1293 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DEV_HANDLE_ACCEPT, IOMB_SIZE64, queueNum);
1294 if (AGSA_RC_SUCCESS != ret)
1295 {
1296 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB failed\n" ));
1297 }
1298 else
1299 {
1300 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB succeeded\n" ));
1301 }
1302
1303 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1304 /* remove the request from IOMap */
1305 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1306 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1307 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1308 pRequest->valid = agFALSE;
1309 /* return the request to free pool */
1310 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1311 {
1312 SA_DBG1(("mpiDevHandleAcceptCmd: saving pRequest (%p) for later use\n", pRequest));
1313 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1314 }
1315 else
1316 {
1317 /* return the request to free pool */
1318 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1319 }
1320
1321 /* return value */
1322 ossaSingleThreadedLeave(agRoot,LL_IOREQ_LOCKEQ_LOCK );
1323 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xt");
1324 return ret;
1325 }
1326
1327 /******************************************************************************/
1328 /*! \brief SPC READ REGISTER DUMP Command
1329 *
1330 * This command used to do the SPC Read Register Dump command.
1331 *
1332 * \param agRoot Handles for this instance of SAS/SATA LLL
1333 * \param tag tag of IOMB
1334 * \param cpuId CPU Id
1335 * \param queueNum IQ/OQ number
1336 * \param cpuId AAP1 or IOP
1337 * \param cOffset offset of the register dump data
1338 * \param addrHi Hi address if Register Dump data
1339 * \param addrHi Low address if Register Dump data
1340 * \param len the length of for read
1341 *
1342 * \return If the MPI command is sent to SPC successfully
1343 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1344 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1345 * - \e AGSA_RC_FAILURE the MPI command is failure
1346 *
1347 */
1348 /*******************************************************************************/
mpiNVMReadRegDumpCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 cpuId,bit32 cOffset,bit32 addrHi,bit32 addrLo,bit32 len)1349 GLOBAL bit32 mpiNVMReadRegDumpCmd(
1350 agsaRoot_t *agRoot,
1351 agsaContext_t *agContext,
1352 bit32 queueNum,
1353 bit32 cpuId,
1354 bit32 cOffset,
1355 bit32 addrHi,
1356 bit32 addrLo,
1357 bit32 len
1358 )
1359 {
1360 bit32 ret = AGSA_RC_SUCCESS;
1361 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1362 agsaIORequestDesc_t *pRequest;
1363 agsaGetNVMDataCmd_t payload;
1364 bit32 nvmd = 0;
1365
1366 smTraceFuncEnter(hpDBG_VERY_LOUD,"xk");
1367
1368 /* Get request from free IORequests */
1369 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1370 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1371
1372 /* If no LL Control request entry available */
1373 if ( agNULL == pRequest )
1374 {
1375 SA_DBG1(("mpiNVMReadRegDumpCmd, No request from free list\n" ));
1376 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xk");
1377 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1378 return AGSA_RC_BUSY;
1379 }
1380 /* If LL Control request entry avaliable */
1381 else
1382 {
1383 /* Remove the request from free list */
1384 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1385 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1386 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1387 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1388 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1389 pRequest->valid = agTRUE;
1390 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1391
1392 /* clean the payload field */
1393 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t));
1394
1395 /* only indirect mode */
1396 if (cpuId <= 1)
1397 {
1398 if (cpuId == 0)
1399 nvmd = AAP1_RDUMP | IRMode;
1400 else
1401 nvmd = IOP_RDUMP | IRMode;
1402
1403 /* setup IOMB */
1404 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, tag), pRequest->HTag);
1405 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), nvmd);
1406 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), cOffset);
1407 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrLo), addrLo);
1408 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrHi), addrHi);
1409 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respLen), len);
1410
1411 /* build IOMB command and send to SPC */
1412 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum);
1413 }
1414 else
1415 {
1416 SA_DBG1(("mpiNVMReadRegDumpCmd, Wrong device type\n" ));
1417 ret = AGSA_RC_FAILURE;
1418 }
1419
1420 if (AGSA_RC_SUCCESS != ret)
1421 {
1422 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1423 /* remove the request from IOMap */
1424 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1425 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1426 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1427 pRequest->valid = agFALSE;
1428 /* return the request to free pool */
1429 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1430
1431 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1432 SA_DBG1(("mpiNVMReadRegDumpCmd, sending IOMB failed\n" ));
1433 }
1434 }
1435
1436 SA_DBG3(("mpiNVMReadRegDumpCmd, return value = %d\n", ret));
1437
1438 /* return value */
1439 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xk");
1440
1441 return ret;
1442 }
1443
1444 /******************************************************************************/
1445 /*! \brief Get NVM Data command
1446 *
1447 * This command is get NVM Data from SPC.
1448 *
1449 * \param agRoot Handles for this instance of SAS/SATA LLL
1450 * \param agContext Context for the VPD command
1451 * \param VPDInfo Pointer of VPD Information
1452 * \param queueNum Queue Number of inbound/outbound queue
1453 *
1454 * \return If the MPI command is sent to SPC successfully
1455 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1456 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1457 * - \e AGSA_RC_FAILURE the MPI command is failure
1458 *
1459 */
1460 /*******************************************************************************/
mpiGetNVMDCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaNVMDData_t * NVMDInfo,bit32 queueNum)1461 GLOBAL bit32 mpiGetNVMDCmd(
1462 agsaRoot_t *agRoot,
1463 agsaContext_t *agContext,
1464 agsaNVMDData_t *NVMDInfo,
1465 bit32 queueNum
1466 )
1467 {
1468 bit32 ret = AGSA_RC_FAILURE;
1469 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1470 agsaIORequestDesc_t *pRequest;
1471 agsaGetNVMDataCmd_t payload;
1472
1473 smTraceFuncEnter(hpDBG_VERY_LOUD,"xr");
1474
1475 /* Get request from free IORequests */
1476 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1477 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1478
1479 /* If no LL Control request entry available */
1480 if ( agNULL == pRequest )
1481 {
1482 SA_DBG1(("mpiGetNVMDCmd, No request from free list\n" ));
1483 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xr");
1484 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1485 return AGSA_RC_BUSY;
1486 }
1487 /* If LL Control request entry avaliable */
1488 else
1489 {
1490 SA_DBG3(("mpiGetNVMDCmd, Build IOMB NVMDDevice= 0x%x\n", NVMDInfo->NVMDevice));
1491 /* Remove the request from free list */
1492 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1493 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1494 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1495 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1496 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1497 pRequest->valid = agTRUE;
1498 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1499
1500 /* set payload to zeros */
1501 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t));
1502 /* set tag field */
1503 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, tag), pRequest->HTag);
1504
1505 if (NVMDInfo->indirectPayload)
1506 {
1507 /* indirect payload IP = 1 */
1508 switch (NVMDInfo->NVMDevice)
1509 {
1510 case AGSA_NVMD_TWI_DEVICES:
1511 /* NVMD = 0 */
1512 /* indirect payload IP = 1 and 0x0 (TWI) */
1513 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1514 (NVMDInfo->TWIDeviceAddress << 16) | (NVMDInfo->TWIBusNumber << 12) |
1515 (NVMDInfo->TWIDevicePageSize << 8) | (NVMDInfo->TWIDeviceAddressSize << 4) |
1516 (NVMDInfo->indirectPayload << 31) | NVMDInfo->NVMDevice);
1517 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1518 NVMDInfo->dataOffsetAddress);
1519 break;
1520 case AGSA_NVMD_CONFIG_SEEPROM:
1521 /* NVMD = 1 */
1522 /* Data Offset should be 0 */
1523 if (NVMDInfo->dataOffsetAddress != 0)
1524 {
1525 /* Error for Offset */
1526 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong offset = 0x%x\n", NVMDInfo->dataOffsetAddress));
1527 }
1528 /* indirect payload IP = 1, NVMD = 0x1 (SEEPROM0) */
1529 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1530 (NVMDInfo->indirectPayload << SHIFT31) | (NVMDInfo->NVMDevice));
1531 break;
1532 case AGSA_NVMD_VPD_FLASH:
1533 /* indirect payload IP = 1 and 0x4 (FLASH) */
1534 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1535 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1536 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1537 NVMDInfo->dataOffsetAddress);
1538 break;
1539 case AGSA_NVMD_EXPANSION_ROM:
1540 /* indirect payload IP = 1 and 0x7 (EXPANSION ROM PARTITION) */
1541 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1542 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1543 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1544 NVMDInfo->dataOffsetAddress);
1545 break;
1546 case AGSA_NVMD_AAP1_REG_FLASH: /* AGSA_NVMD_REG_FLASH SPCv uses 5 as well */
1547 /* indirect payload IP = 1 and 0x5 (AGSA_NVMD_AAP1_REG_FLASH ) */
1548 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1549 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1550 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1551 NVMDInfo->dataOffsetAddress);
1552 break;
1553 case AGSA_NVMD_IOP_REG_FLASH:
1554 /* indirect payload IP = 1 and 0x6 ( AGSA_NVMD_IOP_REG_FLASH ) */
1555 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1556 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1557 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1558 NVMDInfo->dataOffsetAddress);
1559 break;
1560
1561 default:
1562 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong device type = 0x%x\n", NVMDInfo->NVMDevice));
1563 break;
1564 }
1565
1566 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrLo), NVMDInfo->indirectAddrLower32);
1567 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrHi), NVMDInfo->indirectAddrUpper32);
1568 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respLen), NVMDInfo->indirectLen);
1569 /* build IOMB command and send to SPC */
1570 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum);
1571 }
1572 else
1573 {
1574 /* direct payload IP = 0 only for TWI device */
1575 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice)
1576 {
1577 /* NVMD = 0 */
1578 /* indirect payload IP = 0 and 0x0 (TWI) */
1579 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD),
1580 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) |
1581 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) |
1582 NVMDInfo->NVMDevice);
1583 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset),
1584 NVMDInfo->dataOffsetAddress | (NVMDInfo->directLen << SHIFT24));
1585 /* build IOMB command and send to SPC */
1586 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum);
1587 }
1588 else
1589 {
1590 SA_DBG1(("mpiGetNVMDCmd, (IP=0)wrong device type = 0x%x\n", NVMDInfo->NVMDevice));
1591 ret = AGSA_RC_FAILURE;
1592 /* CB for NVMD with error */
1593 ossaGetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR, 0, NVMDInfo->directLen, agNULL);
1594 }
1595 }
1596
1597 if (AGSA_RC_SUCCESS != ret)
1598 {
1599 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1600 /* remove the request from IOMap */
1601 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1602 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1603 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1604 pRequest->valid = agFALSE;
1605
1606 /* return the request to free pool */
1607 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1608
1609 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1610 SA_DBG1(("mpiGetNVMDCmd, sending IOMB failed\n" ));
1611 }
1612 SA_DBG3(("mpiGetNVMDCmd, return value = %d\n", ret));
1613 }
1614
1615 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xr");
1616
1617 /* return value */
1618 return ret;
1619 }
1620
1621 /******************************************************************************/
1622 /*! \brief Set NVM Data Command
1623 *
1624 * This command is set NVM Data to SPC.
1625 *
1626 * \param agRoot Handles for this instance of SAS/SATA LLL
1627 * \param agContext Context for the set VPD command
1628 * \param NVMDInfo pointer of VPD information
1629 * \param queueNum queue Number
1630 *
1631 * \return If the MPI command is sent to SPC successfully
1632 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1633 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1634 * - \e AGSA_RC_FAILURE the MPI command is failure
1635 *
1636 */
1637 /*******************************************************************************/
mpiSetNVMDCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaNVMDData_t * NVMDInfo,bit32 queueNum)1638 GLOBAL bit32 mpiSetNVMDCmd(
1639 agsaRoot_t *agRoot,
1640 agsaContext_t *agContext,
1641 agsaNVMDData_t *NVMDInfo,
1642 bit32 queueNum
1643 )
1644 {
1645 bit32 ret = AGSA_RC_FAILURE;
1646 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1647 agsaIORequestDesc_t *pRequest;
1648 agsaSetNVMDataCmd_t payload;
1649
1650 smTraceFuncEnter(hpDBG_VERY_LOUD,"xm");
1651
1652
1653 /* Get request from free IORequests */
1654 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1655 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1656
1657 /* If no LL Control request entry available */
1658 if ( agNULL == pRequest )
1659 {
1660 SA_DBG1(("mpiSetNVMDCmd, No request from free list\n" ));
1661 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xm");
1662 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1663 return AGSA_RC_BUSY;
1664 }
1665 /* If LL Control request entry avaliable */
1666 else
1667 {
1668 SA_DBG3(("mpiSetNVMDCmd, Build IOMB NVMDDevice= 0x%x\n", NVMDInfo->NVMDevice));
1669 /* Remove the request from free list */
1670 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1671 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1672 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1673 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1674 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1675 pRequest->valid = agTRUE;
1676 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1677
1678 /* set payload to zeros */
1679 si_memset(&payload, 0, sizeof(agsaSetNVMDataCmd_t));
1680
1681 /* set tag field */
1682 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, tag), pRequest->HTag);
1683
1684 if (NVMDInfo->indirectPayload)
1685 {
1686 /* indirect payload IP = 1 */
1687 switch (NVMDInfo->NVMDevice)
1688 {
1689 case AGSA_NVMD_TWI_DEVICES:
1690 /* NVMD = 0 */
1691 /* indirect payload IP = 1 and 0x0 (TWI) */
1692 /* set up signature */
1693 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.signature), NVMDInfo->signature);
1694 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD),
1695 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) |
1696 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) |
1697 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1698 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset),
1699 NVMDInfo->dataOffsetAddress);
1700 break;
1701 /* 0x01:SEEPROM-0 and 0x04:FLASH only in indirect mode */
1702 case AGSA_NVMD_CONFIG_SEEPROM:
1703 /* NVMD=1 */
1704 /* Data Offset should be 0 */
1705 /* set up signature */
1706 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.signature), NVMDInfo->signature);
1707 /* indirect payload IP = 1, NVMD = 0x1 (SEEPROM0) */
1708 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD),
1709 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1710 break;
1711 case AGSA_NVMD_VPD_FLASH:
1712 /* indirect payload IP = 1, NVMD=0x4 (FLASH) */
1713 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD),
1714 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice);
1715 /* set up Offset */
1716 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset),
1717 NVMDInfo->dataOffsetAddress);
1718 break;
1719 default:
1720 SA_DBG1(("mpiSetNVMDCmd, (IP=1)wrong device type = 0x%x\n", NVMDInfo->NVMDevice));
1721 ret = AGSA_RC_FAILURE;
1722 ossaSetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR);
1723 break;
1724 }
1725
1726 /* set up SGL field */
1727 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ISglAL), (NVMDInfo->indirectAddrLower32));
1728 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ISglAH), (NVMDInfo->indirectAddrUpper32));
1729 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ILen), (NVMDInfo->indirectLen));
1730 /* build IOMB command and send to SPC */
1731 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_NVMD_DATA, IOMB_SIZE64, queueNum);
1732 }
1733 else
1734 {
1735 /* direct payload IP = 0 */
1736 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice)
1737 {
1738 /* NVMD = 0 */
1739 /* indirect payload IP = 0 and 0x0 (TWI) */
1740 /* not allow write to Config SEEPROM for direct mode, so don't set singature */
1741 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD),
1742 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) |
1743 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) |
1744 NVMDInfo->NVMDevice);
1745 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset),
1746 NVMDInfo->dataOffsetAddress | (NVMDInfo->directLen << SHIFT24));
1747 si_memcpy(&payload.Data.NVMData[0], NVMDInfo->directData, NVMDInfo->directLen);
1748 /* build IOMB command and send to SPC */
1749 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_NVMD_DATA, IOMB_SIZE64, queueNum);
1750 }
1751 else
1752 {
1753 SA_DBG1(("mpiSetNVMDCmd, (IP=0)wrong device type = 0x%x\n", NVMDInfo->NVMDevice));
1754 ret = AGSA_RC_FAILURE;
1755 ossaSetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR);
1756 }
1757 }
1758
1759 if (AGSA_RC_SUCCESS != ret)
1760 {
1761 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1762 /* remove the request from IOMap */
1763 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1764 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1765 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1766 pRequest->valid = agFALSE;
1767
1768 /* return the request to free pool */
1769 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1770 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1771 SA_DBG1(("mpiSetVPDCmd, sending IOMB failed\n" ));
1772 }
1773 SA_DBG3(("mpiSetNVMDCmd, return value = %d\n", ret));
1774 }
1775
1776
1777 /* return value */
1778 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xm");
1779 return ret;
1780 }
1781
1782 /******************************************************************************/
1783 /*! \brief Set Device State command
1784 *
1785 * This command is set Device State to SPC.
1786 *
1787 * \param agRoot Handles for this instance of SAS/SATA LLL
1788 * \param agContext Context for the Set Nexus State command
1789 * \param deviceId DeviceId
1790 * \param queueNum Queue Number of inbound/outbound queue
1791 *
1792 * \return If the MPI command is sent to SPC successfully
1793 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1794 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1795 * - \e AGSA_RC_FAILURE the MPI command is failure
1796 *
1797 */
1798 /*******************************************************************************/
mpiSetDeviceStateCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 deviceId,bit32 nds,bit32 queueNum)1799 GLOBAL bit32 mpiSetDeviceStateCmd(
1800 agsaRoot_t *agRoot,
1801 agsaContext_t *agContext,
1802 bit32 deviceId,
1803 bit32 nds,
1804 bit32 queueNum
1805 )
1806 {
1807 bit32 ret = AGSA_RC_SUCCESS;
1808 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1809 agsaIORequestDesc_t *pRequest;
1810 agsaSetDeviceStateCmd_t payload;
1811
1812 smTraceFuncEnter(hpDBG_VERY_LOUD,"xn");
1813
1814 /* Get request from free IORequests */
1815 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1816 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1817
1818 /* If no LL Control request entry available */
1819 if ( agNULL == pRequest )
1820 {
1821 SA_DBG1(("mpiSetDeviceStateCmd, No request from free list\n" ));
1822 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xn");
1823 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1824 return AGSA_RC_BUSY;
1825 }
1826 /* If LL Control request entry avaliable */
1827 else
1828 {
1829 SA_DBG3(("mpiSetDeviceStateCmd, Build IOMB DeviceId= 0x%x\n", deviceId));
1830 /* Remove the request from free list */
1831 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1832 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1833 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1834 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1835 pRequest->valid = agTRUE;
1836 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1837
1838 /* set payload to zeros */
1839 si_memset(&payload, 0, sizeof(agsaSetDeviceStateCmd_t));
1840 /* set tag field */
1841 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, tag), pRequest->HTag);
1842 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, deviceId), deviceId);
1843 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, NDS), nds);
1844
1845 /* build IOMB command and send to SPC */
1846 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_DEVICE_STATE, IOMB_SIZE64, queueNum);
1847 if (AGSA_RC_SUCCESS != ret)
1848 {
1849 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1850 /* remove the request from IOMap */
1851 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1852 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1853 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1854 pRequest->valid = agFALSE;
1855
1856 /* return the request to free pool */
1857 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1858
1859 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1860
1861 SA_DBG1(("mpiSetNexusStateCmd, sending IOMB failed\n" ));
1862 }
1863 SA_DBG3(("mpiSetDeviceStateCmd, return value = %d\n", ret));
1864 }
1865
1866 /* return value */
1867 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xn");
1868
1869 return ret;
1870 }
1871
1872 /******************************************************************************/
1873 /*! \brief Get Device State command
1874 *
1875 * This command is get device State to SPC.
1876 *
1877 * \param agRoot Handles for this instance of SAS/SATA LLL
1878 * \param agContext Context for the Get Nexus State command
1879 * \param deviceId DeviceId
1880 * \param queueNum Queue Number of inbound/outbound queue
1881 *
1882 * \return If the MPI command is sent to SPC successfully
1883 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1884 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1885 * - \e AGSA_RC_FAILURE the MPI command is failure
1886 *
1887 */
1888 /*******************************************************************************/
mpiGetDeviceStateCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 deviceId,bit32 queueNum)1889 GLOBAL bit32 mpiGetDeviceStateCmd(
1890 agsaRoot_t *agRoot,
1891 agsaContext_t *agContext,
1892 bit32 deviceId,
1893 bit32 queueNum
1894 )
1895 {
1896 bit32 ret = AGSA_RC_SUCCESS;
1897 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1898 agsaIORequestDesc_t *pRequest;
1899 agsaGetDeviceStateCmd_t payload;
1900 bit32 using_reserved = agFALSE;
1901
1902 smTraceFuncEnter(hpDBG_VERY_LOUD,"xf");
1903
1904 /* Get request from free IORequests */
1905 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1906 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1907
1908 /* If no LL Control request entry available */
1909 if ( agNULL == pRequest )
1910 {
1911 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1912 /* If no LL Control request entry available */
1913 if(agNULL != pRequest)
1914 {
1915 using_reserved = agTRUE;
1916 SA_DBG1(("mpiGetDeviceStateCmd, using saRoot->freeReservedRequests\n"));
1917 }
1918 else
1919 {
1920 SA_DBG1(("mpiGetDeviceStateCmd, No request from free list Not using saRoot->freeReservedRequests\n"));
1921 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xf");
1922 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1923 return AGSA_RC_BUSY;
1924 }
1925
1926 }
1927 /* If LL Control request entry avaliable */
1928 SA_DBG3(("mpiGetDeviceStateCmd, Build IOMB DeviceId= 0x%x\n", deviceId));
1929 /* Remove the request from free list */
1930 if( using_reserved )
1931 {
1932 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1933 }
1934 else
1935 {
1936 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1937 }
1938 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1939 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1940 saRoot->IOMap[pRequest->HTag].agContext = agContext;
1941 pRequest->valid = agTRUE;
1942
1943 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1944
1945 /* set payload to zeros */
1946 si_memset(&payload, 0, sizeof(agsaGetDeviceStateCmd_t));
1947 /* set tag field */
1948 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDeviceStateCmd_t, tag), pRequest->HTag);
1949 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDeviceStateCmd_t, deviceId), deviceId);
1950
1951 /* build IOMB command and send to SPC */
1952 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEVICE_STATE, IOMB_SIZE64, queueNum);
1953 if (AGSA_RC_SUCCESS != ret)
1954 {
1955 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1956 /* remove the request from IOMap */
1957 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
1958 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1959 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1960 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1961 pRequest->valid = agFALSE;
1962 /* return the request to free pool */
1963 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1964 {
1965 SA_DBG1(("mpiGetDeviceStateCmd: saving pRequest (%p) for later use\n", pRequest));
1966 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1967 }
1968 else
1969 {
1970 /* return the request to free pool */
1971 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1972 }
1973 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1974
1975 SA_DBG1(("mpiGetDeviceStateCmd, sending IOMB failed\n" ));
1976 }
1977 SA_DBG3(("mpiGetDeviceStateCmd, return value = %d\n", ret));
1978
1979 /* return value */
1980 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xf");
1981
1982 return ret;
1983 }
1984
1985 /******************************************************************************/
1986 /*! \brief SAS ReInitialize command
1987 *
1988 * This command is Reinitialize SAS paremeters to SPC.
1989 *
1990 * \param agRoot Handles for this instance of SAS/SATA LLL
1991 * \param agContext Context for the Get Nexus State command
1992 * \param agSASConfig SAS Configuration Parameters
1993 * \param queueNum Queue Number of inbound/outbound queue
1994 *
1995 * \return If the MPI command is sent to SPC successfully
1996 * - \e AGSA_RC_SUCCESS the MPI command is successfully
1997 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
1998 * - \e AGSA_RC_FAILURE the MPI command is failure
1999 *
2000 */
2001 /*******************************************************************************/
mpiSasReinitializeCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaSASReconfig_t * agSASConfig,bit32 queueNum)2002 GLOBAL bit32 mpiSasReinitializeCmd(
2003 agsaRoot_t *agRoot,
2004 agsaContext_t *agContext,
2005 agsaSASReconfig_t *agSASConfig,
2006 bit32 queueNum
2007 )
2008 {
2009 bit32 ret = AGSA_RC_SUCCESS;
2010 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2011 agsaIORequestDesc_t *pRequest;
2012 agsaSasReInitializeCmd_t payload;
2013
2014 smTraceFuncEnter(hpDBG_VERY_LOUD,"xo");
2015
2016 /* Get request from free IORequests */
2017 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2018 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2019
2020 /* If no LL Control request entry available */
2021 if ( agNULL == pRequest )
2022 {
2023 SA_DBG1(("mpiSasReinitializeCmd, No request from free list\n" ));
2024 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xo");
2025 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2026 return AGSA_RC_BUSY;
2027 }
2028 /* If LL Control request entry avaliable */
2029 else
2030 {
2031 SA_DBG3(("mpiSasReinitializeCmd, Build IOMB SAS_RE_INITIALIZE\n"));
2032 /* Remove the request from free list */
2033 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2034 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2035 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2036 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2037 pRequest->valid = agTRUE;
2038 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2039
2040 /* set payload to zeros */
2041 si_memset(&payload, 0, sizeof(agsaSasReInitializeCmd_t));
2042
2043 /* set tag field */
2044 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, tag), pRequest->HTag);
2045 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, setFlags), agSASConfig->flags);
2046 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, MaxPorts), agSASConfig->maxPorts);
2047 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, openRejReCmdData),
2048 (agSASConfig->openRejectRetriesCmd << SHIFT16) | agSASConfig->openRejectRetriesData);
2049 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, sataHOLTMO), agSASConfig->sataHolTmo);
2050
2051
2052 /* build IOMB command and send to SPC */
2053 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_RE_INITIALIZE, IOMB_SIZE64, queueNum);
2054 if (AGSA_RC_SUCCESS != ret)
2055 {
2056 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2057 /* remove the request from IOMap */
2058 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2059 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2060 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2061 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2062 pRequest->valid = agFALSE;
2063
2064 /* return the request to free pool */
2065 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2066
2067 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2068
2069 SA_DBG1(("mpiSasReinitializeCmd, sending IOMB failed\n" ));
2070 }
2071 SA_DBG3(("mpiSasReinitializeCmd, return value = %d\n", ret));
2072 }
2073
2074 /* return value */
2075 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xo");
2076
2077 return ret;
2078 }
2079
2080 /******************************************************************************/
2081 /*! \brief SAS Set Controller Configuration Command
2082 *
2083 * This command updates the contents of a controller mode page.
2084 *
2085 * \param agRoot Handles for this instance of SAS/SATA LLL
2086 * \param agContext Context for the Get Nexus State command
2087 * \param agControllerConfig Mode page being sent to the controller
2088 * \param queueNum Queue Number of inbound/outbound queue
2089 *
2090 * \return If the MPI command is sent to SPC successfully
2091 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2092 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2093 * - \e AGSA_RC_FAILURE the MPI command is failure
2094 *
2095 */
2096 /*******************************************************************************/
2097 GLOBAL bit32
mpiSetControllerConfigCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaSetControllerConfigCmd_t * agControllerConfig,bit32 queueNum,bit8 modePageContext)2098 mpiSetControllerConfigCmd(
2099 agsaRoot_t *agRoot,
2100 agsaContext_t *agContext,
2101 agsaSetControllerConfigCmd_t *agControllerConfig,
2102 bit32 queueNum,
2103 bit8 modePageContext
2104 )
2105 {
2106 bit32 ret = AGSA_RC_SUCCESS;
2107 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2108 agsaIORequestDesc_t *pRequest;
2109
2110 smTraceFuncEnter(hpDBG_VERY_LOUD,"x1");
2111
2112 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n",
2113 agControllerConfig->pageCode,agControllerConfig->configPage[0],
2114 agControllerConfig->configPage[1], agControllerConfig->configPage[2]));
2115 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n",
2116 agControllerConfig->configPage[3],agControllerConfig->configPage[4],
2117 agControllerConfig->configPage[5], agControllerConfig->configPage[6]));
2118 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n",
2119 agControllerConfig->configPage[7],agControllerConfig->configPage[8],
2120 agControllerConfig->configPage[9], agControllerConfig->configPage[10]));
2121 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x\n",
2122 agControllerConfig->configPage[11],agControllerConfig->configPage[12]));
2123
2124 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2125 /* Get request from free IORequests */
2126 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2127
2128 /* If no LL Control request entry available */
2129 if ( agNULL == pRequest )
2130 {
2131 SA_DBG1(("mpiSetControllerConfigCmd, No request from free list\n" ));
2132 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "x1");
2133 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2134 return AGSA_RC_BUSY;
2135 }
2136 /* If LL Control request entry avaliable */
2137 else
2138 {
2139 SA_DBG2(("mpiSetControllerConfigCmd, Build IOMB pageCode 0x%x configPage[0] 0x%x\n",agControllerConfig->pageCode,agControllerConfig->configPage[0]));
2140 /* Remove the request from free list */
2141 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2142 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2143 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2144 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2145 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2146 pRequest->valid = agTRUE;
2147 pRequest->modePageContext = modePageContext;
2148 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2149
2150 /* set tag field */
2151 agControllerConfig->tag = pRequest->HTag;
2152 ret = mpiBuildCmd(agRoot, (bit32 *)agControllerConfig,
2153 MPI_CATEGORY_SAS_SATA, OPC_INB_SET_CONTROLLER_CONFIG, IOMB_SIZE64, 0);
2154
2155 if (AGSA_RC_SUCCESS != ret)
2156 {
2157 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2158 /* remove the request from IOMap */
2159 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2160 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2161 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2162 pRequest->valid = agFALSE;
2163
2164 /* return the request to free pool */
2165 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2166
2167 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2168
2169 SA_DBG1(("mpiSetControllerConfigCmd, sending IOMB failed\n" ));
2170 }
2171 SA_DBG3(("mpiSetControllerConfigCmd, return value = %d\n", ret));
2172 }
2173
2174 /* return value */
2175 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x1");
2176
2177 return ret;
2178 }
2179
2180 /******************************************************************************/
2181 /*! \brief SAS Get Controller Configuration Command
2182 *
2183 * This command retrieves the contents of a controller mode page.
2184 *
2185 * \param agRoot Handles for this instance of SAS/SATA LLL
2186 * \param agContext Context for the Get Nexus State command
2187 * \param agControllerConfig Mode page to retrieve from the controller
2188 * \param queueNum Queue Number of inbound/outbound queue
2189 *
2190 * \return If the MPI command is sent to SPC successfully
2191 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2192 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2193 * - \e AGSA_RC_FAILURE the MPI command is failure
2194 *
2195 */
2196 /*******************************************************************************/
mpiGetControllerConfigCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaGetControllerConfigCmd_t * agControllerConfig,bit32 queueNum)2197 GLOBAL bit32 mpiGetControllerConfigCmd(
2198 agsaRoot_t *agRoot,
2199 agsaContext_t *agContext,
2200 agsaGetControllerConfigCmd_t *agControllerConfig,
2201 bit32 queueNum
2202 )
2203 {
2204 bit32 ret = AGSA_RC_SUCCESS;
2205 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2206 agsaIORequestDesc_t *pRequest;
2207
2208 smTraceFuncEnter(hpDBG_VERY_LOUD,"xq");
2209
2210 SA_DBG1(("mpiGetControllerConfigCmd: Tag 0x%0X Page Code %0X\n",agControllerConfig->tag,agControllerConfig->pageCode ));
2211 /* Get request from free IORequests */
2212 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2213 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2214
2215 /* If no LL Control request entry available */
2216 if ( agNULL == pRequest )
2217 {
2218 SA_DBG1(("mpiGetControllerConfigCmd, No request from free list\n" ));
2219 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xq");
2220 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2221 return AGSA_RC_BUSY;
2222 }
2223 /* If LL Control request entry avaliable */
2224 else
2225 {
2226 SA_DBG3(("mpiGetControllerConfig, Build IOMB mpiGetControllerConfigCmd\n"));
2227 /* Remove the request from free list */
2228 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2229 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2230 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2231 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2232 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2233 pRequest->valid = agTRUE;
2234 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2235
2236 /* set tag field */
2237 agControllerConfig->tag = pRequest->HTag;
2238
2239 ret = mpiBuildCmd(agRoot, (bit32 *) agControllerConfig,
2240 MPI_CATEGORY_SAS_SATA, OPC_INB_GET_CONTROLLER_CONFIG, IOMB_SIZE64, 0);
2241
2242 if (AGSA_RC_SUCCESS != ret)
2243 {
2244 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2245 /* remove the request from IOMap */
2246 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2247 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2248 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2249 pRequest->valid = agFALSE;
2250
2251 /* return the request to free pool */
2252 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2253
2254 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2255
2256 SA_DBG1(("mpiGetControllerConfigCmd, sending IOMB failed\n" ));
2257 }
2258 else
2259 {
2260 SA_DBG3(("mpiGetControllerConfigCmd, set OK\n"));
2261 }
2262 SA_DBG3(("mpiGetControllerConfigCmd, return value = %d\n", ret));
2263 }
2264
2265 /* return value */
2266 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xq");
2267
2268 return ret;
2269 }
2270
2271 /******************************************************************************/
2272 /*! \brief SAS Encryption KEK command
2273 *
2274 * This command updates one or more KEK in a controller that supports encryption.
2275 *
2276 * \param agRoot Handles for this instance of SAS/SATA LLL
2277 * \param agContext Context for the Get Nexus State command
2278 * \param agKekMgmt Kek information that will be sent to the controller
2279 * \param queueNum Queue Number of inbound/outbound queue
2280 *
2281 * \return If the MPI command is sent to SPC successfully
2282 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2283 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2284 * - \e AGSA_RC_FAILURE the MPI command is failure
2285 *
2286 */
2287 /*******************************************************************************/
mpiKekManagementCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaKekManagementCmd_t * agKekMgmt,bit32 queueNum)2288 GLOBAL bit32 mpiKekManagementCmd(
2289 agsaRoot_t *agRoot,
2290 agsaContext_t *agContext,
2291 agsaKekManagementCmd_t *agKekMgmt,
2292 bit32 queueNum
2293 )
2294 {
2295 bit32 ret = AGSA_RC_SUCCESS;
2296 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2297 agsaIORequestDesc_t *pRequest;
2298
2299 smTraceFuncEnter(hpDBG_VERY_LOUD,"x2");
2300
2301 /* Get request from free IORequests */
2302 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2303 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2304
2305 /* If no LL Control request entry available */
2306 if ( agNULL == pRequest )
2307 {
2308 SA_DBG1(("mpiKekManagementCmd, No request from free list\n" ));
2309 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "x2");
2310 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2311 return AGSA_RC_BUSY;
2312 }
2313 /* If LL Control request entry avaliable */
2314 else
2315 {
2316 SA_DBG3(("mpiKekManagementCmd, Build OPC_INB_KEK_MANAGEMENT\n"));
2317 /* Remove the request from free list */
2318 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2319 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2320 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2321 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2322 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2323 pRequest->valid = agTRUE;
2324 agKekMgmt->tag = pRequest->HTag;
2325 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2326
2327 SA_DBG1(("mpiKekManagementCmd, 0x%X 0x%X 0x%X\n", agKekMgmt->tag,agKekMgmt->NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP, agKekMgmt->reserved ));
2328
2329 ret = mpiBuildCmd(agRoot, (bit32 *)agKekMgmt, MPI_CATEGORY_SAS_SATA, OPC_INB_KEK_MANAGEMENT, IOMB_SIZE64, 0);
2330
2331 if (AGSA_RC_SUCCESS != ret)
2332 {
2333 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2334 /* remove the request from IOMap */
2335 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2336 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2337 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2338 pRequest->valid = agFALSE;
2339 /* return the request to free pool */
2340 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2341
2342 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2343 SA_DBG1(("mpiKekManagementCmd, sending IOMB failed\n" ));
2344 }
2345 SA_DBG3(("mpiKekManagementCmd, return value = %d\n", ret));
2346 }
2347
2348 /* return value */
2349 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x2");
2350
2351 return ret;
2352 }
2353
2354 /******************************************************************************/
2355 /*! \brief SAS Encryption DEK management command
2356 *
2357 * This command updates one or more DEK in a controller that supports encryption.
2358 *
2359 * \param agRoot Handles for this instance of SAS/SATA LLL
2360 * \param agContext Context for the Get Nexus State command
2361 * \param agDekMgmt DEK information that will be sent to the controller
2362 * \param queueNum Queue Number of inbound/outbound queue
2363 *
2364 * \return If the MPI command is sent to SPC successfully
2365 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2366 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2367 * - \e AGSA_RC_FAILURE the MPI command is failure
2368 *
2369 */
2370 /*******************************************************************************/
mpiDekManagementCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaDekManagementCmd_t * agDekMgmt,bit32 queueNum)2371 GLOBAL bit32 mpiDekManagementCmd(
2372 agsaRoot_t *agRoot,
2373 agsaContext_t *agContext,
2374 agsaDekManagementCmd_t *agDekMgmt,
2375 bit32 queueNum
2376 )
2377 {
2378 bit32 ret = AGSA_RC_SUCCESS;
2379 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2380 agsaIORequestDesc_t *pRequest;
2381
2382 smTraceFuncEnter(hpDBG_VERY_LOUD,"xs");
2383
2384 /* Get request from free IORequests */
2385 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2386 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2387
2388 /* If no LL Control request entry available */
2389 if ( agNULL == pRequest )
2390 {
2391 SA_DBG1(("mpiDekManagementCmd, No request from free list\n" ));
2392 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xs");
2393 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2394 return AGSA_RC_BUSY;
2395 }
2396 /* If LL Control request entry avaliable */
2397 else
2398 {
2399 SA_DBG1(("mpiDekManagementCmd, Build OPC_INB_DEK_MANAGEMENT pRequest %p\n",pRequest));
2400 /* Remove the request from free list */
2401 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2402 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2403 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2404 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2405 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2406 pRequest->valid = agTRUE;
2407 agDekMgmt->tag = pRequest->HTag;
2408 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2409
2410 SA_DBG1(("mpiDekManagementCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
2411 agDekMgmt->tag,
2412 agDekMgmt->KEKIDX_Reserved_TBLS_DSOP,
2413 agDekMgmt->dekIndex,
2414 agDekMgmt->tableAddrLo,
2415 agDekMgmt->tableAddrHi,
2416 agDekMgmt->tableEntries,
2417 agDekMgmt->Reserved_DBF_TBL_SIZE ));
2418 ret = mpiBuildCmd(agRoot, (bit32 *) agDekMgmt, MPI_CATEGORY_SAS_SATA, OPC_INB_DEK_MANAGEMENT, IOMB_SIZE64, 0);
2419
2420 if (AGSA_RC_SUCCESS != ret)
2421 {
2422 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2423 /* remove the request from IOMap */
2424 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2425 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2426 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2427 pRequest->valid = agFALSE;
2428
2429 /* return the request to free pool */
2430 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2431
2432 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2433
2434 SA_DBG1(("mpiDekManagementCmd, sending IOMB failed\n" ));
2435 }
2436 SA_DBG3(("mpiDekManagementCmd, return value = %d\n", ret));
2437 }
2438
2439 /* return value */
2440 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xs");
2441
2442 return ret;
2443 }
2444
2445 /******************************************************************************/
2446 /*! \brief
2447 *
2448 * This command sends operator management command.
2449 *
2450 * \param agRoot Handles for this instance of SAS/SATA LLL
2451 * \param agContext Context
2452 * \param queueNum Queue Number of inbound/outbound queue
2453 *
2454 * \return If the MPI command is sent to SPC successfully
2455 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2456 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2457 * - \e AGSA_RC_FAILURE the MPI command is failure
2458 *
2459 */
2460 /*******************************************************************************/
mpiOperatorManagementCmd(agsaRoot_t * agRoot,bit32 queueNum,agsaContext_t * agContext,agsaOperatorMangmentCmd_t * operatorcode)2461 GLOBAL bit32 mpiOperatorManagementCmd(
2462 agsaRoot_t *agRoot,
2463 bit32 queueNum,
2464 agsaContext_t *agContext,
2465 agsaOperatorMangmentCmd_t *operatorcode )
2466 {
2467 bit32 ret = AGSA_RC_SUCCESS;
2468 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2469 agsaIORequestDesc_t *pRequest;
2470
2471 smTraceFuncEnter(hpDBG_VERY_LOUD,"2q");
2472
2473 SA_DBG1(("mpiOperatorManagementCmd, enter\n" ));
2474
2475 /* Get request from free IORequests */
2476 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2477 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2478
2479 /* If no LL Control request entry available */
2480 if ( agNULL == pRequest )
2481 {
2482 SA_DBG1(("mpiOperatorManagementCmd, No request from free list\n" ));
2483 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2q");
2484 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2485 return AGSA_RC_BUSY;
2486 }
2487 /* If LL Control request entry avaliable */
2488 else
2489 {
2490 SA_DBG1(("mpiOperatorManagementCmd, Build OPC_INB_OPR_MGMT\n"));
2491 /* Remove the request from free list */
2492 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2493 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2494 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2495 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2496 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2497 pRequest->valid = agTRUE;
2498 operatorcode->tag = pRequest->HTag;
2499 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2500
2501 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode , MPI_CATEGORY_SAS_SATA, OPC_INB_OPR_MGMT, IOMB_SIZE128, 0);
2502
2503 if (AGSA_RC_SUCCESS != ret)
2504 {
2505 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2506 /* remove the request from IOMap */
2507 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2508 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2509 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2510 pRequest->valid = agFALSE;
2511
2512 /* return the request to free pool */
2513 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2514
2515 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2516
2517 SA_DBG1(("mpiOperatorManagementCmd, sending IOMB failed\n" ));
2518 }
2519 SA_DBG1(("mpiOperatorManagementCmd, return value = %d\n", ret));
2520 }
2521
2522 /* return value */
2523 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2q");
2524
2525 return ret;
2526 }
2527
2528 /******************************************************************************/
2529 /*! \brief
2530 *
2531 * This command sends encrypt self test command.
2532 *
2533 * \param agRoot Handles for this instance of SAS/SATA LLL
2534 * \param agContext Context
2535 * \param queueNum Queue Number of inbound/outbound queue
2536 *
2537 * \return If the MPI command is sent to SPC successfully
2538 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2539 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2540 * - \e AGSA_RC_FAILURE the MPI command is failure
2541 *
2542 */
2543 /*******************************************************************************/
mpiEncryptBistCmd(agsaRoot_t * agRoot,bit32 queueNum,agsaContext_t * agContext,agsaEncryptBist_t * bist)2544 GLOBAL bit32 mpiEncryptBistCmd(
2545 agsaRoot_t *agRoot,
2546 bit32 queueNum,
2547 agsaContext_t *agContext,
2548 agsaEncryptBist_t *bist )
2549 {
2550 bit32 ret = AGSA_RC_SUCCESS;
2551 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2552 agsaIORequestDesc_t *pRequest;
2553
2554 smTraceFuncEnter(hpDBG_VERY_LOUD,"2z");
2555
2556 SA_DBG1(("mpiEncryptBistCmd, enter\n" ));
2557
2558 /* Get request from free IORequests */
2559 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2560 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2561
2562 /* If no LL Control request entry available */
2563 if ( agNULL == pRequest )
2564 {
2565 SA_DBG1(("mpiEncryptBistCmd, No request from free list\n" ));
2566 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2z");
2567 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2568 return AGSA_RC_BUSY;
2569 }
2570 /* If LL Control request entry avaliable */
2571 else
2572 {
2573 SA_DBG1(("mpiEncryptBistCmd, Build OPC_INB_ENC_TEST_EXECUTE\n"));
2574 /* Remove the request from free list */
2575 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2576 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2577 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2578 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2579 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2580 pRequest->valid = agTRUE;
2581 bist->tag = pRequest->HTag;
2582 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2583
2584 SA_DBG1(("mpiEncryptBistCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
2585 bist->tag,
2586 bist->r_subop,
2587 bist->testDiscption[0],
2588 bist->testDiscption[1],
2589 bist->testDiscption[2],
2590 bist->testDiscption[3],
2591 bist->testDiscption[4] ));
2592 ret = mpiBuildCmd(agRoot, (bit32 *)bist , MPI_CATEGORY_SAS_SATA, OPC_INB_ENC_TEST_EXECUTE, IOMB_SIZE64, 0);
2593
2594 if (AGSA_RC_SUCCESS != ret)
2595 {
2596 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2597 /* remove the request from IOMap */
2598 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2599 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2600 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2601 pRequest->valid = agFALSE;
2602
2603 /* return the request to free pool */
2604 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2605
2606 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2607
2608 SA_DBG1(("mpiEncryptBistCmd, sending IOMB failed\n" ));
2609 }
2610 SA_DBG1(("mpiEncryptBistCmd, return value = %d\n", ret));
2611 }
2612
2613 /* return value */
2614 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2z");
2615
2616 return ret;
2617 }
2618
2619 /******************************************************************************/
2620 /*! \brief
2621 *
2622 * This command sends set operator command.
2623 *
2624 * \param agRoot Handles for this instance of SAS/SATA LLL
2625 * \param agContext Context
2626 * \param queueNum Queue Number of inbound/outbound queue
2627 *
2628 * \return If the MPI command is sent to SPC successfully
2629 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2630 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2631 * - \e AGSA_RC_FAILURE the MPI command is failure
2632 *
2633 */
2634 /*******************************************************************************/
2635 GLOBAL bit32
mpiSetOperatorCmd(agsaRoot_t * agRoot,bit32 queueNum,agsaContext_t * agContext,agsaSetOperatorCmd_t * operatorcode)2636 mpiSetOperatorCmd(
2637 agsaRoot_t *agRoot,
2638 bit32 queueNum,
2639 agsaContext_t *agContext,
2640 agsaSetOperatorCmd_t *operatorcode
2641 )
2642 {
2643 bit32 ret = AGSA_RC_SUCCESS;
2644 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2645 agsaIORequestDesc_t *pRequest;
2646
2647 smTraceFuncEnter(hpDBG_VERY_LOUD,"39");
2648
2649 SA_DBG1(("mpiSetOperatorCmd, enter\n" ));
2650
2651 /* Get request from free IORequests */
2652 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2653 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2654
2655 /* If no LL Control request entry available */
2656 if ( agNULL == pRequest )
2657 {
2658 SA_DBG1(("mpiSetOperatorCmd, No request from free list\n" ));
2659 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "39");
2660 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2661 return AGSA_RC_BUSY;
2662 }
2663 /* If LL Control request entry avaliable */
2664 else
2665 {
2666 SA_DBG1(("mpiSetOperatorCmd, Build OPC_INB_SET_OPERATOR\n"));
2667 /* Remove the request from free list */
2668 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2669 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2670 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2671 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2672 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2673 pRequest->valid = agTRUE;
2674 operatorcode->tag = pRequest->HTag;
2675 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2676
2677 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_OPERATOR, IOMB_SIZE64, 0);
2678
2679 if (AGSA_RC_SUCCESS != ret)
2680 {
2681 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2682 /* remove the request from IOMap */
2683 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2684 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2685 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2686 pRequest->valid = agFALSE;
2687
2688 /* return the request to free pool */
2689 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2690
2691 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2692
2693 SA_DBG1(("mpiSetOperatorCmd, sending IOMB failed\n" ));
2694 }
2695 SA_DBG1(("mpiSetOperatorCmd, return value = %d\n", ret));
2696 }
2697
2698 /* return value */
2699 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "39");
2700
2701 return ret;
2702 }
2703
2704 /******************************************************************************/
2705 /*! \brief
2706 *
2707 * This command sends get operator command.
2708 *
2709 * \param agRoot Handles for this instance of SAS/SATA LLL
2710 * \param agContext Context
2711 * \param queueNum Queue Number of inbound/outbound queue
2712 *
2713 * \return If the MPI command is sent to SPC successfully
2714 * - \e AGSA_RC_SUCCESS the MPI command is successfully
2715 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now
2716 * - \e AGSA_RC_FAILURE the MPI command is failure
2717 *
2718 */
2719 /*******************************************************************************/
2720 GLOBAL bit32
mpiGetOperatorCmd(agsaRoot_t * agRoot,bit32 queueNum,agsaContext_t * agContext,agsaGetOperatorCmd_t * operatorcode)2721 mpiGetOperatorCmd(
2722 agsaRoot_t *agRoot,
2723 bit32 queueNum,
2724 agsaContext_t *agContext,
2725 agsaGetOperatorCmd_t *operatorcode
2726 )
2727 {
2728 bit32 ret = AGSA_RC_SUCCESS;
2729 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2730 agsaIORequestDesc_t *pRequest;
2731
2732 smTraceFuncEnter(hpDBG_VERY_LOUD,"3e");
2733
2734 SA_DBG1(("mpiGetOperatorCmd, enter\n" ));
2735
2736 /* Get request from free IORequests */
2737 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2738 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2739
2740 /* If no LL Control request entry available */
2741 if ( agNULL == pRequest )
2742 {
2743 SA_DBG1(("mpiGetOperatorCmd, No request from free list\n" ));
2744 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3e");
2745 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2746 return AGSA_RC_BUSY;
2747 }
2748 /* If LL Control request entry avaliable */
2749 else
2750 {
2751 SA_DBG1(("mpiGetOperatorCmd, Build OPC_INB_GET_OPERATOR\n"));
2752 /* Remove the request from free list */
2753 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2754 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2755 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2756 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2757 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2758 pRequest->valid = agTRUE;
2759 operatorcode->tag = pRequest->HTag;
2760 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2761
2762 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_OPERATOR, IOMB_SIZE64, 0);
2763
2764 if (AGSA_RC_SUCCESS != ret)
2765 {
2766 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2767 /* remove the request from IOMap */
2768 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2769 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2770 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2771 pRequest->valid = agFALSE;
2772
2773 /* return the request to free pool */
2774 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2775
2776 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2777
2778 SA_DBG1(("mpiGetOperatorCmd, sending IOMB failed\n" ));
2779 }
2780 SA_DBG1(("mpiGetOperatorCmd, return value = %d\n", ret));
2781 }
2782
2783 /* return value */
2784 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3e");
2785
2786 return ret;
2787 }
2788
mpiDIFEncryptionOffloadCmd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 op,agsaDifEncPayload_t * agDifEncOffload,ossaDIFEncryptionOffloadStartCB_t agCB)2789 GLOBAL bit32 mpiDIFEncryptionOffloadCmd(
2790 agsaRoot_t *agRoot,
2791 agsaContext_t *agContext,
2792 bit32 queueNum,
2793 bit32 op,
2794 agsaDifEncPayload_t *agDifEncOffload,
2795 ossaDIFEncryptionOffloadStartCB_t agCB
2796 )
2797 {
2798 bit32 ret = AGSA_RC_SUCCESS;
2799 bit32 dw8=0;
2800 bit32 dw9=0;
2801 bit32 dw10=0;
2802 bit32 dw14=0;
2803 bit32 dw15=0;
2804 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2805 agsaIORequestDesc_t *pRequest;
2806 agsaDifEncOffloadCmd_t payload;
2807 smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
2808
2809 /* Get request from free IORequests */
2810 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2811 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2812
2813 /* If no LL Control request entry available */
2814 if ( agNULL == pRequest )
2815 {
2816 SA_DBG1(("mpiDIFEncryptionOffloadCmd: No request from free list\n" ));
2817 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2b");
2818 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2819 return AGSA_RC_BUSY;
2820 }
2821 /* If LL Control request entry avaliable */
2822 else
2823 {
2824 SA_DBG1(("mpiDIFEncryptionOffloadCmd: Build OPC_INB_DIF_ENC_OFFLOAD_CMD pRequest %p\n",pRequest));
2825 /* Remove the request from free list */
2826 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
2827 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2828 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2829 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2830 saRoot->IOMap[pRequest->HTag].agContext = agContext;
2831 pRequest->valid = agTRUE;
2832 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
2833 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2834
2835 si_memset(&payload, 0, sizeof(agsaDifEncOffloadCmd_t));
2836 SA_DBG1(("mpiDIFEncryptionOffloadCmd: op %d\n",op));
2837
2838 if(smIS_SPCV(agRoot))
2839 {
2840 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tag), pRequest->HTag);
2841 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, option), op);
2842 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, Src_Data_Len), agDifEncOffload->SrcDL);
2843 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, Dst_Data_Len), agDifEncOffload->DstDL);
2844 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, flags), agDifEncOffload->dif.flags);
2845
2846 dw8 = agDifEncOffload->dif.udrtArray[1] << SHIFT24 |
2847 agDifEncOffload->dif.udrtArray[0] << SHIFT16 |
2848 agDifEncOffload->dif.udtArray[1] << SHIFT8 |
2849 agDifEncOffload->dif.udtArray[0];
2850 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDTR01UDT01), dw8);
2851
2852 dw9 = agDifEncOffload->dif.udtArray[5] << SHIFT24 |
2853 agDifEncOffload->dif.udtArray[4] << SHIFT16 |
2854 agDifEncOffload->dif.udtArray[3] << SHIFT8 |
2855 agDifEncOffload->dif.udtArray[2];
2856 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDT2345), dw9);
2857 dw10 = agDifEncOffload->dif.udrtArray[5] << SHIFT24 |
2858 agDifEncOffload->dif.udrtArray[4] << SHIFT16 |
2859 agDifEncOffload->dif.udrtArray[3] << SHIFT8 |
2860 agDifEncOffload->dif.udrtArray[2];
2861
2862 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDTR2345), dw10);
2863
2864 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPLR0SecCnt_IOSeed),
2865 agDifEncOffload->dif.DIFPerLARegion0SecCount << SHIFT16 |
2866 agDifEncOffload->dif.initialIOSeed);
2867
2868 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPL_Addr_Lo) , agDifEncOffload->dif.DIFPerLAAddrLo);
2869 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPL_Addr_Hi) , agDifEncOffload->dif.DIFPerLAAddrHi);
2870
2871 dw14 = agDifEncOffload->encrypt.dekInfo.dekIndex << SHIFT8 |
2872 (agDifEncOffload->encrypt.dekInfo.dekTable & 0x3) << SHIFT2 |
2873 (agDifEncOffload->encrypt.keyTagCheck & 0x1) << SHIFT1;
2874
2875 if (agDifEncOffload->encrypt.cipherMode == agsaEncryptCipherModeXTS)
2876 {
2877 dw14 |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
2878 }
2879 else
2880 {
2881 dw14 |= (agDifEncOffload->encrypt.cipherMode & 0xF) << SHIFT4;
2882 }
2883
2884 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, KeyIndex_CMode_KTS_ENT_R), dw14);
2885
2886 dw15 = agDifEncOffload->encrypt.EncryptionPerLRegion0SecCount << SHIFT16 |
2887 (agDifEncOffload->encrypt.kekIndex & 0xF) << SHIFT5 |
2888 (agDifEncOffload->encrypt.sectorSizeIndex & 0x1F);
2889
2890 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPLR0SecCnt_KS_ENSS), dw15);
2891
2892 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, keyTag_W0), agDifEncOffload->encrypt.keyTag_W0);
2893 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, keyTag_W1), agDifEncOffload->encrypt.keyTag_W1);
2894 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W0), agDifEncOffload->encrypt.tweakVal_W0);
2895 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W1), agDifEncOffload->encrypt.tweakVal_W1);
2896 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W2), agDifEncOffload->encrypt.tweakVal_W2);
2897 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W3), agDifEncOffload->encrypt.tweakVal_W3);
2898 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPL_Addr_Lo), agDifEncOffload->encrypt.EncryptionPerLAAddrLo);
2899 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPL_Addr_Hi), agDifEncOffload->encrypt.EncryptionPerLAAddrHi);
2900
2901 si_memcpy((bit32 *) &(payload.SrcSgl), (bit32 *) &(agDifEncOffload->SrcSgl), sizeof(agsaSgl_t));
2902 si_memcpy((bit32 *) &(payload.DstSgl), (bit32 *) &(agDifEncOffload->DstSgl), sizeof(agsaSgl_t));
2903
2904 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DIF_ENC_OFFLOAD_CMD, IOMB_SIZE128, queueNum);
2905
2906 }
2907 else
2908 {
2909 /* SPC does not support this command */
2910 ret = AGSA_RC_FAILURE;
2911 }
2912
2913 if (AGSA_RC_SUCCESS != ret)
2914 {
2915 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2916 /* remove the request from IOMap */
2917 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2918 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2919 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2920 pRequest->valid = agFALSE;
2921
2922 /* return the request to free pool */
2923 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2924
2925 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2926
2927 SA_DBG1(("mpiDIFEncryptionOffloadCmd: sending IOMB failed\n" ));
2928 }
2929 SA_DBG3(("mpiDIFEncryptionOffloadCmd: return value = %d\n", ret));
2930 }
2931
2932 /* return value */
2933 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");
2934
2935 return ret;
2936 }
2937
2938