1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ********************************************************************************/
22 /*******************************************************************************/
24 * \brief The file implements the functions to SATA IO
27 /******************************************************************************/
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 #include <dev/pms/config.h>
32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
37 #define siTraceFileID 'M'
40 /******************************************************************************/
41 /*! \brief Start SATA command
45 * \param agRoot handles for this instance of SAS/SATA hardware
49 * \param agRequestType
54 * \return If command is started successfully
55 * - \e AGSA_RC_SUCCESS command is started successfully
56 * - \e AGSA_RC_FAILURE command is not started successfully
58 /*******************************************************************************/
59 GLOBAL bit32 saSATAStart(
61 agsaIORequest_t *agIORequest,
63 agsaDevHandle_t *agDevHandle,
65 agsaSATAInitiatorRequest_t *agSATAReq,
67 ossaSATACompletedCB_t agCB
71 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
72 mpiICQueue_t *circularQ = agNULL;
73 agsaDeviceDesc_t *pDevice = agNULL;
74 agsaPort_t *pPort = agNULL;
75 agsaIORequestDesc_t *pRequest = agNULL;
76 void *pMessage = agNULL;
77 agsaSgl_t *pSgl = agNULL;
78 bit32 *payload = agNULL;
79 bit32 deviceIndex = 0;
80 bit32 ret = AGSA_RC_SUCCESS, retVal = 0;
82 bit32 encryptFlags = 0;
85 bit8 inq = 0, outq = 0;
87 OSSA_INP_ENTER(agRoot);
88 smTraceFuncEnter(hpDBG_VERY_LOUD, "8a");
90 SA_DBG3(("saSATAStart: in\n"));
92 SA_ASSERT((agNULL != agRoot), "(saSATAStart) agRoot is NULL");
93 SA_ASSERT((agNULL != agIORequest), "(saSATAStart) agIORequest is NULL");
94 SA_ASSERT((agNULL != agDevHandle), "(saSATAStart) agDevHandle is NULL");
95 SA_ASSERT((agNULL != agSATAReq), "(saSATAStart) agSATAReq is NULL");
97 /* Assign inbound and outbound queue */
98 inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
99 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
100 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
102 /* Find the outgoing port for the device */
103 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
104 SA_ASSERT((agNULL != pDevice), "(saSATAStart) pDevice is NULL");
106 pPort = pDevice->pPort;
107 SA_ASSERT((agNULL != pPort), "(saSATAStart) pPort is NULL");
109 /* SATA DIF is obsolete */
110 if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
112 return AGSA_RC_FAILURE;
115 /* find deviceID for IOMB */
116 deviceIndex = pDevice->DeviceMapIndex;
118 /* Get request from free IORequests */
119 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
120 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
121 if ( agNULL != pRequest )
123 /* If free IOMB avaliable */
124 /* Remove the request from free list */
125 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
127 /* Add the request to the pendingSTARequests list of the device */
128 pRequest->valid = agTRUE;
129 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
130 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
132 if ((agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) ||
133 (agSATAReq->option & AGSA_SATA_ENABLE_DIF))
135 opCode = OPC_INB_SATA_DIF_ENC_OPSTART;
140 opCode = OPC_INB_SATA_HOST_OPSTART;
141 if (agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
142 agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
143 agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT)
148 /* If LL IO request entry avaliable */
149 /* set up pRequest */
150 pRequest->pIORequestContext = agIORequest;
151 pRequest->pDevice = pDevice;
152 pRequest->pPort = pPort;
153 pRequest->requestType = agRequestType;
154 pRequest->startTick = saRoot->timeTick;
155 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
156 /* Set request to the sdkData of agIORequest */
157 agIORequest->sdkData = pRequest;
159 /* save tag and IOrequest pointer to IOMap */
160 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
161 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
163 #ifdef SA_LL_IBQ_PROTECT
164 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
165 #endif /* SA_LL_IBQ_PROTECT */
167 /* get a free inbound queue entry */
168 circularQ = &saRoot->inboundQueue[inq];
169 retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
171 if (AGSA_RC_FAILURE == retVal)
173 #ifdef SA_LL_IBQ_PROTECT
174 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
175 #endif /* SA_LL_IBQ_PROTECT */
176 /* if not sending return to free list rare */
177 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
178 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
179 pRequest->valid = agFALSE;
180 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
181 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
183 SA_DBG3(("saSATAStart, error when get free IOMB\n"));
184 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8a");
185 ret = AGSA_RC_FAILURE;
189 /* return busy if inbound queue is full */
190 if (AGSA_RC_BUSY == retVal)
192 #ifdef SA_LL_IBQ_PROTECT
193 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
194 #endif /* SA_LL_IBQ_PROTECT */
195 /* if not sending return to free list rare */
196 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
197 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
198 pRequest->valid = agFALSE;
199 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
200 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
202 SA_DBG1(("saSATAStart, no more IOMB\n"));
203 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8a");
209 else /* If no LL IO request entry available */
211 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
212 SA_DBG1(("saSATAStart, No request from free list\n"));
213 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8a");
218 payload = (bit32 *)pMessage;
219 SA_DBG4(("saSATAStart: Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
222 switch ( agRequestType )
224 case AGSA_SATA_PROTOCOL_FPDMA_READ:
225 case AGSA_SATA_PROTOCOL_FPDMA_WRITE:
226 case AGSA_SATA_PROTOCOL_FPDMA_READ_M:
227 case AGSA_SATA_PROTOCOL_FPDMA_WRITE_M:
228 pSgl = &(agSATAReq->agSgl);
229 AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
230 if (agRequestType & AGSA_MSG)
233 AtapDir |= AGSA_MSG_BIT;
236 case AGSA_SATA_PROTOCOL_DMA_READ:
237 case AGSA_SATA_PROTOCOL_DMA_WRITE:
238 case AGSA_SATA_PROTOCOL_DMA_READ_M:
239 case AGSA_SATA_PROTOCOL_DMA_WRITE_M:
240 case AGSA_SATA_PROTOCOL_PIO_READ_M:
241 case AGSA_SATA_PROTOCOL_PIO_WRITE_M:
242 case AGSA_SATA_PROTOCOL_PIO_READ:
243 case AGSA_SATA_PROTOCOL_PIO_WRITE:
244 case AGSA_SATA_PROTOCOL_H2D_PKT:
245 case AGSA_SATA_PROTOCOL_D2H_PKT:
246 agTag = 0; /* agTag not valid for these requests */
247 pSgl = &(agSATAReq->agSgl);
248 AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
249 if (agRequestType & AGSA_MSG)
252 AtapDir |= AGSA_MSG_BIT;
256 case AGSA_SATA_PROTOCOL_NON_DATA:
257 case AGSA_SATA_PROTOCOL_NON_DATA_M:
258 case AGSA_SATA_PROTOCOL_NON_PKT:
259 agTag = 0; /* agTag not valid for these requests */
260 AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
261 if (agRequestType & AGSA_MSG)
264 AtapDir |= AGSA_MSG_BIT;
268 case AGSA_SATA_PROTOCOL_SRST_ASSERT:
269 agTag = 0; /* agTag not valid for these requests */
270 AtapDir = AGSA_SATA_ATAP_SRST_ASSERT;
273 case AGSA_SATA_PROTOCOL_SRST_DEASSERT:
274 agTag = 0; /* agTag not valid for these requests */
275 AtapDir = AGSA_SATA_ATAP_SRST_DEASSERT;
278 case AGSA_SATA_PROTOCOL_DEV_RESET:
279 case AGSA_SATA_PROTOCOL_DEV_RESET_M: /* TestBase */
280 agTag = 0; /* agTag not valid for these requests */
281 AtapDir = AGSA_SATA_ATAP_PKT_DEVRESET;
282 if (agRequestType & AGSA_MSG)
285 AtapDir |= AGSA_MSG_BIT; /* TestBase */
290 SA_DBG1(("saSATAStart: (Unknown agRequestType) 0x%X \n",agRequestType));
291 SA_ASSERT((0), "saSATAStart: (Unknown agRequestType)");
296 if ((AGSA_SATA_PROTOCOL_SRST_ASSERT == agRequestType) ||
297 (AGSA_SATA_PROTOCOL_SRST_DEASSERT == agRequestType) ||
298 (AGSA_SATA_PROTOCOL_DEV_RESET == agRequestType))
301 SA_DBG3(("saSATAStart:AGSA_SATA_PROTOCOL_SRST_DEASSERT AGSA_SATA_PROTOCOL_SRST_ASSERT\n"));
303 si_memset((void *)payload, 0, sizeof(agsaSATAStartCmd_t));
304 /* build IOMB DW 1 */
305 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
307 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
309 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), 0 );
311 OSSA_WRITE_LE_32(agRoot,
313 OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
314 (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
318 si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
322 /* build IOMB DW 1 */
323 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
325 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
327 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), agSATAReq->dataLength );
329 /* Since we are writing the payload in order, check for any special modes now. */
330 if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
332 SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
333 SA_DBG4(("saSATAStart: 1 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
334 AtapDir |= AGSA_ENCRYPT_BIT;
337 if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
339 SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
340 AtapDir |= AGSA_DIF_BIT;
342 #ifdef CCBUILD_TEST_EPL
343 if(agSATAReq->encrypt.enableEncryptionPerLA)
344 AtapDir |= (1 << SHIFT4); // enable EPL
347 OSSA_WRITE_LE_32(agRoot,
349 OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
350 (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
354 /* DWORD 5 6 7 8 9 */
355 si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
356 /* DWORD 10 reserved */
357 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved1 ), 0 );
359 /* DWORD 11 reserved */
360 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved2 ), 0 );
362 SA_DBG4(("saSATAStart: 2 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
364 if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
366 /* Write 10 dwords of zeroes as payload, skipping all DIF fields */
367 SA_DBG4(("saSATAStart: 2a Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
368 if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
371 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EPL_DESCL ),0 );
373 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,resSKIPBYTES ),0 );
375 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_DPL_DESCL_NDPLR ),0 );
377 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
379 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_flags ),0 );
381 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udt ),0 );
383 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementLo ),0 );
385 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementHi ),0 );
387 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_seed ),0 );
390 if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
392 SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
394 SA_DBG4(("saSATAStart: 3 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
395 /* Configure DWORD 20 */
398 if (agSATAReq->encrypt.keyTagCheck == agTRUE)
400 encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
403 if( agSATAReq->encrypt.cipherMode == agsaEncryptCipherModeXTS )
405 encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
408 encryptFlags |= agSATAReq->encrypt.dekInfo.dekTable << SHIFT2;
410 encryptFlags |= (agSATAReq->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
411 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsLo ),encryptFlags );
413 /* Configure DWORD 21*/
414 /* This information is available in the sectorSizeIndex */
415 encryptFlags = agSATAReq->encrypt.sectorSizeIndex;
417 * Set Region0 sectors count
419 if(agSATAReq->encrypt.enableEncryptionPerLA)
421 encryptFlags |= (agSATAReq->encrypt.EncryptionPerLRegion0SecCount << SHIFT16);
424 encryptFlags |= (agSATAReq->encrypt.kekIndex) << SHIFT5;
425 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsHi ),encryptFlags );
427 /* Configure DWORD 22*/
428 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), agSATAReq->encrypt.keyTag_W0 );
429 /* Configure DWORD 23 */
430 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), agSATAReq->encrypt.keyTag_W1 );
431 /* Configure DWORD 24 */
432 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), agSATAReq->encrypt.tweakVal_W0 );
433 /* Configure DWORD 25 */
434 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), agSATAReq->encrypt.tweakVal_W1 );
435 /* Configure DWORD 26 */
436 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), agSATAReq->encrypt.tweakVal_W2 );
437 /* Configure DWORD 27 */
438 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), agSATAReq->encrypt.tweakVal_W3 );
442 /* Write 8 dwords of zeros as payload, skipping all encryption fields */
443 if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
445 /* Configure DWORD 22*/
446 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), 0 );
447 /* Configure DWORD 23 */
448 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), 0 );
449 /* Configure DWORD 24 */
450 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), 0 );
451 /* Configure DWORD 25 */
452 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), 0 );
453 /* Configure DWORD 26 */
454 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), 0 );
455 /* Configure DWORD 27 */
456 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), 0 );
460 SA_DBG4(("saSATAStart: 4 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
463 if(agSATAReq->encrypt.enableEncryptionPerLA)
466 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),
467 agSATAReq->encrypt.EncryptionPerLAAddrLo);
469 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
471 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EDPL_DESCH),
472 agSATAReq->encrypt.EncryptionPerLAAddrHi);
477 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),0);
479 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
481 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
484 /* Configure DWORD 28 for encryption*/
487 /* Configure DWORD 28 */
488 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), pSgl->sgLower );
489 /* Configure DWORD 29 */
490 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), pSgl->sgUpper );
491 /* Configure DWORD 30 */
492 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), pSgl->len );
493 /* Configure DWORD 31 */
494 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), pSgl->extReserved );
498 /* Configure DWORD 28 */
499 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), 0 );
500 /* Configure DWORD 29 */
501 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), 0 );
502 /* Configure DWORD 30 */
503 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), 0 );
504 /* Configure DWORD 31 */
505 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), 0 );
511 SA_ASSERT((opCode == OPC_INB_SATA_HOST_OPSTART), "opcode");
514 /* Configure DWORD 12 */
515 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), pSgl->sgLower );
516 /* Configure DWORD 13 */
517 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), pSgl->sgUpper );
518 /* Configure DWORD 14 */
519 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), pSgl->len );
520 /* Configure DWORD 15 */
521 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), pSgl->extReserved );
525 /* Configure DWORD 12 */
526 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), 0 );
527 /* Configure DWORD 13 */
528 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), 0 );
529 /* Configure DWORD 14 */
530 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), 0 );
531 /* Configure DWORD 15 */
532 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), 0 );
534 /* support ATAPI packet command */
535 if ((agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
536 agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
537 agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT))
539 /*DWORD 16 - 19 as SCSI CDB for support ATAPI Packet command*/
540 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB ),
541 (bit32)(agSATAReq->scsiCDB[0]|(agSATAReq->scsiCDB[1]<<8)|(agSATAReq->scsiCDB[2]<<16)|(agSATAReq->scsiCDB[3]<<24)));
542 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 4,
543 (bit32)(agSATAReq->scsiCDB[4]|(agSATAReq->scsiCDB[5]<<8)|(agSATAReq->scsiCDB[6]<<16)|(agSATAReq->scsiCDB[7]<<24)));
544 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 8,
545 (bit32)(agSATAReq->scsiCDB[8]|(agSATAReq->scsiCDB[9]<<8)|(agSATAReq->scsiCDB[10]<<16)|(agSATAReq->scsiCDB[11]<<24)));
546 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 12,
547 (bit32)(agSATAReq->scsiCDB[12]|(agSATAReq->scsiCDB[13]<<8)|(agSATAReq->scsiCDB[14]<<16)|(agSATAReq->scsiCDB[15]<<24)));
551 /* send IOMB to SPC */
552 ret = mpiMsgProduce(circularQ,
554 MPI_CATEGORY_SAS_SATA,
557 (bit8)circularQ->priority);
559 #ifdef SA_LL_IBQ_PROTECT
560 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
561 #endif /* SA_LL_IBQ_PROTECT */
564 if (AGSA_RC_FAILURE != ret)
566 saRoot->LLCounters.IOCounter.numSataStarted++;
570 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8a");
573 OSSA_INP_LEAVE(agRoot);
577 /******************************************************************************/
578 /*! \brief Abort SATA command
582 * \param agRoot handles for this instance of SAS/SATA hardware
583 * \param queueNum inbound/outbound queue number
584 * \param agIORequest the IO Request descriptor
585 * \param agIOtoBeAborted
587 * \return If command is aborted successfully
588 * - \e AGSA_RC_SUCCESS command is aborted successfully
589 * - \e AGSA_RC_FAILURE command is not aborted successfully
591 /*******************************************************************************/
592 GLOBAL bit32 saSATAAbort(
594 agsaIORequest_t *agIORequest,
596 agsaDevHandle_t *agDevHandle,
599 ossaGenericAbortCB_t agCB
602 bit32 ret = AGSA_RC_SUCCESS, retVal;
603 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
604 agsaIORequestDesc_t *pRequest;
605 agsaIORequestDesc_t *pRequestABT = agNULL;
606 agsaDeviceDesc_t *pDevice = agNULL;
607 agsaDeviceDesc_t *pDeviceABT = NULL;
608 agsaPort_t *pPort = agNULL;
609 mpiICQueue_t *circularQ;
611 agsaSATAAbortCmd_t *payload;
612 agsaIORequest_t *agIOToBeAborted;
614 bit32 flag_copy = flag;
617 smTraceFuncEnter(hpDBG_VERY_LOUD,"8b");
620 SA_ASSERT((agNULL != agRoot), "");
621 SA_ASSERT((agNULL != agIORequest), "");
623 SA_DBG3(("saSATAAbort: Aborting request %p ITtoBeAborted %p\n", agIORequest, abortParam));
625 /* Assign inbound and outbound Ring Buffer */
626 inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
627 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
628 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
630 if( ABORT_SINGLE == (flag & ABORT_MASK) )
632 agIOToBeAborted = (agsaIORequest_t *)abortParam;
633 /* Get LL IORequest entry for saSATAAbort() */
634 pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
635 if (agNULL == pRequest)
637 /* no pRequest found - can not Abort */
638 SA_DBG1(("saSATAAbort: pRequest AGSA_RC_FAILURE\n"));
639 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8b");
640 return AGSA_RC_FAILURE;
642 /* Find the device the request sent to */
643 pDevice = pRequest->pDevice;
644 /* Get LL IORequest entry */
645 pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
646 /* Find the device the request sent to */
647 if (agNULL == pRequestABT)
649 /* no pRequestABT - can not find pDeviceABT */
650 SA_DBG1(("saSATAAbort: pRequestABT AGSA_RC_FAILURE\n"));
651 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8b");
652 return AGSA_RC_FAILURE;
654 pDeviceABT = pRequestABT->pDevice;
656 if (agNULL == pDeviceABT)
658 /* no deviceID - can not build IOMB */
659 SA_DBG1(("saSATAAbort: pDeviceABT AGSA_RC_FAILURE\n"));
661 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8b");
662 return AGSA_RC_FAILURE;
665 if (agNULL != pDevice)
667 /* Find the port the request was sent to */
668 pPort = pDevice->pPort;
671 /* Get request from free IORequests */
672 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
673 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
677 if (ABORT_ALL == (flag & ABORT_MASK))
680 /* Find the outgoing port for the device */
681 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
682 pPort = pDevice->pPort;
683 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
684 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
688 /* only support 00 and 01 for flag */
689 SA_DBG1(("saSATAAbort: flag AGSA_RC_FAILURE\n"));
690 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8b");
691 return AGSA_RC_FAILURE;
695 /* If no LL IO request entry avalable */
696 if ( agNULL == pRequest )
698 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
699 SA_DBG1(("saSATAAbort, No request from free list\n" ));
700 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "8b");
704 /* If free IOMB avaliable */
705 /* Remove the request from free list */
706 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
708 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
709 /* Add the request to the pendingIORequests list of the device */
710 pRequest->valid = agTRUE;
711 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
712 /* set up pRequest */
714 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
716 pRequest->pIORequestContext = agIORequest;
717 pRequest->requestType = AGSA_SATA_REQTYPE;
718 pRequest->pDevice = pDevice;
719 pRequest->pPort = pPort;
720 pRequest->completionCB = (void*)agCB;
721 /* pRequest->abortCompletionCB = agCB; */
722 pRequest->startTick = saRoot->timeTick;
724 /* Set request to the sdkData of agIORequest */
725 agIORequest->sdkData = pRequest;
727 /* save tag and IOrequest pointer to IOMap */
728 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
729 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
731 #ifdef SA_LL_IBQ_PROTECT
732 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
733 #endif /* SA_LL_IBQ_PROTECT */
735 /* If LL IO request entry avaliable */
736 /* Get a free inbound queue entry */
737 circularQ = &saRoot->inboundQueue[inq];
738 retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
740 /* if message size is too large return failure */
741 if (AGSA_RC_FAILURE == retVal)
743 #ifdef SA_LL_IBQ_PROTECT
744 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
745 #endif /* SA_LL_IBQ_PROTECT */
747 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
748 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
749 pRequest->valid = agFALSE;
750 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
751 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
753 SA_DBG1(("saSATAAbort, error when get free IOMB\n"));
754 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "8b");
755 return AGSA_RC_FAILURE;
758 /* return busy if inbound queue is full */
759 if (AGSA_RC_BUSY == retVal)
761 #ifdef SA_LL_IBQ_PROTECT
762 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
763 #endif /* SA_LL_IBQ_PROTECT */
765 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
766 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
767 pRequest->valid = agFALSE;
768 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
769 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
771 SA_DBG1(("saSATASAbort, no more IOMB\n"));
772 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "8b");
778 payload = (agsaSATAAbortCmd_t*)pMessage;
779 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, tag), pRequest->HTag);
781 if( ABORT_SINGLE == (flag & ABORT_MASK) )
784 if ( agNULL == pDeviceABT )
786 #ifdef SA_LL_IBQ_PROTECT
787 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
788 #endif /* SA_LL_IBQ_PROTECT */
790 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
791 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
792 pRequest->valid = agFALSE;
793 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
794 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
796 SA_DBG1(("saSATAAbort,no device\n" ));
797 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "8b");
798 return AGSA_RC_FAILURE;
800 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
801 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), pRequestABT->HTag);
806 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
807 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), 0);
810 if(flag & ABORT_TSDK_QUARANTINE)
812 if(smIS_SPCV(agRoot))
814 flag_copy &= ABORT_SCOPE;
815 flag_copy |= ABORT_QUARANTINE_SPCV;
818 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, abortAll), flag_copy);
822 SA_DBG1(("saSATAAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId));
824 /* post the IOMB to SPC */
825 ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SATA_ABORT, outq, (bit8)circularQ->priority);
827 #ifdef SA_LL_IBQ_PROTECT
828 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
829 #endif /* SA_LL_IBQ_PROTECT */
832 if (AGSA_RC_FAILURE != ret)
834 saRoot->LLCounters.IOCounter.numSataAborted++;
838 siCountActiveIORequestsOnDevice( agRoot, payload->deviceId );
840 smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "8b");
845 /******************************************************************************/
846 /*! \brief Routine to handle for received SATA with data payload event
848 * The handle for received SATA with data payload event
850 * \param agRoot handles for this instance of SAS/SATA hardware
851 * \param pRequest the IO request descriptor
852 * \param agFirstDword pointer to the first Dword
853 * \param pResp pointer to the rest of SATA response
854 * \param lengthResp total length of SATA Response frame
858 /*******************************************************************************/
859 GLOBAL void siEventSATAResponseWtDataRcvd(
861 agsaIORequestDesc_t *pRequest,
867 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
868 agsaDeviceDesc_t *pDevice;
869 #if defined(SALLSDK_DEBUG)
870 agsaFrameHandle_t frameHandle;
871 /* get frame handle */
872 frameHandle = (agsaFrameHandle_t)(pResp);
873 #endif /* SALLSDK_DEBUG */
875 smTraceFuncEnter(hpDBG_VERY_LOUD,"8c");
877 /* If the request is still valid */
878 if ( agTRUE == pRequest->valid )
881 pDevice = pRequest->pDevice;
882 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
884 /* Delete the request from the pendingIORequests */
885 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
886 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
888 (*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot,
889 pRequest->pIORequestContext,
895 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
896 pRequest->valid = agFALSE;
897 /* return the request to free pool */
898 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
899 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
902 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8c");
907 /******************************************************************************/
908 /*! \brief copy a SATA signature to another
910 * copy a SATA signature to another
912 * \param pDstSignature pointer to the destination signature
913 * \param pSrcSignature pointer to the source signature
915 * \return If they match
917 * - \e agFALSE doesn't match
919 /*******************************************************************************/
920 GLOBAL void siSATASignatureCpy(
927 for ( i = 0; i < 5; i ++ )
929 pDstSignature[i] = pSrcSignature[i];