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