FreeBSD kernel pms device code
sasmp.c
Go to the documentation of this file.
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/*******************************************************************************/
27/*******************************************************************************/
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30#include <dev/pms/config.h>
31
33#ifdef SA_ENABLE_TRACE_FUNCTIONS
34#ifdef siTraceFileID
35#undef siTraceFileID
36#endif
37#define siTraceFileID 'N'
38#endif
39
40/******************************************************************************/
61/*******************************************************************************/
63 agsaRoot_t *agRoot,
64 agsaIORequest_t *agIORequest,
65 bit32 queueNum,
66 agsaDevHandle_t *agDevHandle,
67 bit32 agRequestType,
68 agsaSASRequestBody_t *agRequestBody,
70 )
71{
72 bit32 ret = AGSA_RC_SUCCESS, retVal;
73 agsaLLRoot_t *saRoot = agNULL;
74 mpiICQueue_t *circularQ;
75 agsaDeviceDesc_t *pDevice;
76 agsaPort_t *pPort;
77 agsaIORequestDesc_t *pRequest;
78 void *pMessage;
79 bit8 i, inq, outq;
80 bit8 using_reserved = agFALSE;
81 bit8 *payload_ptr;
82 agsaSMPFrame_t *pSMPFrame;
83
84 SA_DBG4(("saSMPStart: start\n"));
85
87
88 /* sanity check */
89 SA_ASSERT((agNULL != agRoot), "");
90 SA_ASSERT((agNULL != agIORequest), "");
91 SA_ASSERT((agNULL != agDevHandle), "");
92 SA_ASSERT((agNULL != agRequestBody), "");
93
94 /* sanity check */
95 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
96 SA_ASSERT((agNULL != saRoot), "");
97
98 if(saRoot == agNULL)
99 {
100 SA_DBG1(("saSMPStart : saRoot is NULL!!\n"));
101 return AGSA_RC_FAILURE;
102 }
103
104 /* Assign inbound and outbound queue number */
105 inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
106 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
107 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
108
109 /* Find the outgoing port for the device */
110 if (agNULL == agDevHandle->sdkData)
111 {
112 /* Device has been removed */
113 SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle));
115 return AGSA_RC_FAILURE;
116 }
117
118 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
119
120 pPort = pDevice->pPort;
121
122 /* Get request from free IO Requests */
124 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
125
126 /* If no LL IO request entry available */
127 if ( agNULL == pRequest )
128 {
129
131
132 if(agNULL != pRequest)
133 {
134 using_reserved = agTRUE;
135 SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));
136 }
137 else
138 {
140 SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n"));
142 return AGSA_RC_BUSY;
143 }
144 }
145
146 /* If free IOMB avaliable */
147 /* Remove the request from free list */
148 if( using_reserved )
149 {
150 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
151 }
152 else
153 {
154 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
155 }
156
157 /* Add the request to the pendingSMPRequests list of the device */
158 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
159 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
160 pRequest->valid = agTRUE;
162
163 /* set up pRequest */
164 pRequest->pIORequestContext = agIORequest;
165 pRequest->pDevice = pDevice;
166 pRequest->pPort = pPort;
167 pRequest->requestType = agRequestType;
168 pRequest->startTick = saRoot->timeTick;
169 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
170
171 /* Set request to the sdkData of agIORequest */
172 agIORequest->sdkData = pRequest;
173
174 /* save tag to IOMap */
175 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
176 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
177
178#ifdef SA_LL_IBQ_PROTECT
180#endif /* SA_LL_IBQ_PROTECT */
181
182 /* If LL IO request entry avaliable */
183 /* Get a free inbound queue entry */
184 circularQ = &saRoot->inboundQueue[inq];
185 retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
186
187 if (AGSA_RC_FAILURE == retVal)
188 {
189#ifdef SA_LL_IBQ_PROTECT
191#endif /* SA_LL_IBQ_PROTECT */
192 /* if not sending return to free list rare */
194 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
195 pRequest->valid = agFALSE;
196 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
198
199 SA_DBG1(("saSMPStart, error when get free IOMB\n"));
201 return AGSA_RC_FAILURE;
202 }
203
204 /* return busy if inbound queue is full */
205 if (AGSA_RC_BUSY == retVal)
206 {
207#ifdef SA_LL_IBQ_PROTECT
209#endif /* SA_LL_IBQ_PROTECT */
210 /* if not sending return to free list rare */
212 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
213 pRequest->valid = agFALSE;
214 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
216
217 SA_DBG1(("saSMPStart, no more IOMB\n"));
219 return AGSA_RC_BUSY;
220 }
221
222 /* Setup SMP Frame */
223 pSMPFrame = (agsaSMPFrame_t *) &(agRequestBody->smpFrame);
224
225 SA_DBG2(("saSMPStart:DeviceMapIndex 0x%x portId 0x%x portId 0x%x\n",pDevice->DeviceMapIndex,pPort->portId,pPort->portId));
226
227#if defined(SALLSDK_DEBUG)
228
229 SA_DBG2(("saSMPStart: outFrameBuf %p\n",pSMPFrame->outFrameBuf));
230
231 if(pSMPFrame->outFrameBuf )
232 {
233 SA_DBG2(("saSMPStart: outFrameBuf 0 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+0) ));
234 SA_DBG2(("saSMPStart: outFrameBuf 1 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+1) ));
235 SA_DBG2(("saSMPStart: outFrameBuf 2 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+2) ));
236 SA_DBG2(("saSMPStart: outFrameBuf 3 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+3) ));
237 SA_DBG2(("saSMPStart: outFrameBuf 4 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+4) ));
238 SA_DBG2(("saSMPStart: outFrameBuf 5 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+5) ));
239 SA_DBG2(("saSMPStart: outFrameBuf 6 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+6) ));
240 SA_DBG2(("saSMPStart: outFrameBuf 7 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+7) ));
241 SA_DBG2(("saSMPStart: outFrameBuf 8 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+8) ));
242 SA_DBG2(("saSMPStart: outFrameBuf 9 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+9) ));
243 SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+10) ));
244 SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+11) ));
245 }
246 SA_DBG2(("saSMPStart: outFrameAddrUpper32 0x%08X\n",pSMPFrame->outFrameAddrUpper32));
247 SA_DBG2(("saSMPStart: outFrameAddrLower32 0x%08X\n",pSMPFrame->outFrameAddrLower32));
248 SA_DBG2(("saSMPStart: outFrameLen 0x%08X\n",pSMPFrame->outFrameLen));
249 SA_DBG2(("saSMPStart: inFrameAddrUpper32 0x%08X\n",pSMPFrame->inFrameAddrUpper32));
250 SA_DBG2(("saSMPStart: inFrameAddrLower32 0x%08X\n",pSMPFrame->inFrameAddrLower32));
251 SA_DBG2(("saSMPStart: inFrameLen 0x%08X\n",pSMPFrame->inFrameLen));
252 SA_DBG2(("saSMPStart: expectedRespLen 0x%08X\n",pSMPFrame->expectedRespLen));
253 SA_DBG2(("saSMPStart: flag 0x%08X\n",pSMPFrame->flag));
254#endif /* SALLSDK_DEBUG */
255
256 if(smIS_SPC(agRoot))
257 // if(1)
258 {
259 agsaSMPCmd_t payload;
260 switch ( agRequestType )
261 {
263 {
264 bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
265 /* Prepare the payload of IOMB */
266 si_memset(&payload, 0, sizeof(agsaSMPCmd_t));
267 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag);
268 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex);
269
270 /* check SMP Response Frame with IR mode */
271 /* check if the SMP Response is indirect mode */
272 if (0 == pSMPFrame->inFrameLen)
273 {
274 /* PHY override not support */
275 /* Direct Response mode */
276 pRequest->IRmode = DIRECT_MODE;
277 }
278 else
279 {
280 /* Indirect Response mode */
281 pRequest->IRmode = INDIRECT_MODE;
282 IR_IP_OV_res_phyId_DPdLen_res = 1;
283 /* check SMP direct payload mode len */
284 if (pSMPFrame->outFrameLen > 32)
285 {
286#ifdef SA_LL_IBQ_PROTECT
288#endif /* SA_LL_IBQ_PROTECT */
289 /* if not sending return to free list rare */
291 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
292 pRequest->valid = agFALSE;
293 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
295 /* can not handle SMP frame length > 32 bytes it if IP=0 and IR=1 */
296 SA_DBG1(("saSMPStart, outFrameLen > 32 bytes error.\n"));
298 return AGSA_RC_FAILURE;
299 }
300 }
301
302 /* check Direct mode or Indirect mode for IP mode */
303 if ( (pSMPFrame->outFrameBuf &&
304 (pSMPFrame->outFrameLen <= AGSA_MAX_SMPPAYLOAD_VIA_SFO)) ||
305 ((pSMPFrame->outFrameBuf == agNULL) &&
306 (pSMPFrame->outFrameLen == 0) )
307 )
308 {
309 SA_DBG4(("saSMPStart: DIRECT Request SMP\n"));
310
311 IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
312
313 /* Direct payload length */
314 IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
315
316 /* copy payload - upto 48 bytes */
317 si_memcpy(&(payload.SMPCmd[0]),pSMPFrame->outFrameBuf,pSMPFrame->outFrameLen);
318 for ( i = 0; i < pSMPFrame->outFrameLen / sizeof(bit32)+1; i ++ )
319 {
320 SA_DBG4(("saSMPStart: payload.SMPCmd[%d] %x\n", i, payload.SMPCmd[i]));
321 }
322 }
323 else
324 {
325 SA_DBG4(("saSMPStart: INDIRECT Request SMP\n"));
326 /* use physical address */
327 IR_IP_OV_res_phyId_DPdLen_res = (INDIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
328
329 /* Direct payload length = 0 */
330 IR_IP_OV_res_phyId_DPdLen_res = IR_IP_OV_res_phyId_DPdLen_res & 0xff00ffff;
331
332 /* payload */
333 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32));
334 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32));
335 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen));
336 }
337 /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
338 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
339
340 /* check IR bit */
341 if (IR_IP_OV_res_phyId_DPdLen_res & INDIRECT_MODE)
342 {
343 /* setup indirect response frame address */
344 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32));
345 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32));
346 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen));
347 }
348
349 /* Build IOMB command and send it to SPC */
350 payload_ptr = (bit8 *)&payload;
351 ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
352
353 #ifdef SA_LL_IBQ_PROTECT
355 #endif /* SA_LL_IBQ_PROTECT */
356
357 break;
358 }
359 default:
360 {
361 SA_DBG1(("saSMPStart: SPC unknown agRequestType %x\n",agRequestType));
362 break;
363 }
364 }
365
366#ifdef SALL_API_TEST
367 if (ret == AGSA_RC_SUCCESS)
368 saRoot->LLCounters.IOCounter.numSMPStarted++;
369#endif
370 }
371 else /* IOMB is different for SPCV SMP */
372 {
373 agsaSMPCmd_V_t vpayload;
374
375 switch ( agRequestType )
376 {
378 {
379 bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
380 /* Prepare the payload of IOMB */
381 si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t));
382 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag);
383 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex);
384
385 /* Request header must be valid regardless of IP bit */
386 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) );
387
388 /* check SMP Response Frame with IR mode */
389 /* check if the SMP Response is indirect mode */
390 // smpFrameFlagDirectResponse smpFrameFlagDirectPayload
391 if ( 0 == pSMPFrame->flag && pSMPFrame->outFrameBuf )
392 {
393 /* PHY override not support */
394 /* Direct Response mode */
395 pRequest->IRmode = DIRECT_MODE;
396 SA_DBG2(("saSMPStart:V DIRECT Request SMP\n"));
397
398 IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
399
400 /* Direct payload length */
401 IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
402 /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
403 /* fatal error if missing */
404 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
405 /* fatal error if missing */
406
407 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) );
408 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) );
409 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) );
410
411 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), *((bit32*)pSMPFrame->outFrameBuf+4) );
412 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), *((bit32*)pSMPFrame->outFrameBuf+5) );
413 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) );
414 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24), *((bit32*)pSMPFrame->outFrameBuf+7) );
415
416 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28 ), *((bit32*)pSMPFrame->outFrameBuf+8) );
417 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32 ), *((bit32*)pSMPFrame->outFrameBuf+9) );
418 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36 ), *((bit32*)pSMPFrame->outFrameBuf+10) );
419 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF43_40 ), *((bit32*)pSMPFrame->outFrameBuf+11) );
420
421 }
422 else if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
423 {
424 /* IR IP */
425 SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse smpFrameFlagIndirectPayload SMP\n"));
426
427 pRequest->IRmode = INDIRECT_MODE;
428 IR_IP_OV_res_phyId_DPdLen_res = 3;
429
430 /* Indirect payload mode */
431 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32);
432 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32);
433 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen);
434 /* Indirect Response mode */
435 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
436 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
437 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
438 }
439 else if (smpFrameFlagIndirectPayload & pSMPFrame->flag ) /* */
440 {
441 /* IP */
442 SA_DBG2(("saSMPStart:V smpFrameFlagIndirectPayload SMP\n"));
443 pRequest->IRmode = DIRECT_MODE;
444 IR_IP_OV_res_phyId_DPdLen_res = 2;
445
446 /* Indirect payload mode */
447 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32);
448 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32);
449 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen);
450 }
451 else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
452 {
453 /* check IR bit */
454 /* Indirect Response mode */
455 pRequest->IRmode = INDIRECT_MODE;
456 SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse SMP\n"));
457 /* use physical address */
458 IR_IP_OV_res_phyId_DPdLen_res = 1;
459 /* Direct payload length */
460 IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
461
462 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) );
463 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) );
464 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) );
465
466 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), *((bit32*)pSMPFrame->outFrameBuf+4) );
467 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), *((bit32*)pSMPFrame->outFrameBuf+5) );
468 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) );
469 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24), *((bit32*)pSMPFrame->outFrameBuf+7) );
470
471 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
472 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
473 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
474 }
475 IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
476 /* fatal error if missing */
477 OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
478 /* fatal error if missing */
479 }
480 /* Build IOMB command and send it to SPCv */
481 payload_ptr = (bit8 *)&vpayload;
482 ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
483
484#ifdef SA_LL_IBQ_PROTECT
486#endif /* SA_LL_IBQ_PROTECT */
487
488 break;
489 default:
490 {
491 SA_DBG1(("saSMPStart: SPCv unknown agRequestType %x\n",agRequestType));
492 break;
493 }
494 }
495 }
496
498
499 /* return */
500 return ret;
501}
502
503/******************************************************************************/
516/*******************************************************************************/
518 agsaRoot_t *agRoot,
519 agsaIORequest_t *agIORequest,
520 bit32 queueNum,
521 agsaDevHandle_t *agDevHandle,
522 bit32 flag,
523 void *abortParam,
525 )
526{
528 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
529 agsaIORequestDesc_t *pRequest;
530 agsaIORequestDesc_t *pRequestABT = NULL;
531 agsaIORequest_t *agIOToBeAborted;
532 agsaDeviceDesc_t *pDevice;
533 agsaSMPAbortCmd_t payload;
534 bit32 using_reserved = agFALSE;
535
537
538 /* sanity check */
539 SA_ASSERT((agNULL != agRoot), "");
540 SA_ASSERT((agNULL != agIORequest), "");
541 SA_ASSERT((agNULL != agDevHandle), "");
542
543 SA_DBG3(("saSMPAbort: Aborting request %p\n", agIORequest));
544
545 if( ABORT_SINGLE == (flag & ABORT_MASK) )
546 {
547 agIOToBeAborted = (agsaIORequest_t *)abortParam;
548 /* Get LL IORequest entry for saSMPAbort() */
549 pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
550 if (agNULL == pRequestABT)
551 {
552 /* The IO to Be Abort is no longer exist - can not Abort */
553 SA_DBG1(("saSMPAbort: pRequestABT AGSA_RC_FAILURE\n"));
555 return AGSA_RC_FAILURE;
556 }
557
558 /* Find the device the request Abort to */
559 pDevice = pRequestABT->pDevice;
560
561 if (agNULL == pDevice)
562 {
563 /* no deviceID - can not build IOMB */
564 SA_DBG1(("saSMPAbort: pDevice AGSA_RC_FAILURE\n"));
566 return AGSA_RC_FAILURE;
567 }
568 }
569 else
570 {
571 if (ABORT_ALL == (flag & ABORT_MASK))
572 {
573 /* abort All with Device or Port */
574 /* Find the outgoing port for the device */
575 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
576 if (agNULL == pDevice)
577 {
578 /* no deviceID - can not build IOMB */
579 SA_DBG1(("saSMPAbort:ABORT_ALL pDevice AGSA_RC_FAILURE\n"));
581 return AGSA_RC_FAILURE;
582 }
583 }
584 else
585 {
586 /* only support 00 and 01 for flag */
587 SA_DBG1(("saSMPAbort:flag AGSA_RC_FAILURE\n"));
589 return AGSA_RC_FAILURE;
590 }
591 }
592
593 /* Get LL IORequest entry */
595 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
596
597 /* If no LL IO request entry available */
598 if ( agNULL == pRequest )
599 {
601 /* If no LL Control request entry available */
602 if(agNULL != pRequest)
603 {
604 using_reserved = agTRUE;
605 SA_DBG1(("saSMPAbort, using saRoot->freeReservedRequests\n"));
606 }
607 else
608 {
610 SA_DBG1(("saSMPAbort, No request from free list Not using saRoot->freeReservedRequests\n"));
612 return AGSA_RC_BUSY;
613 }
614 }
615
616 /* If free IOMB avaliable */
617 /* Remove the request from free list */
618 if( using_reserved )
619 {
620 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
621 }
622 else
623 {
624 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
625 }
626
627 /* Add the request to the pendingSMPRequests list of the device */
628 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
629 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
630 pRequest->valid = agTRUE;
632 /* set up pRequest */
633 pRequest->pIORequestContext = agIORequest;
634 pRequest->requestType = AGSA_SMP_REQTYPE;
635 pRequest->completionCB = (void*)agCB;
636 pRequest->pDevice = pDevice;
637 pRequest->startTick = saRoot->timeTick;
638
639 /* Set request to the sdkData of agIORequest */
640 agIORequest->sdkData = pRequest;
641
642 /* save tag to IOMap */
643 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
644 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
645
646 /* setup payload */
647 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, tag), pRequest->HTag);
648
649 if( ABORT_SINGLE == (flag & ABORT_MASK) )
650 {
651 if (agNULL == pRequestABT)
652 {
653 /* remove the request from IOMap */
654 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
655 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
656 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
657 /* Delete the request from the pendingSMPRequests */
659 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
660 /* return the request to free pool */
662 {
663 SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest));
664 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
665 }
666 else
667 {
668 /* return the request to free pool */
669 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
670 }
672 SA_DBG1(("saSMPAbort, agNULL == pRequestABT\n"));
673 /* The IO to Be Abort is no longer exist - can not Abort */
675 return AGSA_RC_FAILURE;
676 }
677 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), pRequestABT->HTag);
678 }
679 else
680 {
681 /* abort all */
682 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), 0);
683 }
684 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
685 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, Scp), flag);
686
687 SA_DBG1(("saSMPAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload.tag, payload.HTagAbort, payload.deviceId));
688
689 /* build IOMB command and send to SPC */
690 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SMP_ABORT, IOMB_SIZE64, queueNum);
691 if (AGSA_RC_SUCCESS != ret)
692 {
693 /* remove the request from IOMap */
694 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
695 saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
696 saRoot->IOMap[pRequest->HTag].agContext = agNULL;
697 /* Delete the request from the pendingSMPRequests */
699 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
700 /* return the request to free pool */
702 {
703 SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest));
704 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
705 }
706 else
707 {
708 /* return the request to free pool */
709 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
710 }
712 SA_DBG1(("saSMPAbort, sending IOMB failed\n" ));
713 }
714#ifdef SALL_API_TEST
715 else
716 {
717 saRoot->LLCounters.IOCounter.numSMPAborted++;
718 }
719#endif
720
722
723 return ret;
724}
725
726
727
GLOBAL FORCEINLINE bit32 mpiMsgFreeGet(mpiICQueue_t *circularQ, bit16 messageSize, void **messagePtr)
Retrieves a free message buffer from an inbound queue.
Definition: mpi.c:228
#define MPI_OB_SHIFT
Definition: mpi.h:55
#define MPI_OB_NUM_MASK
Definition: mpi.h:54
#define MPI_IB_NUM_MASK
Definition: mpi.h:53
@ MPI_CATEGORY_SAS_SATA
Definition: mpi.h:80
#define smTraceFuncEnter(L, I)
Definition: mpidebug.h:238
#define smTraceFuncExit(L, S, I)
Definition: mpidebug.h:239
#define hpDBG_VERY_LOUD
Definition: mpidebug.h:100
#define NULL
Definition: ostypes.h:142
#define agNULL
Definition: ostypes.h:151
#define GLOBAL
Definition: ostypes.h:131
unsigned int bit32
Definition: ostypes.h:99
#define agFALSE
Definition: ostypes.h:150
#define agTRUE
Definition: ostypes.h:149
unsigned char bit8
Definition: ostypes.h:97
#define SA_RESERVED_REQUEST_COUNT
Definition: sa.h:3597
void(* ossaSMPCompletedCB_t)(agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, agsaFrameHandle_t agFrameHandle)
Callback definition for.
Definition: sa.h:3530
#define smpFrameFlagIndirectResponse
Definition: sa.h:3095
#define AGSA_RC_BUSY
Definition: sa.h:782
#define AGSA_SMP_REQTYPE
Definition: sa.h:888
#define OSSA_OFFSET_OF(STRUCT_TYPE, FEILD)
Definition: sa.h:39
#define AGSA_MAX_SMPPAYLOAD_VIA_SFO
Definition: sa.h:1129
void(* ossaGenericAbortCB_t)(agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 flag, bit32 status)
Callback definition for abort SMP SSP SATA callback.
Definition: sa.h:3496
void(* ossaSSPCompletedCB_t)(agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit16 sspTag, bit32 agOtherInfo)
Callback definition for.
Definition: sa.h:3542
#define AGSA_MAX_INBOUND_Q
Definition: sa.h:827
#define AGSA_SMP_INIT_REQ
Definition: sa.h:994
#define AGSA_RC_FAILURE
Definition: sa.h:781
#define smpFrameFlagIndirectPayload
Definition: sa.h:3097
#define AGSA_RC_SUCCESS
Definition: sa.h:780
#define IOMB_SIZE64
Definition: sadefs.h:60
#define LL_IOREQ_LOCKEQ_LOCK
Definition: sadefs.h:130
#define ABORT_ALL
Definition: sadefs.h:238
#define ABORT_SINGLE
Definition: sadefs.h:236
#define ABORT_MASK
Definition: sadefs.h:235
#define MARK_OFF
Definition: sadefs.h:185
#define LL_IOREQ_IBQ0_LOCK
Definition: sadefs.h:154
#define SHIFT16
Definition: sadefs.h:217
This file defines global types.
#define saLlistIOAdd(pList, pLink)
Definition: sallist.h:185
#define saLlistIORemove(pList, pLink)
Definition: sallist.h:275
#define saLlistIOGetHead(pList)
Definition: sallist.h:307
#define saLlistIOGetCount(pList)
Definition: sallist.h:361
#define SA_DBG4(format)
Definition: samacro.h:203
#define SA_DBG1(format)
Definition: samacro.h:200
#define SA_DBG2(format)
Definition: samacro.h:201
#define SA_ASSERT
Definition: samacro.h:209
#define SA_DBG3(format)
Definition: samacro.h:202
GLOBAL bit32 mpiBuildCmd(agsaRoot_t *agRoot, bit32 *payload, mpiMsgCategory_t category, bit16 opcode, bit16 size, bit32 queueNum)
Build a IOMB command and send to SPC.
Definition: sampicmd.c:94
GLOBAL bit32 mpiSMPCmd(agsaRoot_t *agRoot, void *pIomb, bit16 opcode, agsaSMPCmd_t *payload, bit8 inq, bit8 outq)
SPC MPI SMP Request Command.
Definition: sampicmd.c:901
#define DIRECT_MODE
Definition: sampidefs.h:791
#define OPC_INB_SMP_ABORT
Definition: sampidefs.h:52
#define OPC_INB_SMP_REQUEST
Definition: sampidefs.h:50
#define INDIRECT_MODE
Definition: sampidefs.h:792
GLOBAL FORCEINLINE void ossaSingleThreadedEnter(agsaRoot_t *agRoot, bit32 syncLockId)
ossaSingleThreadedEnter
Definition: ossacmnapi.c:3786
GLOBAL FORCEINLINE void ossaSingleThreadedLeave(agsaRoot_t *agRoot, bit32 syncLockId)
ossaSingleThreadedLeave
Definition: ossacmnapi.c:3827
GLOBAL FORCEINLINE void * si_memcpy(void *dst, void *src, bit32 count)
memcopy
Definition: sautil.c:76
GLOBAL bit32 smIS_SPC(agsaRoot_t *agRoot)
Definition: sautil.c:437
GLOBAL FORCEINLINE void * si_memset(void *s, int c, bit32 n)
memset
Definition: sautil.c:104
GLOBAL bit32 saSMPAbort(agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 queueNum, agsaDevHandle_t *agDevHandle, bit32 flag, void *abortParam, ossaGenericAbortCB_t agCB)
Abort SMP request.
Definition: sasmp.c:517
GLOBAL bit32 saSMPStart(agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 queueNum, agsaDevHandle_t *agDevHandle, bit32 agRequestType, agsaSASRequestBody_t *agRequestBody, ossaSMPCompletedCB_t agCB)
Start SMP request.
Definition: sasmp.c:62
__FBSDID("$FreeBSD$")
data structure stores OS specific and LL specific context
Definition: sa.h:1658
void * sdkData
Definition: sa.h:1660
the LL defined device descriptor
Definition: satypes.h:112
agsaPort_t * pPort
Definition: satypes.h:117
bit32 DeviceMapIndex
Definition: satypes.h:123
SALINK_LIST pendingIORequests
Definition: satypes.h:116
agsaIORequestDesc_t * IORequest
Definition: satypes.h:171
bit32 Tag
Definition: satypes.h:170
agsaContext_t * agContext
Definition: satypes.h:172
the LL defined IO request descriptor
Definition: satypes.h:132
agsaPort_t * pPort
Definition: satypes.h:136
agsaIORequest_t * pIORequestContext
Definition: satypes.h:134
ossaSSPCompletedCB_t completionCB
Definition: satypes.h:137
agsaDeviceDesc_t * pDevice
Definition: satypes.h:135
the LLRoot
Definition: satypes.h:209
SALINK_LIST freeIORequests
Definition: satypes.h:214
SALINK_LIST freeReservedRequests
Definition: satypes.h:215
agsaIOMap_t IOMap[MAX_ACTIVE_IO_REQUESTS]
Definition: satypes.h:246
bit32 timeTick
Definition: satypes.h:234
mpiICQueue_t inboundQueue[AGSA_MAX_INBOUND_Q]
Definition: satypes.h:257
the port
Definition: satypes.h:64
bit32 portId
Definition: satypes.h:71
the data structure of SMP Abort Command
Definition: sampidefs.h:417
the data structure of SMP Request Command
Definition: sampidefs.h:376
bit32 SMPCmd[12]
Definition: sampidefs.h:385
data structure describes a SMP request or response frame to be sent on the SAS port
Definition: sa.h:3057
bit32 inFrameAddrLower32
Definition: sa.h:3070
bit32 inFrameLen
Definition: sa.h:3072
bit32 flag
Definition: sa.h:3075
void * outFrameBuf
Definition: sa.h:3058
bit32 inFrameAddrUpper32
Definition: sa.h:3068
bit32 outFrameAddrLower32
Definition: sa.h:3064
bit32 expectedRespLen
Definition: sa.h:3074
bit32 outFrameLen
Definition: sa.h:3066
bit32 outFrameAddrUpper32
Definition: sa.h:3062
Circular Queue descriptor.
Definition: mpi.h:178
union data structure specifies a request
Definition: sa.h:3104
agsaSMPFrame_t smpFrame
Definition: sa.h:3111