1285242Sachim/******************************************************************************* 2285242Sachim** 3285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4285242Sachim* 5285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided 6285242Sachim*that the following conditions are met: 7285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 8285242Sachim*following disclaimer. 9285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice, 10285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided 11285242Sachim*with the distribution. 12285242Sachim* 13285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 14285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 18285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 21285242Sachim 22285242Sachim********************************************************************************/ 23285242Sachim/*******************************************************************************/ 24285242Sachim/*! \file sassp.c 25285242Sachim * \brief The file implements the functions for SSP request/response 26285242Sachim * 27285242Sachim */ 28285242Sachim/*******************************************************************************/ 29285242Sachim#include <sys/cdefs.h> 30285242Sachim__FBSDID("$FreeBSD$"); 31285242Sachim#include <dev/pms/config.h> 32285242Sachim 33285242Sachim#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 34285242Sachim#ifdef SA_ENABLE_TRACE_FUNCTIONS 35285242Sachim#ifdef siTraceFileID 36285242Sachim#undef siTraceFileID 37285242Sachim#endif 38285242Sachim#define siTraceFileID 'O' 39285242Sachim#endif 40285242Sachim 41285242Sachim#ifdef LOOPBACK_MPI 42285242Sachimextern int loopback; 43285242Sachim#endif 44285242Sachim 45285242Sachim#ifdef SALLSDK_DEBUG 46285242SachimLOCAL void siDumpSSPStartIu( 47285242Sachim agsaDevHandle_t *agDevHandle, 48285242Sachim bit32 agRequestType, 49285242Sachim agsaSASRequestBody_t *agRequestBody 50285242Sachim ); 51285242Sachim#endif 52285242Sachim 53285242Sachim#ifdef FAST_IO_TEST 54285242SachimLOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot, 55285242Sachim bit32 queueNum) 56285242Sachim{ 57285242Sachim bit8 inq; 58285242Sachim mpiICQueue_t *circularQ; 59285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 60285242Sachim 61285242Sachim inq = INQ(queueNum); 62285242Sachim circularQ = &saRoot->inboundQueue[inq]; 63285242Sachim return circularQ->producerIdx; 64285242Sachim} 65285242Sachim 66285242SachimLOCAL void saSetIBQPI(agsaRoot_t *agRoot, 67285242Sachim bit32 queueNum, 68285242Sachim bit32 pi) 69285242Sachim{ 70285242Sachim bit8 inq; 71285242Sachim mpiICQueue_t *circularQ; 72285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 73285242Sachim 74285242Sachim inq = INQ(queueNum); 75285242Sachim circularQ = &saRoot->inboundQueue[inq]; 76285242Sachim circularQ->producerIdx = pi; 77285242Sachim} 78285242Sachim 79285242SachimosLOCAL void* 80285242SachimsiFastSSPReqAlloc(agsaRoot_t *agRoot) 81285242Sachim{ 82285242Sachim int idx; 83285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 84285242Sachim saFastRequest_t *fr; 85285242Sachim 86285242Sachim if (!saRoot->freeFastIdx) 87285242Sachim { 88285242Sachim SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n")); 89285242Sachim SA_ASSERT((0), ""); 90285242Sachim return 0; 91285242Sachim } 92285242Sachim 93285242Sachim ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 94285242Sachim saRoot->freeFastIdx--; 95285242Sachim idx = saRoot->freeFastIdx; 96285242Sachim ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 97285242Sachim 98285242Sachim fr = saRoot->freeFastReq[idx]; 99285242Sachim SA_ASSERT((fr), ""); 100285242Sachim fr->valid = 1; 101285242Sachim 102285242Sachim return fr; 103285242Sachim} 104285242Sachim 105285242SachimLOCAL void 106285242SachimsiFastSSPReqFree( 107285242Sachim agsaRoot_t *agRoot, 108285242Sachim void *freq) 109285242Sachim{ 110285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 111285242Sachim saFastRequest_t *fr = (saFastRequest_t*)freq; 112285242Sachim 113285242Sachim SA_DBG2(("siFastSSPReqFree: enter\n")); 114285242Sachim SA_ASSERT((fr->valid), ""); 115285242Sachim if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) / 116285242Sachim sizeof(saRoot->freeFastReq[0])) 117285242Sachim { 118285242Sachim SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n", 119285242Sachim saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) / 120285242Sachim sizeof(saRoot->freeFastReq[0])))); 121285242Sachim SA_ASSERT((0), ""); 122285242Sachim return; 123285242Sachim } 124285242Sachim ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 125285242Sachim /* not need if only one entry */ 126285242Sachim /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq; */ 127285242Sachim saRoot->freeFastIdx++; 128285242Sachim ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 129285242Sachim 130285242Sachim fr->valid = 0; 131285242Sachim SA_DBG6(("siFastSSPReqFree: leave\n")); 132285242Sachim} 133285242Sachim 134285242SachimLOCAL bit32 siFastSSPResAlloc( 135285242Sachim agsaRoot_t *agRoot, 136285242Sachim bit32 queueNum, 137285242Sachim bit32 agRequestType, 138285242Sachim agsaDeviceDesc_t *pDevice, 139285242Sachim agsaIORequestDesc_t **pRequest, 140285242Sachim void **pPayload 141285242Sachim ) 142285242Sachim{ 143285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 144285242Sachim mpiICQueue_t *circularQ; 145285242Sachim bit8 inq; 146285242Sachim bit16 size = IOMB_SIZE64; 147285242Sachim bit32 ret = AGSA_RC_SUCCESS, retVal; 148285242Sachim 149285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"2D"); 150285242Sachim 151285242Sachim SA_DBG4(("Entering function siFastSSPResAlloc:\n")); 152285242Sachim 153285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 154285242Sachim *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests); 155285242Sachim 156285242Sachim /* If no LL IO request entry available */ 157285242Sachim if (agNULL == *pRequest ) 158285242Sachim { 159285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 160285242Sachim SA_DBG1(("siFastSSPResAlloc: No request from free list\n" )); 161285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D"); 162285242Sachim ret = AGSA_RC_BUSY; 163285242Sachim goto ext; 164285242Sachim } 165285242Sachim 166285242Sachim /* Get IO request from free IORequests */ 167285242Sachim /* Assign inbound and outbound Buffer */ 168285242Sachim inq = INQ(queueNum); 169285242Sachim SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 170285242Sachim 171285242Sachim /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */ 172285242Sachim if (agRequestType & AGSA_SSP_EXT_BIT) 173285242Sachim { 174285242Sachim size = IOMB_SIZE96; 175285242Sachim } 176285242Sachim /* If LL IO request entry avaliable */ 177285242Sachim /* Get a free inbound queue entry */ 178285242Sachim circularQ = &saRoot->inboundQueue[inq]; 179285242Sachim retVal = mpiMsgFreeGet(circularQ, size, pPayload); 180285242Sachim 181285242Sachim /* if message size is too large return failure */ 182285242Sachim if (AGSA_RC_SUCCESS != retVal) 183285242Sachim { 184285242Sachim if (AGSA_RC_FAILURE == retVal) 185285242Sachim { 186285242Sachim SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n")); 187285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D"); 188285242Sachim } 189285242Sachim 190285242Sachim /* return busy if inbound queue is full */ 191285242Sachim if (AGSA_RC_BUSY == retVal) 192285242Sachim { 193285242Sachim SA_DBG3(("siFastSSPResAlloc: no more IOMB\n")); 194285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D"); 195285242Sachim } 196285242Sachim ret = retVal; 197285242Sachim goto ext; 198285242Sachim } 199285242Sachim 200285242Sachim /* But add it to the pending queue during FastStart */ 201285242Sachim /* If free IOMB avaliable */ 202285242Sachim /* Remove the request from free list */ 203285242Sachim saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode); 204285242Sachim 205285242Sachim /* Add the request to the pendingIORequests list of the device */ 206285242Sachim saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode); 207285242Sachim 208285242Sachimext: 209285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 210285242Sachim 211285242Sachim if (AGSA_RC_SUCCESS == ret) 212285242Sachim { 213285242Sachim /* save tag and IOrequest pointer to IOMap */ 214285242Sachim saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag; 215285242Sachim saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest; 216285242Sachim } 217285242Sachim 218285242Sachim return ret; 219285242Sachim} /* siFastSSPResAlloc */ 220285242Sachim 221285242Sachim 222285242SachimGLOBAL bit32 saFastSSPCancel(void *ioHandle) 223285242Sachim{ 224285242Sachim agsaRoot_t *agRoot; 225285242Sachim agsaLLRoot_t *saRoot; 226285242Sachim saFastRequest_t *fr; 227285242Sachim bit32 i; 228285242Sachim agsaIORequestDesc_t *ior; 229285242Sachim 230285242Sachim SA_ASSERT((ioHandle), ""); 231285242Sachim fr = (saFastRequest_t*)ioHandle; 232285242Sachim SA_ASSERT((fr->valid), ""); 233285242Sachim agRoot = (agsaRoot_t*)fr->agRoot; 234285242Sachim SA_ASSERT((agRoot), ""); 235285242Sachim saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 236285242Sachim SA_ASSERT((saRoot), ""); 237285242Sachim 238285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"2E"); 239285242Sachim 240285242Sachim /* rollback the previously set IBQ PI */ 241285242Sachim for (i = 0; i < fr->inqMax - 1; i++) 242285242Sachim saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]); 243285242Sachim 244285242Sachim /* free all the previous Fast IO Requests */ 245285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 246285242Sachim /* at least one entry, no need to check for NULL saLlistIOGetHead() */ 247285242Sachim ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) - 248285242Sachim OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 249285242Sachim do 250285242Sachim { 251285242Sachim agsaDeviceDesc_t *pDevice; 252285242Sachim void *tmp; 253285242Sachim 254285242Sachim pDevice = ior->pDevice; 255285242Sachim saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode); 256285242Sachim saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode); 257285242Sachim 258285242Sachim tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink); 259285242Sachim if (!tmp) 260285242Sachim { 261285242Sachim break; /* end of list */ 262285242Sachim } 263285242Sachim ior = (agsaIORequestDesc_t*)((char*)tmp - 264285242Sachim OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 265285242Sachim } while (1); 266285242Sachim 267285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 268285242Sachim 269285242Sachim /* free the IBQ PI tracking struct */ 270285242Sachim siFastSSPReqFree(agRoot, fr); 271285242Sachim 272285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E"); 273285242Sachim return AGSA_RC_SUCCESS; 274285242Sachim} /* saFastSSPCancel */ 275285242Sachim 276285242SachimGLOBAL void *saFastSSPPrepare( 277285242Sachim void *ioh, 278285242Sachim agsaFastCommand_t *fc, 279285242Sachim ossaSSPCompletedCB_t cb, 280285242Sachim void *cbArg) 281285242Sachim{ 282285242Sachim bit32 ret = AGSA_RC_SUCCESS; 283285242Sachim agsaRoot_t *agRoot; 284285242Sachim agsaLLRoot_t *saRoot; 285285242Sachim mpiICQueue_t *circularQ; 286285242Sachim agsaDeviceDesc_t *pDevice; 287285242Sachim agsaSgl_t *pSgl; 288285242Sachim bit32 Dir = 0; 289285242Sachim bit8 inq, outq; 290285242Sachim saFastRequest_t *fr; 291285242Sachim void *pMessage; 292285242Sachim agsaIORequestDesc_t *pRequest; 293285242Sachim bit16 opCode; 294285242Sachim bitptr offsetTag; 295285242Sachim bitptr offsetDeviceId; 296285242Sachim bitptr offsetDataLen; 297285242Sachim bitptr offsetDir; 298285242Sachim 299285242Sachim agRoot = (agsaRoot_t*)fc->agRoot; 300285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"2G"); 301285242Sachim 302285242Sachim OSSA_INP_ENTER(agRoot); 303285242Sachim 304285242Sachim saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 305285242Sachim /* sanity check */ 306285242Sachim SA_ASSERT((agNULL != saRoot), ""); 307285242Sachim 308285242Sachim SA_DBG4(("Entering function saFastSSPPrepare:\n")); 309285242Sachim 310285242Sachim fr = (saFastRequest_t*)ioh; 311285242Sachim if (!fr) 312285242Sachim { 313285242Sachim int i; 314285242Sachim fr = siFastSSPReqAlloc(agRoot); 315285242Sachim if (!fr) 316285242Sachim { 317285242Sachim SA_ASSERT((0), ""); 318285242Sachim goto ext; 319285242Sachim } 320285242Sachim 321285242Sachim saLlistIOInitialize(&fr->requests); 322285242Sachim for (i = 0; i < AGSA_MAX_INBOUND_Q; i++) 323285242Sachim fr->beforePI[i] = (bit32)-1; 324285242Sachim 325285242Sachim fr->inqMax = 0; 326285242Sachim fr->agRoot = agRoot; 327285242Sachim ioh = fr; 328285242Sachim } 329285242Sachim 330285242Sachim /* Find the outgoing port for the device */ 331285242Sachim pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData); 332285242Sachim 333285242Sachim ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType, 334285242Sachim pDevice, &pRequest, &pMessage); 335285242Sachim if (ret != AGSA_RC_SUCCESS) 336285242Sachim { 337285242Sachim SA_ASSERT((0), ""); 338285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G"); 339285242Sachim goto ext; 340285242Sachim } 341285242Sachim 342285242Sachim /* Assign inbound and outbound Buffer */ 343285242Sachim inq = INQ(fc->queueNum); 344285242Sachim outq = OUQ(fc->queueNum); 345285242Sachim circularQ = &saRoot->inboundQueue[inq]; 346285242Sachim 347285242Sachim SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex)); 348285242Sachim 349285242Sachim /* set up pRequest */ 350285242Sachim pRequest->valid = agTRUE; 351285242Sachim pRequest->pDevice = pDevice; 352285242Sachim pRequest->requestType = fc->agRequestType; 353285242Sachim 354285242Sachim pRequest->completionCB = cb; 355285242Sachim pRequest->pIORequestContext = (agsaIORequest_t*)cbArg; 356285242Sachim 357285242Sachim pSgl = fc->agSgl; 358285242Sachim 359285242Sachim switch (fc->agRequestType) 360285242Sachim { 361285242Sachim /* case AGSA_SSP_INIT_NONDATA: */ 362285242Sachim case AGSA_SSP_INIT_READ: 363285242Sachim case AGSA_SSP_INIT_WRITE: 364285242Sachim case AGSA_SSP_INIT_READ_M: 365285242Sachim case AGSA_SSP_INIT_WRITE_M: 366285242Sachim { 367285242Sachim agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 368285242Sachim agsaSSPCmdInfoUnit_t *piu; 369285242Sachim 370285242Sachim /* SSPIU less equal 28 bytes */ 371285242Sachim offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag); 372285242Sachim offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId); 373285242Sachim offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen); 374285242Sachim offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr); 375285242Sachim 376285242Sachim piu = &pPayload->SSPInfoUnit; 377285242Sachim 378285242Sachim si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 379285242Sachim si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb)); 380285242Sachim piu->efb_tp_taskAttribute = fc->taskAttribute; 381285242Sachim piu->additionalCdbLen = fc->additionalCdbLen; 382285242Sachim 383285242Sachim /* Mask DIR for Read/Write command */ 384285242Sachim Dir = fc->agRequestType & AGSA_DIR_MASK; 385285242Sachim 386285242Sachim /* set TLR */ 387285242Sachim Dir |= fc->flag & TLR_MASK; 388285242Sachim if (fc->agRequestType & AGSA_MSG) 389285242Sachim { 390285242Sachim /* set M bit */ 391285242Sachim Dir |= AGSA_MSG_BIT; 392285242Sachim } 393285242Sachim 394285242Sachim /* Setup SGL */ 395285242Sachim if (fc->dataLength) 396285242Sachim { 397285242Sachim SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n", 398285242Sachim pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 399285242Sachim /* 400285242Sachim pPayload->AddrLow0 = pSgl->sgLower; 401285242Sachim pPayload->AddrHi0 = pSgl->sgUpper; 402285242Sachim pPayload->Len0 = pSgl->len; 403285242Sachim pPayload->E0 = pSgl->extReserved; 404285242Sachim */ 405285242Sachim si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl)); 406285242Sachim } 407285242Sachim else 408285242Sachim { 409285242Sachim /* no data transfer */ 410285242Sachim si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl)); 411285242Sachim } 412285242Sachim 413285242Sachim opCode = OPC_INB_SSPINIIOSTART; 414285242Sachim break; 415285242Sachim } 416285242Sachim 417285242Sachim case AGSA_SSP_INIT_READ_EXT: 418285242Sachim case AGSA_SSP_INIT_WRITE_EXT: 419285242Sachim case AGSA_SSP_INIT_READ_EXT_M: 420285242Sachim case AGSA_SSP_INIT_WRITE_EXT_M: 421285242Sachim { 422285242Sachim agsaSSPIniExtIOStartCmd_t *pPayload = 423285242Sachim (agsaSSPIniExtIOStartCmd_t *)pMessage; 424285242Sachim agsaSSPCmdInfoUnitExt_t *piu; 425285242Sachim bit32 sspiul; 426285242Sachim 427285242Sachim /* CDB > 16 bytes */ 428285242Sachim offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag); 429285242Sachim offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId); 430285242Sachim offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen); 431285242Sachim offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr); 432285242Sachim 433285242Sachim /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 434285242Sachim /* setup standard CDB bytes + additional CDB bytes in length field */ 435285242Sachim sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC); 436285242Sachim 437285242Sachim Dir = sspiul << 16; 438285242Sachim piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu; 439285242Sachim 440285242Sachim si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 441285242Sachim si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb), 442285242Sachim 16 + fc->additionalCdbLen)); 443285242Sachim piu->efb_tp_taskAttribute = fc->taskAttribute; 444285242Sachim piu->additionalCdbLen = fc->additionalCdbLen; 445285242Sachim 446285242Sachim /* Mask DIR for Read/Write command */ 447285242Sachim Dir |= fc->agRequestType & AGSA_DIR_MASK; 448285242Sachim 449285242Sachim /* set TLR */ 450285242Sachim Dir |= fc->flag & TLR_MASK; 451285242Sachim if (fc->agRequestType & AGSA_MSG) 452285242Sachim { 453285242Sachim /* set M bit */ 454285242Sachim Dir |= AGSA_MSG_BIT; 455285242Sachim } 456285242Sachim 457285242Sachim /* Setup SGL */ 458285242Sachim if (fc->dataLength) 459285242Sachim { 460285242Sachim SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n", 461285242Sachim pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 462285242Sachim 463285242Sachim si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl)); 464285242Sachim } 465285242Sachim else //? 466285242Sachim { 467285242Sachim /* no data transfer */ 468285242Sachim //pPayload->dataLen = 0; 469285242Sachim si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl)); 470285242Sachim } 471285242Sachim SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 472285242Sachim opCode = OPC_INB_SSPINIEXTIOSTART; 473285242Sachim break; 474285242Sachim } 475285242Sachim 476285242Sachim default: 477285242Sachim { 478285242Sachim SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n")); 479285242Sachim ret = AGSA_RC_FAILURE; 480285242Sachim SA_ASSERT((0), ""); 481285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G"); 482285242Sachim goto ext; 483285242Sachim } 484285242Sachim } 485285242Sachim 486285242Sachim OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag); 487285242Sachim OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex); 488285242Sachim OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength); 489285242Sachim OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir); 490285242Sachim 491285242Sachim if (fr->beforePI[inq] == -1) 492285242Sachim { 493285242Sachim /* save the new IBQ' PI */ 494285242Sachim fr->beforePI[inq] = saGetIBQPI(agRoot, inq); 495285242Sachim fr->inqList[fr->inqMax++] = inq; 496285242Sachim } 497285242Sachim 498285242Sachim /* post the IOMB to SPC */ 499285242Sachim ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, 500285242Sachim opCode, outq, 0); 501285242Sachim if (AGSA_RC_SUCCESS != ret) 502285242Sachim { 503285242Sachim SA_ASSERT((0), ""); 504285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 505285242Sachim /* Remove the request from pendingIORequests list */ 506285242Sachim saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode); 507285242Sachim 508285242Sachim /* Add the request to the free list of the device */ 509285242Sachim saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode); 510285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 511285242Sachim 512285242Sachim SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n")); 513285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G"); 514285242Sachim goto ext; 515285242Sachim } 516285242Sachim 517285242Sachim /* Add the request to the pendingFastIORequests list of the device */ 518285242Sachim saLlistIOAdd(&fr->requests, &pRequest->fastLink); 519285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G"); 520285242Sachim 521285242Sachimext: 522285242Sachim if (fr && ret != AGSA_RC_SUCCESS) 523285242Sachim { 524285242Sachim saFastSSPCancel(fr); 525285242Sachim ioh = 0; 526285242Sachim } 527285242Sachim OSSA_INP_LEAVE(agRoot); 528285242Sachim return ioh; 529285242Sachim} /* saFastSSPPrepare */ 530285242Sachim 531285242SachimGLOBAL bit32 saFastSSPSend(void *ioHandle) 532285242Sachim{ 533285242Sachim bit8 inq; 534285242Sachim agsaRoot_t *agRoot; 535285242Sachim agsaLLRoot_t *saRoot; 536285242Sachim saFastRequest_t *fr; 537285242Sachim bit32 i; 538285242Sachim 539285242Sachim SA_ASSERT((ioHandle), ""); 540285242Sachim fr = (saFastRequest_t*)ioHandle; 541285242Sachim agRoot = (agsaRoot_t*)fr->agRoot; 542285242Sachim SA_ASSERT((agRoot), ""); 543285242Sachim saRoot = (agsaLLRoot_t*)agRoot->sdkData; 544285242Sachim SA_ASSERT((saRoot), ""); 545285242Sachim 546285242Sachim SA_DBG4(("Entering function saFastSSPSend:\n")); 547285242Sachim 548285242Sachim for (i = 0; i < fr->inqMax; i++) 549285242Sachim { 550285242Sachim inq = INQ(fr->inqList[i]); 551285242Sachim /* FW interrupt */ 552285242Sachim mpiIBQMsgSend(&saRoot->inboundQueue[inq]); 553285242Sachim } 554285242Sachim /* IORequests are freed in siIODone() */ 555285242Sachim 556285242Sachim siFastSSPReqFree(agRoot, fr); 557285242Sachim return AGSA_RC_SUCCESS; 558285242Sachim} /* saFastSSPSend */ 559285242Sachim#endif 560285242Sachim 561285242Sachim/******************************************************************************/ 562285242Sachim/*! \brief Start SSP request 563285242Sachim * 564285242Sachim * Start SSP request 565285242Sachim * 566285242Sachim * \param agRoot handles for this instance of SAS/SATA LLL 567285242Sachim * \param queueNum 568285242Sachim * \param agIORequest 569285242Sachim * \param agDevHandle 570285242Sachim * \param agRequestType 571285242Sachim * \param agRequestBody 572285242Sachim * \param agTMRequest valid for task management 573285242Sachim * \param agCB 574285242Sachim * 575285242Sachim * \return If request is started successfully 576285242Sachim * - \e AGSA_RC_SUCCESS request is started successfully 577285242Sachim * - \e AGSA_RC_BUSY request is not started successfully 578285242Sachim */ 579285242Sachim/******************************************************************************/ 580285242SachimGLOBAL bit32 saSSPStart( 581285242Sachim agsaRoot_t *agRoot, 582285242Sachim agsaIORequest_t *agIORequest, 583285242Sachim bit32 queueNum, 584285242Sachim agsaDevHandle_t *agDevHandle, 585285242Sachim bit32 agRequestType, 586285242Sachim agsaSASRequestBody_t *agRequestBody, 587285242Sachim agsaIORequest_t *agTMRequest, 588285242Sachim ossaSSPCompletedCB_t agCB) 589285242Sachim{ 590285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 591285242Sachim#ifdef LOOPBACK_MPI 592285242Sachim mpiOCQueue_t *circularOQ = agNULL; 593285242Sachim#endif 594285242Sachim mpiICQueue_t *circularQ = agNULL; 595285242Sachim agsaDeviceDesc_t *pDevice = agNULL; 596285242Sachim agsaPort_t *pPort = agNULL; 597285242Sachim agsaIORequestDesc_t *pRequest = agNULL; 598285242Sachim agsaSgl_t *pSgl = agNULL; 599285242Sachim void *pMessage = agNULL; 600285242Sachim bit32 ret = AGSA_RC_SUCCESS, retVal = 0; 601285242Sachim bit32 DirDW4 = 0; /* no data and no AutoGR */ 602285242Sachim bit32 encryptFlags = 0; 603285242Sachim bit16 size = 0; 604285242Sachim bit16 opCode = 0; 605285242Sachim bit8 inq = 0, outq = 0; 606285242Sachim 607285242Sachim 608285242Sachim OSSA_INP_ENTER(agRoot); 609285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa"); 610285242Sachim 611285242Sachim /* sanity check */ 612285242Sachim SA_ASSERT((agNULL != agRoot), ""); 613285242Sachim SA_ASSERT((agNULL != agIORequest), ""); 614285242Sachim SA_ASSERT((agNULL != agDevHandle), ""); 615285242Sachim SA_ASSERT((agNULL != agRequestBody), ""); 616285242Sachim 617285242Sachim DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody); 618285242Sachim 619285242Sachim /* Find the outgoing port for the device */ 620285242Sachim pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 621285242Sachim 622285242Sachim if(pDevice == agNULL ) 623285242Sachim { 624285242Sachim SA_ASSERT((pDevice), "pDevice"); 625285242Sachim ret = AGSA_RC_FAILURE; 626285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa"); 627285242Sachim goto ext; 628285242Sachim } 629285242Sachim 630285242Sachim pPort = pDevice->pPort; 631285242Sachim /* Assign inbound and outbound Buffer */ 632285242Sachim inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 633285242Sachim outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 634285242Sachim SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 635285242Sachim 636285242Sachim SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex)); 637285242Sachim 638285242Sachim /* Get request from free IORequests */ 639285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 640285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 641285242Sachim 642285242Sachim /* If no LL IO request entry available */ 643285242Sachim if ( agNULL == pRequest ) 644285242Sachim { 645285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 646285242Sachim SA_DBG1(("saSSPStart, No request from free list\n" )); 647285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa"); 648285242Sachim ret = AGSA_RC_BUSY; 649285242Sachim goto ext; 650285242Sachim } 651285242Sachim /* If LL IO request entry avaliable */ 652285242Sachim else 653285242Sachim { 654285242Sachim /* Remove the request from free list */ 655285242Sachim saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 656285242Sachim /* Add the request to the pendingIORequests list of the device */ 657285242Sachim saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 658285242Sachim 659285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 660285242Sachim 661285242Sachim SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 662285242Sachim 663285242Sachim SA_DBG3(("saSSPStart, request %p\n", pRequest )); 664285242Sachim 665285242Sachim /* Decode the flag settings in the standard I/O requests to decide what size we need. */ 666285242Sachim /* All other requests will be fine with only 64 byte messages. */ 667285242Sachim switch ( agRequestType ) 668285242Sachim { 669285242Sachim case AGSA_SSP_INIT_READ: 670285242Sachim case AGSA_SSP_INIT_WRITE: 671285242Sachim case AGSA_SSP_INIT_NONDATA: 672285242Sachim case AGSA_SSP_INIT_READ_M: 673285242Sachim case AGSA_SSP_INIT_WRITE_M: 674285242Sachim { 675285242Sachim agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 676285242Sachim 677285242Sachim if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 678285242Sachim#ifdef SAFLAG_USE_DIF_ENC_IOMB 679285242Sachim (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 680285242Sachim#endif /* SAFLAG_USE_DIF_ENC_IOMB */ 681285242Sachim (pIRequest->flag & AGSA_SAS_ENABLE_DIF) ) 682285242Sachim { 683285242Sachim opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 684285242Sachim size = IOMB_SIZE128; 685285242Sachim } 686285242Sachim else 687285242Sachim { 688285242Sachim opCode = OPC_INB_SSPINIIOSTART; 689285242Sachim size = IOMB_SIZE64; 690285242Sachim } 691285242Sachim break; 692285242Sachim } 693285242Sachim case AGSA_SSP_INIT_READ_EXT: 694285242Sachim case AGSA_SSP_INIT_WRITE_EXT: 695285242Sachim case AGSA_SSP_INIT_READ_EXT_M: 696285242Sachim case AGSA_SSP_INIT_WRITE_EXT_M: 697285242Sachim { 698285242Sachim agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 699285242Sachim 700285242Sachim if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 701285242Sachim (pIRequest->flag & AGSA_SAS_ENABLE_DIF) || 702285242Sachim#ifdef SAFLAG_USE_DIF_ENC_IOMB 703285242Sachim (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 704285242Sachim#endif /* SAFLAG_USE_DIF_ENC_IOMB */ 705285242Sachim (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)) 706285242Sachim { 707285242Sachim opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 708285242Sachim size = IOMB_SIZE128; 709285242Sachim } 710285242Sachim else 711285242Sachim { 712285242Sachim SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 713285242Sachim opCode = OPC_INB_SSPINIEXTIOSTART; 714285242Sachim size = IOMB_SIZE96; 715285242Sachim } 716285242Sachim break; 717285242Sachim } 718285242Sachim case AGSA_SSP_INIT_READ_INDIRECT: 719285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT: 720285242Sachim case AGSA_SSP_INIT_READ_INDIRECT_M: 721285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT_M: 722285242Sachim { 723285242Sachim SA_DBG3(("saSSPStart: agRequestType 0x%X INDIRECT\n", agRequestType)); 724285242Sachim opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 725285242Sachim size = IOMB_SIZE128; 726285242Sachim break; 727285242Sachim } 728285242Sachim case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT): 729285242Sachim case AGSA_SSP_TASK_MGNT_REQ_M: 730285242Sachim case AGSA_SSP_TGT_READ_DATA: 731285242Sachim case AGSA_SSP_TGT_READ_GOOD_RESP: 732285242Sachim case AGSA_SSP_TGT_WRITE_DATA: 733285242Sachim case AGSA_SSP_TGT_WRITE_GOOD_RESP: 734285242Sachim case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 735285242Sachim 736285242Sachim SA_DBG3(("saSSPStart: agRequestType 0x%X (was default)\n", agRequestType)); 737285242Sachim opCode = OPC_INB_SSPINIIOSTART; 738285242Sachim size = IOMB_SIZE64; 739285242Sachim break; 740285242Sachim default: 741285242Sachim SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType)); 742285242Sachim /* OpCode is not used in this case, but Linux complains if it is not initialized. */ 743285242Sachim opCode = OPC_INB_SSPINIIOSTART; 744285242Sachim size = IOMB_SIZE64; 745285242Sachim break; 746285242Sachim } 747285242Sachim 748285242Sachim /* If free IOMB avaliable, set up pRequest*/ 749285242Sachim pRequest->valid = agTRUE; 750285242Sachim pRequest->pIORequestContext = agIORequest; 751285242Sachim pRequest->pDevice = pDevice; 752285242Sachim pRequest->requestType = agRequestType; 753285242Sachim pRequest->pPort = pPort; 754285242Sachim pRequest->startTick = saRoot->timeTick; 755285242Sachim pRequest->completionCB = agCB; 756285242Sachim 757285242Sachim /* Set request to the sdkData of agIORequest */ 758285242Sachim agIORequest->sdkData = pRequest; 759285242Sachim 760285242Sachim /* save tag and IOrequest pointer to IOMap */ 761285242Sachim saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 762285242Sachim saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 763285242Sachim 764285242Sachim#ifdef SA_LL_IBQ_PROTECT 765285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 766285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 767285242Sachim 768285242Sachim /* Get a free inbound queue entry */ 769285242Sachim#ifdef LOOPBACK_MPI 770285242Sachim if (loopback) 771285242Sachim { 772285242Sachim SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag)); 773285242Sachim circularOQ = &saRoot->outboundQueue[outq]; 774285242Sachim retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage); 775285242Sachim } 776285242Sachim else 777285242Sachim#endif /* LOOPBACK_MPI */ 778285242Sachim { 779285242Sachim circularQ = &saRoot->inboundQueue[inq]; 780285242Sachim retVal = mpiMsgFreeGet(circularQ, size, &pMessage); 781285242Sachim } 782285242Sachim 783285242Sachim /* if message size is too large return failure */ 784285242Sachim if (AGSA_RC_FAILURE == retVal) 785285242Sachim { 786285242Sachim#ifdef SA_LL_IBQ_PROTECT 787285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 788285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 789285242Sachim /* if not sending return to free list rare */ 790285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 791285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 792285242Sachim pRequest->valid = agFALSE; 793285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 794285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 795285242Sachim 796285242Sachim SA_DBG1(("saSSPStart, error when get free IOMB\n")); 797285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa"); 798285242Sachim ret = AGSA_RC_FAILURE; 799285242Sachim goto ext; 800285242Sachim } 801285242Sachim 802285242Sachim /* return busy if inbound queue is full */ 803285242Sachim if (AGSA_RC_BUSY == retVal) 804285242Sachim { 805285242Sachim#ifdef SA_LL_IBQ_PROTECT 806285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 807285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 808285242Sachim /* if not sending return to free list rare */ 809285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 810285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 811285242Sachim pRequest->valid = agFALSE; 812285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 813285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 814285242Sachim 815285242Sachim SA_DBG1(("saSSPStart, no more IOMB\n")); 816285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa"); 817285242Sachim ret = AGSA_RC_BUSY; 818285242Sachim goto ext; 819285242Sachim } 820285242Sachim SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType)); 821285242Sachim 822285242Sachim switch ( agRequestType ) 823285242Sachim { 824285242Sachim case AGSA_SSP_INIT_READ: 825285242Sachim case AGSA_SSP_INIT_WRITE: 826285242Sachim case AGSA_SSP_INIT_NONDATA: 827285242Sachim case AGSA_SSP_INIT_READ_EXT: 828285242Sachim case AGSA_SSP_INIT_WRITE_EXT: 829285242Sachim case AGSA_SSP_INIT_READ_M: 830285242Sachim case AGSA_SSP_INIT_WRITE_M: 831285242Sachim case AGSA_SSP_INIT_READ_EXT_M: 832285242Sachim case AGSA_SSP_INIT_WRITE_EXT_M: 833285242Sachim case AGSA_SSP_INIT_READ_INDIRECT: 834285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT: 835285242Sachim case AGSA_SSP_INIT_READ_INDIRECT_M: 836285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT_M: 837285242Sachim { 838285242Sachim if (!(agRequestType & AGSA_SSP_EXT_BIT)) 839285242Sachim { 840285242Sachim agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 841285242Sachim agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 842285242Sachim agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage; 843285242Sachim 844285242Sachim /* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */ 845285242Sachim /* Be careful with the scatter/gather lists, encryption and DIF options. */ 846285242Sachim 847285242Sachim/* if( pIRequest->sspCmdIU.cdb[ 0] == 0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A) 848285242Sachim { 849285242Sachim pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) | 850285242Sachim (pIRequest->sspCmdIU.cdb[3] << 16 ) | 851285242Sachim (pIRequest->sspCmdIU.cdb[4] << 8 ) | 852285242Sachim (pIRequest->sspCmdIU.cdb[5] ) ); 853285242Sachim } 854285242Sachim*/ 855285242Sachim#ifdef LOOPBACK_MPI 856285242Sachim if (loopback) 857285242Sachim { 858285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag); 859285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS); 860285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0); 861285242Sachim //OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0); 862285242Sachim } 863285242Sachim else 864285242Sachim#endif /* LOOPBACK_MPI */ 865285242Sachim { 866285242Sachim /* SSPIU less equal 28 bytes */ 867285242Sachim /* Configure DWORD 1 */ 868285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag); 869285242Sachim /* Configure DWORD 2 */ 870285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 871285242Sachim /* Configure DWORD 3 */ 872285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength); 873285242Sachim } 874285242Sachim 875285242Sachim#ifdef SA_TESTBASE_EXTRA 876285242Sachim /* TestBase - Set the host BST entry */ 877285242Sachim DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16; 878285242Sachim#endif /* SA_TESTBASE_EXTRA */ 879285242Sachim 880285242Sachim if (!(agRequestType & AGSA_SSP_INDIRECT_BIT)) 881285242Sachim { 882285242Sachim /* Configure DWORD 5-12 */ 883285242Sachim si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit)); 884285242Sachim pPayload->dirMTlr = 0; 885285242Sachim /* Mask DIR for Read/Write command */ 886285242Sachim /* Configure DWORD 4 bit 8-9 */ 887285242Sachim DirDW4 |= agRequestType & AGSA_DIR_MASK; 888285242Sachim } 889285242Sachim else /* AGSA_SSP_INDIRECT_BIT was set */ 890285242Sachim { 891285242Sachim 892285242Sachim agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect); 893285242Sachim 894285242Sachim /* Configure DWORD 5 */ 895285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32); 896285242Sachim /* Configure DWORD 6 */ 897285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 ); 898285242Sachim /* Configure DWORD 7 */ 899285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0); 900285242Sachim /* Configure DWORD 8 */ 901285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0); 902285242Sachim /* Configure DWORD 9 */ 903285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0); 904285242Sachim /* Configure DWORD 10 */ 905285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0); 906285242Sachim /* Configure DWORD 11 */ 907285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0); 908285242Sachim /* Mask DIR for Read/Write command */ 909285242Sachim /* Configure DWORD 4 bit 8-9 */ 910285242Sachim DirDW4 |= agRequestType & AGSA_DIR_MASK; 911285242Sachim /* Configure DWORD 4 bit 24-31 */ 912285242Sachim DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24; 913285242Sachim /* Configure DWORD 4 bit 4 */ 914285242Sachim DirDW4 |= 1 << SHIFT3; 915285242Sachim } 916285242Sachim 917285242Sachim /* set TLR */ 918285242Sachim DirDW4 |= pIRequest->flag & TLR_MASK; 919285242Sachim if (agRequestType & AGSA_MSG) 920285242Sachim { 921285242Sachim /* set M bit */ 922285242Sachim DirDW4 |= AGSA_MSG_BIT; 923285242Sachim } 924285242Sachim 925285242Sachim /* check for skipmask operation */ 926285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 927285242Sachim { 928285242Sachim DirDW4 |= AGSA_SKIP_MASK_BIT; 929285242Sachim /* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5 */ 930285242Sachim DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8; 931285242Sachim } 932285242Sachim 933285242Sachim 934285242Sachim /* Configure DWORDS 12-14 */ 935285242Sachim if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA) 936285242Sachim { 937285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 938285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 939285242Sachim pIRequest->encrypt.EncryptionPerLAAddrLo ); 940285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 941285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 942285242Sachim pIRequest->dif.DIFPerLAAddrLo ); 943285242Sachim 944285242Sachim SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal"); 945285242Sachim 946285242Sachim if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi ) 947285242Sachim { 948285242Sachim 949285242Sachim SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" )); 950285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa"); 951285242Sachim ret = AGSA_RC_FAILURE; 952285242Sachim goto ext; 953285242Sachim } 954285242Sachim 955285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 956285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 957285242Sachim pIRequest->encrypt.EncryptionPerLAAddrHi ); 958285242Sachim } 959285242Sachim else if( pIRequest->encrypt.enableEncryptionPerLA) 960285242Sachim { 961285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 962285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 963285242Sachim pIRequest->encrypt.EncryptionPerLAAddrLo ); 964285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 965285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 966285242Sachim 0); 967285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 968285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 969285242Sachim pIRequest->encrypt.EncryptionPerLAAddrHi ); 970285242Sachim } 971285242Sachim else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */ 972285242Sachim { 973285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 974285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 975285242Sachim 0); 976285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 977285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 978285242Sachim pIRequest->dif.DIFPerLAAddrLo ); 979285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 980285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 981285242Sachim pIRequest->dif.DIFPerLAAddrHi); 982285242Sachim } 983285242Sachim else /* Not EPL or DPL */ 984285242Sachim { 985285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 986285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 987285242Sachim 0); 988285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 989285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 990285242Sachim 0); 991285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 992285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 993285242Sachim 0); 994285242Sachim } 995285242Sachim 996285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 997285242Sachim { 998285242Sachim bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 999285242Sachim bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1000285242Sachim bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1001285242Sachim 1002285242Sachim SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1003285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1004285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1005285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1006285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1007285242Sachim 1008285242Sachim SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n", 1009285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1010285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1011285242Sachim pIRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1012285242Sachim 1013285242Sachim SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1014285242Sachim pIRequest->dif.udtArray[0], 1015285242Sachim pIRequest->dif.udtArray[1], 1016285242Sachim pIRequest->dif.udtArray[2], 1017285242Sachim pIRequest->dif.udtArray[3], 1018285242Sachim pIRequest->dif.udtArray[4], 1019285242Sachim pIRequest->dif.udtArray[5])); 1020285242Sachim 1021285242Sachim SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1022285242Sachim pIRequest->dif.udrtArray[0], 1023285242Sachim pIRequest->dif.udrtArray[1], 1024285242Sachim pIRequest->dif.udrtArray[2], 1025285242Sachim pIRequest->dif.udrtArray[3], 1026285242Sachim pIRequest->dif.udrtArray[4], 1027285242Sachim pIRequest->dif.udrtArray[5])); 1028285242Sachim 1029285242Sachim SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1030285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1031285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1032285242Sachim pIRequest->dif.DIFPerLAAddrLo, 1033285242Sachim pIRequest->dif.DIFPerLAAddrHi)); 1034285242Sachim 1035285242Sachim DirDW4 |= AGSA_DIF_BIT; 1036285242Sachim 1037285242Sachim /* DWORD 15 */ 1038285242Sachim SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags )); 1039285242Sachim 1040285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1041285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags), 1042285242Sachim pIRequest->dif.flags); 1043285242Sachim 1044285242Sachim /* Populate the UDT and UDTR bytes as necessary. */ 1045285242Sachim if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1046285242Sachim { 1047285242Sachim UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 | 1048285242Sachim pIRequest->dif.udtArray[0]); 1049285242Sachim UDT5_UDT4_UDT3_UDT2 = (pIRequest->dif.udtArray[5] << SHIFT24 | 1050285242Sachim pIRequest->dif.udtArray[4] << SHIFT16 | 1051285242Sachim pIRequest->dif.udtArray[3] << SHIFT8 | 1052285242Sachim pIRequest->dif.udtArray[2]); 1053285242Sachim } 1054285242Sachim 1055285242Sachim if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1056285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1057285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1058285242Sachim { 1059285242Sachim UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 | 1060285242Sachim pIRequest->dif.udrtArray[0] << SHIFT16 ); 1061285242Sachim UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 | 1062285242Sachim pIRequest->dif.udrtArray[4] << SHIFT16 | 1063285242Sachim pIRequest->dif.udrtArray[3] << SHIFT8 | 1064285242Sachim pIRequest->dif.udrtArray[2]); 1065285242Sachim } 1066285242Sachim 1067285242Sachim /* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */ 1068285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1069285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt), 1070285242Sachim UDTR1_UDTR0_UDT1_UDT0); 1071285242Sachim 1072285242Sachim /* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */ 1073285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1074285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo), 1075285242Sachim UDT5_UDT4_UDT3_UDT2); 1076285242Sachim 1077285242Sachim /* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1078285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1079285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi), 1080285242Sachim UDTR5_UDTR4_UDTR3_UDTR2); 1081285242Sachim 1082285242Sachim /* DWORD 19 */ 1083285242Sachim /* Get IOS IOSeed enable bit */ 1084285242Sachim if( pIRequest->dif.enableDIFPerLA || 1085285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) ) 1086285242Sachim { 1087285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1088285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1089285242Sachim ((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1090285242Sachim (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 ))); 1091285242Sachim } 1092285242Sachim else 1093285242Sachim { 1094285242Sachim if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1095285242Sachim { 1096285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1097285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1098285242Sachim pIRequest->dif.initialIOSeed ); 1099285242Sachim } 1100285242Sachim else 1101285242Sachim { 1102285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1103285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 0 ); 1104285242Sachim } 1105285242Sachim } 1106285242Sachim } 1107285242Sachim 1108285242Sachim /* configure encryption */ 1109285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1110285242Sachim { 1111285242Sachim 1112285242Sachim SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n", 1113285242Sachim pIRequest->encrypt.dekInfo.dekTable, 1114285242Sachim pIRequest->encrypt.dekInfo.dekIndex)); 1115285242Sachim 1116285242Sachim SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n", 1117285242Sachim pIRequest->encrypt.kekIndex, 1118285242Sachim pIRequest->encrypt.sectorSizeIndex, 1119285242Sachim pIRequest->encrypt.cipherMode)); 1120285242Sachim 1121285242Sachim SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n", 1122285242Sachim pIRequest->encrypt.keyTag_W0, 1123285242Sachim pIRequest->encrypt.keyTag_W1)); 1124285242Sachim SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n", 1125285242Sachim pIRequest->encrypt.tweakVal_W0, 1126285242Sachim pIRequest->encrypt.tweakVal_W1)); 1127285242Sachim SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n", 1128285242Sachim pIRequest->encrypt.tweakVal_W2, 1129285242Sachim pIRequest->encrypt.tweakVal_W3)); 1130285242Sachim 1131285242Sachim DirDW4 |= AGSA_ENCRYPT_BIT; 1132285242Sachim 1133285242Sachim encryptFlags = 0; 1134285242Sachim 1135285242Sachim if (pIRequest->encrypt.keyTagCheck == agTRUE) 1136285242Sachim { 1137285242Sachim encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT; 1138285242Sachim } 1139285242Sachim 1140285242Sachim if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS ) 1141285242Sachim { 1142285242Sachim encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4; 1143285242Sachim } 1144285242Sachim 1145285242Sachim encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2; 1146285242Sachim 1147285242Sachim /* Always use encryption for DIF fields, skip SKPD */ 1148285242Sachim 1149285242Sachim encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8; 1150285242Sachim /* Configure DWORD 20 */ 1151285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1152285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo), 1153285242Sachim encryptFlags); 1154285242Sachim 1155285242Sachim encryptFlags = pIRequest->encrypt.sectorSizeIndex; 1156285242Sachim 1157285242Sachim encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5; 1158285242Sachim 1159285242Sachim encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16; 1160285242Sachim /* Configure DWORD 21 */ 1161285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1162285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi), 1163285242Sachim encryptFlags); 1164285242Sachim 1165285242Sachim /* Configure DWORD 22 */ 1166285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1167285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0), 1168285242Sachim pIRequest->encrypt.keyTag_W0); 1169285242Sachim /* Configure DWORD 23 */ 1170285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1171285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1), 1172285242Sachim pIRequest->encrypt.keyTag_W1); 1173285242Sachim 1174285242Sachim /* Configure DWORD 24 */ 1175285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1176285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0), 1177285242Sachim pIRequest->encrypt.tweakVal_W0); 1178285242Sachim /* Configure DWORD 25 */ 1179285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1180285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1), 1181285242Sachim pIRequest->encrypt.tweakVal_W1); 1182285242Sachim /* Configure DWORD 26 */ 1183285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1184285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2), 1185285242Sachim pIRequest->encrypt.tweakVal_W2); 1186285242Sachim /* Configure DWORD 27 */ 1187285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1188285242Sachim OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3), 1189285242Sachim pIRequest->encrypt.tweakVal_W3); 1190285242Sachim } 1191285242Sachim 1192285242Sachim /* Setup SGL */ 1193285242Sachim if (pIRequest->dataLength) 1194285242Sachim { 1195285242Sachim pSgl = &(pIRequest->agSgl); 1196285242Sachim 1197285242Sachim SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode, 1198285242Sachim pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1199285242Sachim 1200285242Sachim /* Get DIF PER LA flag */ 1201285242Sachim DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0); 1202285242Sachim DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0); 1203285242Sachim /* Configure DWORD 4 */ 1204285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1205285242Sachim 1206285242Sachim if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1207285242Sachim { 1208285242Sachim /* Configure DWORD 28 */ 1209285242Sachim pEncryptPayload->AddrLow0 = pSgl->sgLower; 1210285242Sachim /* Configure DWORD 29 */ 1211285242Sachim pEncryptPayload->AddrHi0 = pSgl->sgUpper; 1212285242Sachim /* Configure DWORD 30 */ 1213285242Sachim pEncryptPayload->Len0 = pSgl->len; 1214285242Sachim /* Configure DWORD 31 */ 1215285242Sachim pEncryptPayload->E0 = pSgl->extReserved; 1216285242Sachim } 1217285242Sachim else 1218285242Sachim { 1219285242Sachim pPayload->AddrLow0 = pSgl->sgLower; 1220285242Sachim pPayload->AddrHi0 = pSgl->sgUpper; 1221285242Sachim pPayload->Len0 = pSgl->len; 1222285242Sachim pPayload->E0 = pSgl->extReserved; 1223285242Sachim } 1224285242Sachim } 1225285242Sachim else 1226285242Sachim { 1227285242Sachim /* no data transfer */ 1228285242Sachim /* Configure DWORD 4 */ 1229285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1230285242Sachim 1231285242Sachim if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1232285242Sachim { 1233285242Sachim pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload; 1234285242Sachim 1235285242Sachim pEncryptPayload->AddrLow0 = 0; 1236285242Sachim pEncryptPayload->AddrHi0 = 0; 1237285242Sachim pEncryptPayload->Len0 = 0; 1238285242Sachim pEncryptPayload->E0 = 0; 1239285242Sachim } 1240285242Sachim else 1241285242Sachim { 1242285242Sachim pPayload->AddrLow0 = 0; 1243285242Sachim pPayload->AddrHi0 = 0; 1244285242Sachim pPayload->Len0 = 0; 1245285242Sachim pPayload->E0 = 0; 1246285242Sachim } 1247285242Sachim } 1248285242Sachim 1249285242Sachim /* post the IOMB to SPC */ 1250285242Sachim#ifdef LOOPBACK_MPI 1251285242Sachim if (loopback) 1252285242Sachim ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority); 1253285242Sachim else 1254285242Sachim#endif /* LOOPBACK_MPI */ 1255285242Sachim ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority); 1256285242Sachim if (AGSA_RC_FAILURE == ret) 1257285242Sachim { 1258285242Sachim SA_DBG1(("saSSPStart, error when post SSP IOMB\n")); 1259285242Sachim ret = AGSA_RC_FAILURE; 1260285242Sachim } 1261285242Sachim } 1262285242Sachim else 1263285242Sachim { 1264285242Sachim /* additionalCdbLen is not zero and type is Ext - use EXT mode */ 1265285242Sachim agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 1266285242Sachim agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage; 1267285242Sachim bit32 sspiul; 1268285242Sachim 1269285242Sachim /* 1270285242Sachim * Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. 1271285242Sachim * Be careful with the scatter/gather lists, encryption and DIF options. 1272285242Sachim */ 1273285242Sachim /* CDB > 16 bytes */ 1274285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag); 1275285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1276285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength); 1277285242Sachim /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 1278285242Sachim /* setup standard CDB bytes + additional CDB bytes in length field */ 1279285242Sachim sspiul = sizeof(agsaSSPCmdInfoUnit_t) + 1280285242Sachim (pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC); 1281285242Sachim DirDW4 = sspiul << 16; 1282285242Sachim si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul); 1283285242Sachim pPayload->SSPIuLendirMTlr = 0; 1284285242Sachim 1285285242Sachim /* Mask DIR for Read/Write command */ 1286285242Sachim DirDW4 |= agRequestType & AGSA_DIR_MASK; 1287285242Sachim 1288285242Sachim /* set TLR */ 1289285242Sachim DirDW4 |= pIRequest->flag & TLR_MASK; 1290285242Sachim if (agRequestType & AGSA_MSG) 1291285242Sachim { 1292285242Sachim /* set M bit */ 1293285242Sachim DirDW4 |= AGSA_MSG_BIT; 1294285242Sachim } 1295285242Sachim 1296285242Sachim /* check for skipmask operation */ 1297285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 1298285242Sachim { 1299285242Sachim SA_ASSERT(0, "Mode not supported"); 1300285242Sachim } 1301285242Sachim 1302285242Sachim /* configure DIF */ 1303285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 1304285242Sachim { 1305285242Sachim SA_ASSERT(0, "Mode not supported"); 1306285242Sachim } 1307285242Sachim 1308285242Sachim /* configure encryption */ 1309285242Sachim if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1310285242Sachim { 1311285242Sachim SA_ASSERT(0, "Mode not supported"); 1312285242Sachim } 1313285242Sachim /* Setup SGL */ 1314285242Sachim if (pIRequest->dataLength) 1315285242Sachim { 1316285242Sachim pSgl = &(pIRequest->agSgl); 1317285242Sachim 1318285242Sachim SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n", 1319285242Sachim pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1320285242Sachim 1321285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1322285242Sachim 1323285242Sachim if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1324285242Sachim { 1325285242Sachim si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t)); 1326285242Sachim } 1327285242Sachim else 1328285242Sachim { 1329285242Sachim si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t)); 1330285242Sachim } 1331285242Sachim } 1332285242Sachim else 1333285242Sachim { 1334285242Sachim /* no data transfer */ 1335285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1336285242Sachim pPayload->dataLen = 0; 1337285242Sachim } 1338285242Sachim 1339285242Sachim /* post the IOMB to SPC */ 1340285242Sachim if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority )) 1341285242Sachim { 1342285242Sachim SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n")); 1343285242Sachim ret = AGSA_RC_FAILURE; 1344285242Sachim } 1345285242Sachim } 1346285242Sachim break; 1347285242Sachim } 1348285242Sachim case AGSA_SSP_TASK_MGNT_REQ: 1349285242Sachim case AGSA_SSP_TASK_MGNT_REQ_M: 1350285242Sachim { 1351285242Sachim agsaIORequestDesc_t *pTMRequestToAbort = agNULL; 1352285242Sachim agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage; 1353285242Sachim 1354285242Sachim if (agRequestType & AGSA_MSG) 1355285242Sachim { 1356285242Sachim /* set M bit */ 1357285242Sachim DirDW4 = AGSA_MSG_BIT; 1358285242Sachim } 1359285242Sachim 1360285242Sachim /* set DS and ADS bit */ 1361285242Sachim DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3; 1362285242Sachim 1363285242Sachim /* Prepare the SSP TASK Management payload */ 1364285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag); 1365285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1366285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged); 1367285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction); 1368285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4); 1369285242Sachim pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0]; 1370285242Sachim pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1]; 1371285242Sachim pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2]; 1372285242Sachim pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3]; 1373285242Sachim pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4]; 1374285242Sachim pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5]; 1375285242Sachim pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6]; 1376285242Sachim pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7]; 1377285242Sachim 1378285242Sachim if (agTMRequest) 1379285242Sachim { 1380285242Sachim pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData; 1381285242Sachim if (pTMRequestToAbort) 1382285242Sachim { 1383285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag); 1384285242Sachim } 1385285242Sachim } 1386285242Sachim 1387285242Sachim SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n", 1388285242Sachim pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId)); 1389285242Sachim 1390285242Sachim siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs); 1391285242Sachim 1392285242Sachim /* post the IOMB to SPC */ 1393285242Sachim if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority)) 1394285242Sachim { 1395285242Sachim SA_DBG1(("saSSPStart, error when post TM IOMB\n")); 1396285242Sachim ret = AGSA_RC_FAILURE; 1397285242Sachim } 1398285242Sachim 1399285242Sachim break; 1400285242Sachim } 1401285242Sachim case AGSA_SSP_TGT_READ_DATA: 1402285242Sachim case AGSA_SSP_TGT_READ_GOOD_RESP: 1403285242Sachim case AGSA_SSP_TGT_WRITE_DATA: 1404285242Sachim case AGSA_SSP_TGT_WRITE_GOOD_RESP: 1405285242Sachim { 1406285242Sachim agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 1407285242Sachim agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage; 1408285242Sachim bit32 DirDW5 = 0; 1409285242Sachim /* Prepare the SSP TGT IO Start payload */ 1410285242Sachim /* Configure DWORD 1 */ 1411285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag); 1412285242Sachim /* Configure DWORD 2 */ 1413285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1414285242Sachim /* Configure DWORD 3 */ 1415285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength); 1416285242Sachim /* Configure DWORD 4 */ 1417285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset); 1418285242Sachim 1419285242Sachim SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption )); 1420285242Sachim 1421285242Sachim /* Mask DIR and AutoGR bits for Read/Write command */ 1422285242Sachim DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16); 1423285242Sachim 1424285242Sachim if (pTRequest->sspOption & SSP_OPTION_DIF ) 1425285242Sachim { 1426285242Sachim bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 1427285242Sachim bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1428285242Sachim bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1429285242Sachim SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1430285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1431285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1432285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1433285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1434285242Sachim 1435285242Sachim SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n", 1436285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1437285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1438285242Sachim pTRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1439285242Sachim 1440285242Sachim SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1441285242Sachim pTRequest->dif.udtArray[0], 1442285242Sachim pTRequest->dif.udtArray[1], 1443285242Sachim pTRequest->dif.udtArray[2], 1444285242Sachim pTRequest->dif.udtArray[3], 1445285242Sachim pTRequest->dif.udtArray[4], 1446285242Sachim pTRequest->dif.udtArray[5])); 1447285242Sachim 1448285242Sachim SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1449285242Sachim pTRequest->dif.udrtArray[0], 1450285242Sachim pTRequest->dif.udrtArray[1], 1451285242Sachim pTRequest->dif.udrtArray[2], 1452285242Sachim pTRequest->dif.udrtArray[3], 1453285242Sachim pTRequest->dif.udrtArray[4], 1454285242Sachim pTRequest->dif.udrtArray[5])); 1455285242Sachim 1456285242Sachim SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1457285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1458285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1459285242Sachim pTRequest->dif.DIFPerLAAddrLo, 1460285242Sachim pTRequest->dif.DIFPerLAAddrHi)); 1461285242Sachim 1462285242Sachim DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF; 1463285242Sachim 1464285242Sachim 1465285242Sachim SA_DBG3(("saSSPStart,tgt DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags )); 1466285242Sachim 1467285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1468285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags), 1469285242Sachim pTRequest->dif.flags); 1470285242Sachim 1471285242Sachim /* Populate the UDT and UDTR bytes as necessary. */ 1472285242Sachim if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1473285242Sachim { 1474285242Sachim UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 | 1475285242Sachim pTRequest->dif.udtArray[0]); 1476285242Sachim UDT5_UDT4_UDT3_UDT2 = (pTRequest->dif.udtArray[5] << SHIFT24 | 1477285242Sachim pTRequest->dif.udtArray[4] << SHIFT16 | 1478285242Sachim pTRequest->dif.udtArray[3] << SHIFT8 | 1479285242Sachim pTRequest->dif.udtArray[2]); 1480285242Sachim } 1481285242Sachim 1482285242Sachim if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1483285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1484285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1485285242Sachim { 1486285242Sachim UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 | 1487285242Sachim pTRequest->dif.udrtArray[0] << SHIFT16 ); 1488285242Sachim UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 | 1489285242Sachim pTRequest->dif.udrtArray[4] << SHIFT16 | 1490285242Sachim pTRequest->dif.udrtArray[3] << SHIFT8 | 1491285242Sachim pTRequest->dif.udrtArray[2]); 1492285242Sachim } 1493285242Sachim /* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */ 1494285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1495285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt), 1496285242Sachim UDTR1_UDTR0_UDT1_UDT0); 1497285242Sachim 1498285242Sachim /* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */ 1499285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1500285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo), 1501285242Sachim UDT5_UDT4_UDT3_UDT2); 1502285242Sachim 1503285242Sachim /* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1504285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1505285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi), 1506285242Sachim UDTR5_UDTR4_UDTR3_UDTR2); 1507285242Sachim /* DWORD 11 */ 1508285242Sachim /* Get IOS IOSeed enable bit */ 1509285242Sachim if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) 1510285242Sachim { 1511285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1512285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1513285242Sachim ((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1514285242Sachim (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 ))); 1515285242Sachim } 1516285242Sachim else 1517285242Sachim { 1518285242Sachim /* Get IOS IOSeed enable bit */ 1519285242Sachim if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1520285242Sachim { 1521285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1522285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1523285242Sachim pTRequest->dif.initialIOSeed ); 1524285242Sachim } 1525285242Sachim else 1526285242Sachim { 1527285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, 1528285242Sachim OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 0 ); 1529285242Sachim } 1530285242Sachim } 1531285242Sachim } 1532285242Sachim 1533285242Sachim /* Mask DIR and AutoGR bits for Read/Write command */ 1534285242Sachim if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE) 1535285242Sachim { 1536285242Sachim DirDW5 |= AGSA_SSP_TGT_BITS_AGR; 1537285242Sachim } 1538285242Sachim 1539285242Sachim /* AN, RTE, RDF bits */ 1540285242Sachim DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2; 1541285242Sachim 1542285242Sachim /* ODS */ 1543285242Sachim if(pTRequest->sspOption & SSP_OPTION_ODS) 1544285242Sachim { 1545285242Sachim DirDW5 |= AGSA_SSP_TGT_BITS_ODS; 1546285242Sachim } 1547285242Sachim 1548285242Sachim /* Setup SGL */ 1549285242Sachim if (pTRequest->dataLength) 1550285242Sachim { 1551285242Sachim pSgl = &(pTRequest->agSgl); 1552285242Sachim 1553285242Sachim SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n", 1554285242Sachim pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1555285242Sachim 1556285242Sachim /* set up dir on the payload */ 1557285242Sachim /* Configure DWORD 5 */ 1558285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1559285242Sachim 1560285242Sachim pPayload->AddrLow0 = pSgl->sgLower; 1561285242Sachim pPayload->AddrHi0 = pSgl->sgUpper; 1562285242Sachim pPayload->Len0 = pSgl->len; 1563285242Sachim pPayload->E0 = pSgl->extReserved; 1564285242Sachim } 1565285242Sachim else 1566285242Sachim { 1567285242Sachim /* no data transfer */ 1568285242Sachim /* Configure DWORD 5 */ 1569285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1570285242Sachim pPayload->AddrLow0 = 0; 1571285242Sachim pPayload->AddrHi0 = 0; 1572285242Sachim pPayload->Len0 = 0; 1573285242Sachim } 1574285242Sachim /* Configure DWORD 6 */ 1575285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0); 1576285242Sachim 1577285242Sachim /* Build TGT IO START command and send it to SPC */ 1578285242Sachim if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority)) 1579285242Sachim { 1580285242Sachim SA_DBG1(("saSSPStart, error when post TGT IOMB\n")); 1581285242Sachim ret = AGSA_RC_FAILURE; 1582285242Sachim } 1583285242Sachim 1584285242Sachim break; 1585285242Sachim } 1586285242Sachim case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 1587285242Sachim { 1588285242Sachim agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 1589285242Sachim agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage; 1590285242Sachim bit32 ip, an, ods; 1591285242Sachim 1592285242Sachim if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)) 1593285242Sachim { 1594285242Sachim ip = 1; 1595285242Sachim si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength); 1596285242Sachim } 1597285242Sachim else 1598285242Sachim { 1599285242Sachim ip = 0; 1600285242Sachim /* NOTE: 1601285242Sachim * 1. reserved field must be ZEROED out. FW depends on it 1602285242Sachim * 2. trusted interface. indirect response buffer must be valid. 1603285242Sachim */ 1604285242Sachim si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved)); 1605285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower); 1606285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper); 1607285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength); 1608285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0); 1609285242Sachim } 1610285242Sachim 1611285242Sachim /* TLR setting */ 1612285242Sachim an = (pTResponse->respOption & RESP_OPTION_BITS); 1613285242Sachim /* ODS */ 1614285242Sachim ods = (pTResponse->respOption & RESP_OPTION_ODS); 1615285242Sachim 1616285242Sachim /* Prepare the SSP TGT RESPONSE Start payload */ 1617285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag); 1618285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1619285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength); 1620285242Sachim OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN), 1621285242Sachim (pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2)); 1622285242Sachim 1623285242Sachim /* Build TGT RESPONSE START command and send it to SPC */ 1624285242Sachim if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority)) 1625285242Sachim { 1626285242Sachim SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n")); 1627285242Sachim ret = AGSA_RC_FAILURE; 1628285242Sachim } 1629285242Sachim 1630285242Sachim break; 1631285242Sachim } 1632285242Sachim default: 1633285242Sachim { 1634285242Sachim SA_DBG1(("saSSPStart, Unsupported Request IOMB\n")); 1635285242Sachim ret = AGSA_RC_FAILURE; 1636285242Sachim break; 1637285242Sachim } 1638285242Sachim } 1639285242Sachim 1640285242Sachim } /* LL IOrequest available */ 1641285242Sachim 1642285242Sachim#ifdef SA_LL_IBQ_PROTECT 1643285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1644285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 1645285242Sachim 1646285242Sachim#ifdef SALL_API_TEST 1647285242Sachim if (ret == AGSA_RC_SUCCESS) 1648285242Sachim saRoot->LLCounters.IOCounter.numSSPStarted++; 1649285242Sachim#endif /*SALL_API_TEST */ 1650285242Sachim 1651285242Sachim#ifdef LOOPBACK_MPI 1652285242Sachim if (loopback) 1653285242Sachim saRoot->interruptVecIndexBitMap[0] |= (1 << outq); 1654285242Sachim#endif /* LOOPBACK_MPI */ 1655285242Sachim /* goto have leave and trace point info */ 1656285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa"); 1657285242Sachimext: 1658285242Sachim 1659285242Sachim OSSA_INP_LEAVE(agRoot); 1660285242Sachim return ret; 1661285242Sachim} 1662285242Sachim 1663285242Sachim/******************************************************************************/ 1664285242Sachim/*! \brief Abort SSP request 1665285242Sachim * 1666285242Sachim * Abort SSP request 1667285242Sachim * 1668285242Sachim * \param agRoot handles for this instance of SAS/SATA LLL 1669285242Sachim * \param queueNum 1670285242Sachim * \param agIORequest 1671285242Sachim * \param agIOToBeAborted 1672285242Sachim * 1673285242Sachim * \return If request is aborted successfully 1674285242Sachim * - \e AGSA_RC_SUCCESS request is aborted successfully 1675285242Sachim * - \e AGSA_RC_FAILURE request is not aborted successfully 1676285242Sachim */ 1677285242Sachim/*******************************************************************************/ 1678285242SachimGLOBAL bit32 saSSPAbort( 1679285242Sachim agsaRoot_t *agRoot, 1680285242Sachim agsaIORequest_t *agIORequest, 1681285242Sachim bit32 queueNum, 1682285242Sachim agsaDevHandle_t *agDevHandle, 1683285242Sachim bit32 flag, 1684285242Sachim void *abortParam, 1685285242Sachim ossaGenericAbortCB_t agCB 1686285242Sachim ) 1687285242Sachim{ 1688285242Sachim bit32 ret = AGSA_RC_SUCCESS, retVal; 1689285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 1690285242Sachim agsaIORequestDesc_t *pRequest; 1691285242Sachim agsaIORequestDesc_t *pRequestABT = NULL; 1692285242Sachim agsaDeviceDesc_t *pDevice = NULL; 1693285242Sachim agsaDeviceDesc_t *pDeviceABT = NULL; 1694285242Sachim agsaPort_t *pPort = NULL; 1695285242Sachim mpiICQueue_t *circularQ; 1696285242Sachim void *pMessage; 1697285242Sachim agsaSSPAbortCmd_t *payload; 1698285242Sachim agsaIORequest_t *agIOToBeAborted; 1699285242Sachim bit8 inq, outq; 1700285242Sachim bit32 using_reserved = agFALSE; 1701285242Sachim bit32 flag_copy = flag; 1702285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb"); 1703285242Sachim 1704285242Sachim /* sanity check */ 1705285242Sachim SA_ASSERT((agNULL != agRoot), ""); 1706285242Sachim SA_ASSERT((agNULL != agIORequest), ""); 1707285242Sachim 1708285242Sachim SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag)); 1709285242Sachim 1710285242Sachim /* Assign inbound and outbound Buffer */ 1711285242Sachim inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 1712285242Sachim outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 1713285242Sachim SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 1714285242Sachim 1715285242Sachim#ifdef SA_PRINTOUT_IN_WINDBG 1716285242Sachim#ifndef DBG 1717285242Sachim DbgPrint("saSSPAbort flag %d\n", flag ); 1718285242Sachim#endif /* DBG */ 1719285242Sachim#endif /* SA_PRINTOUT_IN_WINDBG */ 1720285242Sachim 1721285242Sachim if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1722285242Sachim { 1723285242Sachim agIOToBeAborted = (agsaIORequest_t *)abortParam; 1724285242Sachim /* Get LL IORequest entry for saSSPAbort() */ 1725285242Sachim pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1726285242Sachim if (agNULL == pRequest) 1727285242Sachim { 1728285242Sachim /* no pRequest found - can not Abort */ 1729285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n")); 1730285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb"); 1731285242Sachim return AGSA_RC_FAILURE; 1732285242Sachim } 1733285242Sachim /* Find the device the request sent to */ 1734285242Sachim pDevice = pRequest->pDevice; 1735285242Sachim /* Get LL IORequest entry for IOToBeAborted */ 1736285242Sachim pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1737285242Sachim if (agNULL == pRequestABT) 1738285242Sachim { 1739285242Sachim /* The IO to Be Abort is no longer exist */ 1740285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n")); 1741285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb"); 1742285242Sachim return AGSA_RC_FAILURE; 1743285242Sachim } 1744285242Sachim /* Find the device the request Abort to */ 1745285242Sachim pDeviceABT = pRequestABT->pDevice; 1746285242Sachim 1747285242Sachim if (agNULL == pDeviceABT) 1748285242Sachim { 1749285242Sachim /* no deviceID - can not build IOMB */ 1750285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n")); 1751285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb"); 1752285242Sachim return AGSA_RC_FAILURE; 1753285242Sachim } 1754285242Sachim 1755285242Sachim if (agNULL != pDevice) 1756285242Sachim { 1757285242Sachim /* Find the port the request was sent to */ 1758285242Sachim pPort = pDevice->pPort; 1759285242Sachim } 1760285242Sachim else 1761285242Sachim { 1762285242Sachim /* no deviceID - can not build IOMB */ 1763285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n")); 1764285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb"); 1765285242Sachim return AGSA_RC_FAILURE; 1766285242Sachim } 1767285242Sachim 1768285242Sachim /* Get request from free IORequests */ 1769285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1770285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1771285242Sachim } 1772285242Sachim else 1773285242Sachim { 1774285242Sachim if (ABORT_ALL == (flag & ABORT_MASK)) 1775285242Sachim { 1776285242Sachim /* abort All with Device or Port */ 1777285242Sachim /* Find the outgoing port for the device */ 1778285242Sachim if (agDevHandle == agNULL) 1779285242Sachim { 1780285242Sachim /* no deviceID - can not build IOMB */ 1781285242Sachim SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n")); 1782285242Sachim return AGSA_RC_FAILURE; 1783285242Sachim } 1784285242Sachim pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 1785285242Sachim if (agNULL == pDevice) 1786285242Sachim { 1787285242Sachim /* no deviceID - can not build IOMB */ 1788285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n")); 1789285242Sachim return AGSA_RC_FAILURE; 1790285242Sachim } 1791285242Sachim pPort = pDevice->pPort; 1792285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1793285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1794285242Sachim } 1795285242Sachim else 1796285242Sachim { 1797285242Sachim /* only support 00, 01 and 02 for flag */ 1798285242Sachim SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag)); 1799285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb"); 1800285242Sachim return AGSA_RC_FAILURE; 1801285242Sachim } 1802285242Sachim } 1803285242Sachim 1804285242Sachim if ( agNULL == pRequest ) 1805285242Sachim { 1806285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 1807285242Sachim if(agNULL != pRequest) 1808285242Sachim { 1809285242Sachim using_reserved = agTRUE; 1810285242Sachim SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n")); 1811285242Sachim } 1812285242Sachim else 1813285242Sachim { 1814285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1815285242Sachim /* If no LL IO request entry available */ 1816285242Sachim SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n")); 1817285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb"); 1818285242Sachim return AGSA_RC_BUSY; 1819285242Sachim } 1820285242Sachim } 1821285242Sachim 1822285242Sachim /* If free IOMB avaliable */ 1823285242Sachim /* Remove the request from free list */ 1824285242Sachim if( using_reserved ) 1825285242Sachim { 1826285242Sachim saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1827285242Sachim } 1828285242Sachim else 1829285242Sachim { 1830285242Sachim saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1831285242Sachim } 1832285242Sachim 1833285242Sachim /* Add the request to the pendingIORequests list of the device */ 1834285242Sachim pRequest->valid = agTRUE; 1835285242Sachim saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1836285242Sachim 1837285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1838285242Sachim 1839285242Sachim /* set up pRequest */ 1840285242Sachim pRequest->pIORequestContext = agIORequest; 1841285242Sachim pRequest->requestType = AGSA_SSP_REQTYPE; 1842285242Sachim pRequest->pDevice = pDevice; 1843285242Sachim pRequest->pPort = pPort; 1844285242Sachim pRequest->completionCB = (void*)agCB; 1845285242Sachim/* pRequest->abortCompletionCB = agCB;*/ 1846285242Sachim pRequest->startTick = saRoot->timeTick; 1847285242Sachim 1848285242Sachim /* Set request to the sdkData of agIORequest */ 1849285242Sachim agIORequest->sdkData = pRequest; 1850285242Sachim 1851285242Sachim /* save tag and IOrequest pointer to IOMap */ 1852285242Sachim saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1853285242Sachim saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1854285242Sachim 1855285242Sachim 1856285242Sachim#ifdef SA_LL_IBQ_PROTECT 1857285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1858285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 1859285242Sachim 1860285242Sachim /* If LL IO request entry avaliable */ 1861285242Sachim /* Get a free inbound queue entry */ 1862285242Sachim circularQ = &saRoot->inboundQueue[inq]; 1863285242Sachim retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage); 1864285242Sachim 1865285242Sachim /* if message size is too large return failure */ 1866285242Sachim if (AGSA_RC_FAILURE == retVal) 1867285242Sachim { 1868285242Sachim#ifdef SA_LL_IBQ_PROTECT 1869285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1870285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 1871285242Sachim 1872285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1873285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1874285242Sachim pRequest->valid = agFALSE; 1875285242Sachim if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1876285242Sachim { 1877285242Sachim SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1878285242Sachim saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1879285242Sachim } 1880285242Sachim else 1881285242Sachim { 1882285242Sachim /* return the request to free pool */ 1883285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1884285242Sachim } 1885285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1886285242Sachim 1887285242Sachim SA_DBG1(("saSSPAbort: error when get free IOMB\n")); 1888285242Sachim 1889285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb"); 1890285242Sachim return AGSA_RC_FAILURE; 1891285242Sachim } 1892285242Sachim 1893285242Sachim /* return busy if inbound queue is full */ 1894285242Sachim if (AGSA_RC_BUSY == retVal) 1895285242Sachim { 1896285242Sachim#ifdef SA_LL_IBQ_PROTECT 1897285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1898285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 1899285242Sachim 1900285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1901285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1902285242Sachim pRequest->valid = agFALSE; 1903285242Sachim if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1904285242Sachim { 1905285242Sachim SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1906285242Sachim saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1907285242Sachim } 1908285242Sachim else 1909285242Sachim { 1910285242Sachim /* return the request to free pool */ 1911285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1912285242Sachim } 1913285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1914285242Sachim 1915285242Sachim SA_DBG1(("saSSPAbort: no more IOMB\n")); 1916285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb"); 1917285242Sachim return AGSA_RC_BUSY; 1918285242Sachim } 1919285242Sachim 1920285242Sachim /* setup payload */ 1921285242Sachim payload = (agsaSSPAbortCmd_t*)pMessage; 1922285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag); 1923285242Sachim 1924285242Sachim if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1925285242Sachim { 1926285242Sachim if ( agNULL == pDeviceABT ) 1927285242Sachim { 1928285242Sachim SA_DBG1(("saSSPSAbort: no device\n" )); 1929285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb"); 1930285242Sachim return AGSA_RC_FAILURE; 1931285242Sachim } 1932285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex); 1933285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag); 1934285242Sachim } 1935285242Sachim else 1936285242Sachim { 1937285242Sachim /* abort all */ 1938285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex); 1939285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0); 1940285242Sachim } 1941285242Sachim 1942285242Sachim if(flag & ABORT_TSDK_QUARANTINE) 1943285242Sachim { 1944285242Sachim if(smIS_SPCV(agRoot)) 1945285242Sachim { 1946285242Sachim flag_copy &= ABORT_SCOPE; 1947285242Sachim flag_copy |= ABORT_QUARANTINE_SPCV; 1948285242Sachim } 1949285242Sachim } 1950285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy); 1951285242Sachim 1952285242Sachim SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag)); 1953285242Sachim 1954285242Sachim siCountActiveIORequestsOnDevice( agRoot, payload->deviceId ); 1955285242Sachim 1956285242Sachim /* post the IOMB to SPC */ 1957285242Sachim ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority); 1958285242Sachim 1959285242Sachim#ifdef SA_LL_IBQ_PROTECT 1960285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1961285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 1962285242Sachim 1963285242Sachim#ifdef SALL_API_TEST 1964285242Sachim if (AGSA_RC_SUCCESS == ret) 1965285242Sachim { 1966285242Sachim saRoot->LLCounters.IOCounter.numSSPAborted++; 1967285242Sachim } 1968285242Sachim#endif 1969285242Sachim 1970285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb"); 1971285242Sachim 1972285242Sachim return ret; 1973285242Sachim} 1974285242Sachim 1975285242Sachim 1976285242Sachim#if defined(SALLSDK_DEBUG) 1977285242Sachim/******************************************************************************/ 1978285242Sachim/*! \brief 1979285242Sachim * 1980285242Sachim * Dump StartSSP information 1981285242Sachim * 1982285242Sachim * Debug helper routine 1983285242Sachim * 1984285242Sachim * \return -none - 1985285242Sachim */ 1986285242Sachim/*******************************************************************************/ 1987285242SachimLOCAL void siDumpSSPStartIu( 1988285242Sachim agsaDevHandle_t *agDevHandle, 1989285242Sachim bit32 agRequestType, 1990285242Sachim agsaSASRequestBody_t *agRequestBody 1991285242Sachim ) 1992285242Sachim { 1993285242Sachim switch ( agRequestType ) 1994285242Sachim { 1995285242Sachim case AGSA_SSP_INIT_READ: 1996285242Sachim case AGSA_SSP_INIT_WRITE: 1997285242Sachim { 1998285242Sachim agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 1999285242Sachim 2000285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2001285242Sachim agDevHandle, 2002285242Sachim (agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE", 2003285242Sachim pIRequest->dataLength, 2004285242Sachim pIRequest->sspCmdIU.efb_tp_taskAttribute, 2005285242Sachim pIRequest->sspCmdIU.cdb[0], 2006285242Sachim pIRequest->sspCmdIU.cdb[1], 2007285242Sachim pIRequest->sspCmdIU.cdb[2], 2008285242Sachim pIRequest->sspCmdIU.cdb[3], 2009285242Sachim pIRequest->sspCmdIU.cdb[4], 2010285242Sachim pIRequest->sspCmdIU.cdb[5], 2011285242Sachim pIRequest->sspCmdIU.cdb[6], 2012285242Sachim pIRequest->sspCmdIU.cdb[7], 2013285242Sachim pIRequest->sspCmdIU.cdb[8], 2014285242Sachim pIRequest->sspCmdIU.cdb[9] 2015285242Sachim )); 2016285242Sachim break; 2017285242Sachim } 2018285242Sachim 2019285242Sachim case AGSA_SSP_INIT_READ_EXT: 2020285242Sachim case AGSA_SSP_INIT_WRITE_EXT: 2021285242Sachim { 2022285242Sachim agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2023285242Sachim 2024285242Sachim SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2025285242Sachim agDevHandle, 2026285242Sachim (agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT", 2027285242Sachim pIRequest->dataLength, 2028285242Sachim pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2029285242Sachim pIRequest->sspCmdIUExt.cdb[0], 2030285242Sachim pIRequest->sspCmdIUExt.cdb[1], 2031285242Sachim pIRequest->sspCmdIUExt.cdb[2], 2032285242Sachim pIRequest->sspCmdIUExt.cdb[3], 2033285242Sachim pIRequest->sspCmdIUExt.cdb[4], 2034285242Sachim pIRequest->sspCmdIUExt.cdb[5], 2035285242Sachim pIRequest->sspCmdIUExt.cdb[6], 2036285242Sachim pIRequest->sspCmdIUExt.cdb[7], 2037285242Sachim pIRequest->sspCmdIUExt.cdb[8], 2038285242Sachim pIRequest->sspCmdIUExt.cdb[9] 2039285242Sachim )); 2040285242Sachim break; 2041285242Sachim } 2042285242Sachim 2043285242Sachim case AGSA_SSP_INIT_READ_EXT_M: 2044285242Sachim case AGSA_SSP_INIT_WRITE_EXT_M: 2045285242Sachim { 2046285242Sachim agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2047285242Sachim 2048285242Sachim SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2049285242Sachim agDevHandle, 2050285242Sachim (agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M", 2051285242Sachim pIRequest->dataLength, 2052285242Sachim pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2053285242Sachim pIRequest->sspCmdIUExt.cdb[0], 2054285242Sachim pIRequest->sspCmdIUExt.cdb[1], 2055285242Sachim pIRequest->sspCmdIUExt.cdb[2], 2056285242Sachim pIRequest->sspCmdIUExt.cdb[3], 2057285242Sachim pIRequest->sspCmdIUExt.cdb[4], 2058285242Sachim pIRequest->sspCmdIUExt.cdb[5], 2059285242Sachim pIRequest->sspCmdIUExt.cdb[6], 2060285242Sachim pIRequest->sspCmdIUExt.cdb[7], 2061285242Sachim pIRequest->sspCmdIUExt.cdb[8], 2062285242Sachim pIRequest->sspCmdIUExt.cdb[9] 2063285242Sachim )); 2064285242Sachim break; 2065285242Sachim } 2066285242Sachim 2067285242Sachim case AGSA_SSP_INIT_READ_INDIRECT: 2068285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT: 2069285242Sachim case AGSA_SSP_INIT_READ_INDIRECT_M: 2070285242Sachim case AGSA_SSP_INIT_WRITE_INDIRECT_M: 2071285242Sachim { 2072285242Sachim agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect); 2073285242Sachim 2074285242Sachim SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n", 2075285242Sachim agDevHandle, 2076285242Sachim (agRequestType==AGSA_SSP_INIT_READ_INDIRECT || 2077285242Sachim agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT", 2078285242Sachim pIRequest->dataLength, 2079285242Sachim pIRequest->sspInitiatorReqLen, 2080285242Sachim pIRequest->sspInitiatorReqAddrUpper32, 2081285242Sachim pIRequest->sspInitiatorReqAddrLower32 )); 2082285242Sachim break; 2083285242Sachim } 2084285242Sachim 2085285242Sachim 2086285242Sachim case AGSA_SSP_TASK_MGNT_REQ: 2087285242Sachim { 2088285242Sachim agsaSSPScsiTaskMgntReq_t *pTaskCmd =&agRequestBody->sspTaskMgntReq; 2089285242Sachim /* copy payload */ 2090285242Sachim 2091285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x", 2092285242Sachim agDevHandle, 2093285242Sachim "AGSA_SSP_TASK_MGNT_REQ", 2094285242Sachim pTaskCmd->taskMgntFunction, 2095285242Sachim pTaskCmd->tagOfTaskToBeManaged 2096285242Sachim )); 2097285242Sachim break; 2098285242Sachim } 2099285242Sachim case AGSA_SSP_TGT_READ_DATA: 2100285242Sachim { 2101285242Sachim agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2102285242Sachim 2103285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2104285242Sachim agDevHandle, 2105285242Sachim "AGSA_SSP_TGT_READ_DATA", 2106285242Sachim pTRequest->dataLength, 2107285242Sachim pTRequest->offset )); 2108285242Sachim break; 2109285242Sachim } 2110285242Sachim case AGSA_SSP_TGT_READ_GOOD_RESP: 2111285242Sachim { 2112285242Sachim agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2113285242Sachim 2114285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2115285242Sachim agDevHandle, 2116285242Sachim "AGSA_SSP_TGT_READ_GOOD_RESP", 2117285242Sachim pTRequest->dataLength, 2118285242Sachim pTRequest->offset)); 2119285242Sachim break; 2120285242Sachim } 2121285242Sachim case AGSA_SSP_TGT_WRITE_GOOD_RESP: 2122285242Sachim { 2123285242Sachim agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2124285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2125285242Sachim agDevHandle, 2126285242Sachim "AGSA_SSP_TGT_WRITE_GOOD_RESP", 2127285242Sachim pTRequest->dataLength, 2128285242Sachim pTRequest->offset )); 2129285242Sachim 2130285242Sachim break; 2131285242Sachim } 2132285242Sachim case AGSA_SSP_TGT_WRITE_DATA: 2133285242Sachim { 2134285242Sachim agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2135285242Sachim 2136285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2137285242Sachim agDevHandle, 2138285242Sachim "AGSA_SSP_TGT_WRITE_DATA", 2139285242Sachim pTRequest->dataLength, 2140285242Sachim pTRequest->offset )); 2141285242Sachim break; 2142285242Sachim } 2143285242Sachim case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 2144285242Sachim { 2145285242Sachim agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 2146285242Sachim 2147285242Sachim SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x Tag=%x\n", 2148285242Sachim agDevHandle, 2149285242Sachim "AGSA_SSP_TGT_CMD_OR_TASK_RSP", 2150285242Sachim pTResponse->respBufLength, 2151285242Sachim pTResponse->respBufUpper, 2152285242Sachim pTResponse->respBufLower, 2153285242Sachim pTResponse->agTag )); 2154285242Sachim break; 2155285242Sachim } 2156285242Sachim 2157285242Sachim default: 2158285242Sachim { 2159285242Sachim SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n", 2160285242Sachim agDevHandle, 2161285242Sachim "Unknown SSP cmd type", 2162285242Sachim agRequestType 2163285242Sachim )); 2164285242Sachim break; 2165285242Sachim } 2166285242Sachim } 2167285242Sachim return; 2168285242Sachim} 2169285242Sachim#endif /* SALLSDK_DEBUG */ 2170