1285809Sscottl/******************************************************************************* 2285809Sscottl** 3285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4285809Sscottl* 5285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 6285809Sscottl*that the following conditions are met: 7285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 8285809Sscottl*following disclaimer. 9285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 10285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided 11285809Sscottl*with the distribution. 12285809Sscottl* 13285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 14285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 18285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 21285809Sscottl 22285809Sscottl********************************************************************************/ 23285809Sscottl/*******************************************************************************/ 24285809Sscottl/*! \file sassp.c 25285809Sscottl * \brief The file implements the functions for SSP request/response 26285809Sscottl * 27285809Sscottl */ 28285809Sscottl/*******************************************************************************/ 29285809Sscottl#include <sys/cdefs.h> 30285809Sscottl__FBSDID("$FreeBSD$"); 31285809Sscottl#include <dev/pms/config.h> 32285809Sscottl 33285809Sscottl#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 34285809Sscottl#ifdef SA_ENABLE_TRACE_FUNCTIONS 35285809Sscottl#ifdef siTraceFileID 36285809Sscottl#undef siTraceFileID 37285809Sscottl#endif 38285809Sscottl#define siTraceFileID 'O' 39285809Sscottl#endif 40285809Sscottl 41285809Sscottl#ifdef LOOPBACK_MPI 42285809Sscottlextern int loopback; 43285809Sscottl#endif 44285809Sscottl 45285809Sscottl#ifdef SALLSDK_DEBUG 46285809SscottlLOCAL void siDumpSSPStartIu( 47285809Sscottl agsaDevHandle_t *agDevHandle, 48285809Sscottl bit32 agRequestType, 49285809Sscottl agsaSASRequestBody_t *agRequestBody 50285809Sscottl ); 51285809Sscottl#endif 52285809Sscottl 53285809Sscottl#ifdef FAST_IO_TEST 54285809SscottlLOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot, 55285809Sscottl bit32 queueNum) 56285809Sscottl{ 57285809Sscottl bit8 inq; 58285809Sscottl mpiICQueue_t *circularQ; 59285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 60285809Sscottl 61285809Sscottl inq = INQ(queueNum); 62285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 63285809Sscottl return circularQ->producerIdx; 64285809Sscottl} 65285809Sscottl 66285809SscottlLOCAL void saSetIBQPI(agsaRoot_t *agRoot, 67285809Sscottl bit32 queueNum, 68285809Sscottl bit32 pi) 69285809Sscottl{ 70285809Sscottl bit8 inq; 71285809Sscottl mpiICQueue_t *circularQ; 72285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 73285809Sscottl 74285809Sscottl inq = INQ(queueNum); 75285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 76285809Sscottl circularQ->producerIdx = pi; 77285809Sscottl} 78285809Sscottl 79285809SscottlosLOCAL void* 80285809SscottlsiFastSSPReqAlloc(agsaRoot_t *agRoot) 81285809Sscottl{ 82285809Sscottl int idx; 83285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 84285809Sscottl saFastRequest_t *fr; 85285809Sscottl 86285809Sscottl if (!saRoot->freeFastIdx) 87285809Sscottl { 88285809Sscottl SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n")); 89285809Sscottl SA_ASSERT((0), ""); 90285809Sscottl return 0; 91285809Sscottl } 92285809Sscottl 93285809Sscottl ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 94285809Sscottl saRoot->freeFastIdx--; 95285809Sscottl idx = saRoot->freeFastIdx; 96285809Sscottl ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 97285809Sscottl 98285809Sscottl fr = saRoot->freeFastReq[idx]; 99285809Sscottl SA_ASSERT((fr), ""); 100285809Sscottl fr->valid = 1; 101285809Sscottl 102285809Sscottl return fr; 103285809Sscottl} 104285809Sscottl 105285809SscottlLOCAL void 106285809SscottlsiFastSSPReqFree( 107285809Sscottl agsaRoot_t *agRoot, 108285809Sscottl void *freq) 109285809Sscottl{ 110285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 111285809Sscottl saFastRequest_t *fr = (saFastRequest_t*)freq; 112285809Sscottl 113285809Sscottl SA_DBG2(("siFastSSPReqFree: enter\n")); 114285809Sscottl SA_ASSERT((fr->valid), ""); 115285809Sscottl if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) / 116285809Sscottl sizeof(saRoot->freeFastReq[0])) 117285809Sscottl { 118285809Sscottl SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n", 119285809Sscottl saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) / 120285809Sscottl sizeof(saRoot->freeFastReq[0])))); 121285809Sscottl SA_ASSERT((0), ""); 122285809Sscottl return; 123285809Sscottl } 124285809Sscottl ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 125285809Sscottl /* not need if only one entry */ 126285809Sscottl /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq; */ 127285809Sscottl saRoot->freeFastIdx++; 128285809Sscottl ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 129285809Sscottl 130285809Sscottl fr->valid = 0; 131285809Sscottl SA_DBG6(("siFastSSPReqFree: leave\n")); 132285809Sscottl} 133285809Sscottl 134285809SscottlLOCAL bit32 siFastSSPResAlloc( 135285809Sscottl agsaRoot_t *agRoot, 136285809Sscottl bit32 queueNum, 137285809Sscottl bit32 agRequestType, 138285809Sscottl agsaDeviceDesc_t *pDevice, 139285809Sscottl agsaIORequestDesc_t **pRequest, 140285809Sscottl void **pPayload 141285809Sscottl ) 142285809Sscottl{ 143285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 144285809Sscottl mpiICQueue_t *circularQ; 145285809Sscottl bit8 inq; 146285809Sscottl bit16 size = IOMB_SIZE64; 147285809Sscottl bit32 ret = AGSA_RC_SUCCESS, retVal; 148285809Sscottl 149285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"2D"); 150285809Sscottl 151285809Sscottl SA_DBG4(("Entering function siFastSSPResAlloc:\n")); 152285809Sscottl 153285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 154285809Sscottl *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests); 155285809Sscottl 156285809Sscottl /* If no LL IO request entry available */ 157285809Sscottl if (agNULL == *pRequest ) 158285809Sscottl { 159285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 160285809Sscottl SA_DBG1(("siFastSSPResAlloc: No request from free list\n" )); 161285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D"); 162285809Sscottl ret = AGSA_RC_BUSY; 163285809Sscottl goto ext; 164285809Sscottl } 165285809Sscottl 166285809Sscottl /* Get IO request from free IORequests */ 167285809Sscottl /* Assign inbound and outbound Buffer */ 168285809Sscottl inq = INQ(queueNum); 169285809Sscottl SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 170285809Sscottl 171285809Sscottl /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */ 172285809Sscottl if (agRequestType & AGSA_SSP_EXT_BIT) 173285809Sscottl { 174285809Sscottl size = IOMB_SIZE96; 175285809Sscottl } 176285809Sscottl /* If LL IO request entry avaliable */ 177285809Sscottl /* Get a free inbound queue entry */ 178285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 179285809Sscottl retVal = mpiMsgFreeGet(circularQ, size, pPayload); 180285809Sscottl 181285809Sscottl /* if message size is too large return failure */ 182285809Sscottl if (AGSA_RC_SUCCESS != retVal) 183285809Sscottl { 184285809Sscottl if (AGSA_RC_FAILURE == retVal) 185285809Sscottl { 186285809Sscottl SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n")); 187285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D"); 188285809Sscottl } 189285809Sscottl 190285809Sscottl /* return busy if inbound queue is full */ 191285809Sscottl if (AGSA_RC_BUSY == retVal) 192285809Sscottl { 193285809Sscottl SA_DBG3(("siFastSSPResAlloc: no more IOMB\n")); 194285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D"); 195285809Sscottl } 196285809Sscottl ret = retVal; 197285809Sscottl goto ext; 198285809Sscottl } 199285809Sscottl 200285809Sscottl /* But add it to the pending queue during FastStart */ 201285809Sscottl /* If free IOMB avaliable */ 202285809Sscottl /* Remove the request from free list */ 203285809Sscottl saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode); 204285809Sscottl 205285809Sscottl /* Add the request to the pendingIORequests list of the device */ 206285809Sscottl saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode); 207285809Sscottl 208285809Sscottlext: 209285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 210285809Sscottl 211285809Sscottl if (AGSA_RC_SUCCESS == ret) 212285809Sscottl { 213285809Sscottl /* save tag and IOrequest pointer to IOMap */ 214285809Sscottl saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag; 215285809Sscottl saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest; 216285809Sscottl } 217285809Sscottl 218285809Sscottl return ret; 219285809Sscottl} /* siFastSSPResAlloc */ 220285809Sscottl 221285809Sscottl 222285809SscottlGLOBAL bit32 saFastSSPCancel(void *ioHandle) 223285809Sscottl{ 224285809Sscottl agsaRoot_t *agRoot; 225285809Sscottl agsaLLRoot_t *saRoot; 226285809Sscottl saFastRequest_t *fr; 227285809Sscottl bit32 i; 228285809Sscottl agsaIORequestDesc_t *ior; 229285809Sscottl 230285809Sscottl SA_ASSERT((ioHandle), ""); 231285809Sscottl fr = (saFastRequest_t*)ioHandle; 232285809Sscottl SA_ASSERT((fr->valid), ""); 233285809Sscottl agRoot = (agsaRoot_t*)fr->agRoot; 234285809Sscottl SA_ASSERT((agRoot), ""); 235285809Sscottl saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 236285809Sscottl SA_ASSERT((saRoot), ""); 237285809Sscottl 238285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"2E"); 239285809Sscottl 240285809Sscottl /* rollback the previously set IBQ PI */ 241285809Sscottl for (i = 0; i < fr->inqMax - 1; i++) 242285809Sscottl saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]); 243285809Sscottl 244285809Sscottl /* free all the previous Fast IO Requests */ 245285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 246285809Sscottl /* at least one entry, no need to check for NULL saLlistIOGetHead() */ 247285809Sscottl ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) - 248285809Sscottl OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 249285809Sscottl do 250285809Sscottl { 251285809Sscottl agsaDeviceDesc_t *pDevice; 252285809Sscottl void *tmp; 253285809Sscottl 254285809Sscottl pDevice = ior->pDevice; 255285809Sscottl saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode); 256285809Sscottl saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode); 257285809Sscottl 258285809Sscottl tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink); 259285809Sscottl if (!tmp) 260285809Sscottl { 261285809Sscottl break; /* end of list */ 262285809Sscottl } 263285809Sscottl ior = (agsaIORequestDesc_t*)((char*)tmp - 264285809Sscottl OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 265285809Sscottl } while (1); 266285809Sscottl 267285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 268285809Sscottl 269285809Sscottl /* free the IBQ PI tracking struct */ 270285809Sscottl siFastSSPReqFree(agRoot, fr); 271285809Sscottl 272285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E"); 273285809Sscottl return AGSA_RC_SUCCESS; 274285809Sscottl} /* saFastSSPCancel */ 275285809Sscottl 276285809SscottlGLOBAL void *saFastSSPPrepare( 277285809Sscottl void *ioh, 278285809Sscottl agsaFastCommand_t *fc, 279285809Sscottl ossaSSPCompletedCB_t cb, 280285809Sscottl void *cbArg) 281285809Sscottl{ 282285809Sscottl bit32 ret = AGSA_RC_SUCCESS; 283285809Sscottl agsaRoot_t *agRoot; 284285809Sscottl agsaLLRoot_t *saRoot; 285285809Sscottl mpiICQueue_t *circularQ; 286285809Sscottl agsaDeviceDesc_t *pDevice; 287285809Sscottl agsaSgl_t *pSgl; 288285809Sscottl bit32 Dir = 0; 289285809Sscottl bit8 inq, outq; 290285809Sscottl saFastRequest_t *fr; 291285809Sscottl void *pMessage; 292285809Sscottl agsaIORequestDesc_t *pRequest; 293285809Sscottl bit16 opCode; 294285809Sscottl bitptr offsetTag; 295285809Sscottl bitptr offsetDeviceId; 296285809Sscottl bitptr offsetDataLen; 297285809Sscottl bitptr offsetDir; 298285809Sscottl 299285809Sscottl agRoot = (agsaRoot_t*)fc->agRoot; 300285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"2G"); 301285809Sscottl 302285809Sscottl OSSA_INP_ENTER(agRoot); 303285809Sscottl 304285809Sscottl saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 305285809Sscottl /* sanity check */ 306285809Sscottl SA_ASSERT((agNULL != saRoot), ""); 307285809Sscottl 308285809Sscottl SA_DBG4(("Entering function saFastSSPPrepare:\n")); 309285809Sscottl 310285809Sscottl fr = (saFastRequest_t*)ioh; 311285809Sscottl if (!fr) 312285809Sscottl { 313285809Sscottl int i; 314285809Sscottl fr = siFastSSPReqAlloc(agRoot); 315285809Sscottl if (!fr) 316285809Sscottl { 317285809Sscottl SA_ASSERT((0), ""); 318285809Sscottl goto ext; 319285809Sscottl } 320285809Sscottl 321285809Sscottl saLlistIOInitialize(&fr->requests); 322285809Sscottl for (i = 0; i < AGSA_MAX_INBOUND_Q; i++) 323285809Sscottl fr->beforePI[i] = (bit32)-1; 324285809Sscottl 325285809Sscottl fr->inqMax = 0; 326285809Sscottl fr->agRoot = agRoot; 327285809Sscottl ioh = fr; 328285809Sscottl } 329285809Sscottl 330285809Sscottl /* Find the outgoing port for the device */ 331285809Sscottl pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData); 332285809Sscottl 333285809Sscottl ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType, 334285809Sscottl pDevice, &pRequest, &pMessage); 335285809Sscottl if (ret != AGSA_RC_SUCCESS) 336285809Sscottl { 337285809Sscottl SA_ASSERT((0), ""); 338285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G"); 339285809Sscottl goto ext; 340285809Sscottl } 341285809Sscottl 342285809Sscottl /* Assign inbound and outbound Buffer */ 343285809Sscottl inq = INQ(fc->queueNum); 344285809Sscottl outq = OUQ(fc->queueNum); 345285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 346285809Sscottl 347285809Sscottl SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex)); 348285809Sscottl 349285809Sscottl /* set up pRequest */ 350285809Sscottl pRequest->valid = agTRUE; 351285809Sscottl pRequest->pDevice = pDevice; 352285809Sscottl pRequest->requestType = fc->agRequestType; 353285809Sscottl 354285809Sscottl pRequest->completionCB = cb; 355285809Sscottl pRequest->pIORequestContext = (agsaIORequest_t*)cbArg; 356285809Sscottl 357285809Sscottl pSgl = fc->agSgl; 358285809Sscottl 359285809Sscottl switch (fc->agRequestType) 360285809Sscottl { 361285809Sscottl /* case AGSA_SSP_INIT_NONDATA: */ 362285809Sscottl case AGSA_SSP_INIT_READ: 363285809Sscottl case AGSA_SSP_INIT_WRITE: 364285809Sscottl case AGSA_SSP_INIT_READ_M: 365285809Sscottl case AGSA_SSP_INIT_WRITE_M: 366285809Sscottl { 367285809Sscottl agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 368285809Sscottl agsaSSPCmdInfoUnit_t *piu; 369285809Sscottl 370285809Sscottl /* SSPIU less equal 28 bytes */ 371285809Sscottl offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag); 372285809Sscottl offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId); 373285809Sscottl offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen); 374285809Sscottl offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr); 375285809Sscottl 376285809Sscottl piu = &pPayload->SSPInfoUnit; 377285809Sscottl 378285809Sscottl si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 379285809Sscottl si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb)); 380285809Sscottl piu->efb_tp_taskAttribute = fc->taskAttribute; 381285809Sscottl piu->additionalCdbLen = fc->additionalCdbLen; 382285809Sscottl 383285809Sscottl /* Mask DIR for Read/Write command */ 384285809Sscottl Dir = fc->agRequestType & AGSA_DIR_MASK; 385285809Sscottl 386285809Sscottl /* set TLR */ 387285809Sscottl Dir |= fc->flag & TLR_MASK; 388285809Sscottl if (fc->agRequestType & AGSA_MSG) 389285809Sscottl { 390285809Sscottl /* set M bit */ 391285809Sscottl Dir |= AGSA_MSG_BIT; 392285809Sscottl } 393285809Sscottl 394285809Sscottl /* Setup SGL */ 395285809Sscottl if (fc->dataLength) 396285809Sscottl { 397285809Sscottl SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n", 398285809Sscottl pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 399285809Sscottl /* 400285809Sscottl pPayload->AddrLow0 = pSgl->sgLower; 401285809Sscottl pPayload->AddrHi0 = pSgl->sgUpper; 402285809Sscottl pPayload->Len0 = pSgl->len; 403285809Sscottl pPayload->E0 = pSgl->extReserved; 404285809Sscottl */ 405285809Sscottl si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl)); 406285809Sscottl } 407285809Sscottl else 408285809Sscottl { 409285809Sscottl /* no data transfer */ 410285809Sscottl si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl)); 411285809Sscottl } 412285809Sscottl 413285809Sscottl opCode = OPC_INB_SSPINIIOSTART; 414285809Sscottl break; 415285809Sscottl } 416285809Sscottl 417285809Sscottl case AGSA_SSP_INIT_READ_EXT: 418285809Sscottl case AGSA_SSP_INIT_WRITE_EXT: 419285809Sscottl case AGSA_SSP_INIT_READ_EXT_M: 420285809Sscottl case AGSA_SSP_INIT_WRITE_EXT_M: 421285809Sscottl { 422285809Sscottl agsaSSPIniExtIOStartCmd_t *pPayload = 423285809Sscottl (agsaSSPIniExtIOStartCmd_t *)pMessage; 424285809Sscottl agsaSSPCmdInfoUnitExt_t *piu; 425285809Sscottl bit32 sspiul; 426285809Sscottl 427285809Sscottl /* CDB > 16 bytes */ 428285809Sscottl offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag); 429285809Sscottl offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId); 430285809Sscottl offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen); 431285809Sscottl offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr); 432285809Sscottl 433285809Sscottl /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 434285809Sscottl /* setup standard CDB bytes + additional CDB bytes in length field */ 435285809Sscottl sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC); 436285809Sscottl 437285809Sscottl Dir = sspiul << 16; 438285809Sscottl piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu; 439285809Sscottl 440285809Sscottl si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 441285809Sscottl si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb), 442285809Sscottl 16 + fc->additionalCdbLen)); 443285809Sscottl piu->efb_tp_taskAttribute = fc->taskAttribute; 444285809Sscottl piu->additionalCdbLen = fc->additionalCdbLen; 445285809Sscottl 446285809Sscottl /* Mask DIR for Read/Write command */ 447285809Sscottl Dir |= fc->agRequestType & AGSA_DIR_MASK; 448285809Sscottl 449285809Sscottl /* set TLR */ 450285809Sscottl Dir |= fc->flag & TLR_MASK; 451285809Sscottl if (fc->agRequestType & AGSA_MSG) 452285809Sscottl { 453285809Sscottl /* set M bit */ 454285809Sscottl Dir |= AGSA_MSG_BIT; 455285809Sscottl } 456285809Sscottl 457285809Sscottl /* Setup SGL */ 458285809Sscottl if (fc->dataLength) 459285809Sscottl { 460285809Sscottl SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n", 461285809Sscottl pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 462285809Sscottl 463285809Sscottl si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl)); 464285809Sscottl } 465285809Sscottl else //? 466285809Sscottl { 467285809Sscottl /* no data transfer */ 468285809Sscottl //pPayload->dataLen = 0; 469285809Sscottl si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl)); 470285809Sscottl } 471285809Sscottl SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 472285809Sscottl opCode = OPC_INB_SSPINIEXTIOSTART; 473285809Sscottl break; 474285809Sscottl } 475285809Sscottl 476285809Sscottl default: 477285809Sscottl { 478285809Sscottl SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n")); 479285809Sscottl ret = AGSA_RC_FAILURE; 480285809Sscottl SA_ASSERT((0), ""); 481285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G"); 482285809Sscottl goto ext; 483285809Sscottl } 484285809Sscottl } 485285809Sscottl 486285809Sscottl OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag); 487285809Sscottl OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex); 488285809Sscottl OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength); 489285809Sscottl OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir); 490285809Sscottl 491285809Sscottl if (fr->beforePI[inq] == -1) 492285809Sscottl { 493285809Sscottl /* save the new IBQ' PI */ 494285809Sscottl fr->beforePI[inq] = saGetIBQPI(agRoot, inq); 495285809Sscottl fr->inqList[fr->inqMax++] = inq; 496285809Sscottl } 497285809Sscottl 498285809Sscottl /* post the IOMB to SPC */ 499285809Sscottl ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, 500285809Sscottl opCode, outq, 0); 501285809Sscottl if (AGSA_RC_SUCCESS != ret) 502285809Sscottl { 503285809Sscottl SA_ASSERT((0), ""); 504285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 505285809Sscottl /* Remove the request from pendingIORequests list */ 506285809Sscottl saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode); 507285809Sscottl 508285809Sscottl /* Add the request to the free list of the device */ 509285809Sscottl saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode); 510285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 511285809Sscottl 512285809Sscottl SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n")); 513285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G"); 514285809Sscottl goto ext; 515285809Sscottl } 516285809Sscottl 517285809Sscottl /* Add the request to the pendingFastIORequests list of the device */ 518285809Sscottl saLlistIOAdd(&fr->requests, &pRequest->fastLink); 519285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G"); 520285809Sscottl 521285809Sscottlext: 522285809Sscottl if (fr && ret != AGSA_RC_SUCCESS) 523285809Sscottl { 524285809Sscottl saFastSSPCancel(fr); 525285809Sscottl ioh = 0; 526285809Sscottl } 527285809Sscottl OSSA_INP_LEAVE(agRoot); 528285809Sscottl return ioh; 529285809Sscottl} /* saFastSSPPrepare */ 530285809Sscottl 531285809SscottlGLOBAL bit32 saFastSSPSend(void *ioHandle) 532285809Sscottl{ 533285809Sscottl bit8 inq; 534285809Sscottl agsaRoot_t *agRoot; 535285809Sscottl agsaLLRoot_t *saRoot; 536285809Sscottl saFastRequest_t *fr; 537285809Sscottl bit32 i; 538285809Sscottl 539285809Sscottl SA_ASSERT((ioHandle), ""); 540285809Sscottl fr = (saFastRequest_t*)ioHandle; 541285809Sscottl agRoot = (agsaRoot_t*)fr->agRoot; 542285809Sscottl SA_ASSERT((agRoot), ""); 543285809Sscottl saRoot = (agsaLLRoot_t*)agRoot->sdkData; 544285809Sscottl SA_ASSERT((saRoot), ""); 545285809Sscottl 546285809Sscottl SA_DBG4(("Entering function saFastSSPSend:\n")); 547285809Sscottl 548285809Sscottl for (i = 0; i < fr->inqMax; i++) 549285809Sscottl { 550285809Sscottl inq = INQ(fr->inqList[i]); 551285809Sscottl /* FW interrupt */ 552285809Sscottl mpiIBQMsgSend(&saRoot->inboundQueue[inq]); 553285809Sscottl } 554285809Sscottl /* IORequests are freed in siIODone() */ 555285809Sscottl 556285809Sscottl siFastSSPReqFree(agRoot, fr); 557285809Sscottl return AGSA_RC_SUCCESS; 558285809Sscottl} /* saFastSSPSend */ 559285809Sscottl#endif 560285809Sscottl 561285809Sscottl/******************************************************************************/ 562285809Sscottl/*! \brief Start SSP request 563285809Sscottl * 564285809Sscottl * Start SSP request 565285809Sscottl * 566285809Sscottl * \param agRoot handles for this instance of SAS/SATA LLL 567285809Sscottl * \param queueNum 568285809Sscottl * \param agIORequest 569285809Sscottl * \param agDevHandle 570285809Sscottl * \param agRequestType 571285809Sscottl * \param agRequestBody 572285809Sscottl * \param agTMRequest valid for task management 573285809Sscottl * \param agCB 574285809Sscottl * 575285809Sscottl * \return If request is started successfully 576285809Sscottl * - \e AGSA_RC_SUCCESS request is started successfully 577285809Sscottl * - \e AGSA_RC_BUSY request is not started successfully 578285809Sscottl */ 579285809Sscottl/******************************************************************************/ 580285809SscottlGLOBAL bit32 saSSPStart( 581285809Sscottl agsaRoot_t *agRoot, 582285809Sscottl agsaIORequest_t *agIORequest, 583285809Sscottl bit32 queueNum, 584285809Sscottl agsaDevHandle_t *agDevHandle, 585285809Sscottl bit32 agRequestType, 586285809Sscottl agsaSASRequestBody_t *agRequestBody, 587285809Sscottl agsaIORequest_t *agTMRequest, 588285809Sscottl ossaSSPCompletedCB_t agCB) 589285809Sscottl{ 590285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 591285809Sscottl#ifdef LOOPBACK_MPI 592285809Sscottl mpiOCQueue_t *circularOQ = agNULL; 593285809Sscottl#endif 594285809Sscottl mpiICQueue_t *circularQ = agNULL; 595285809Sscottl agsaDeviceDesc_t *pDevice = agNULL; 596285809Sscottl agsaPort_t *pPort = agNULL; 597285809Sscottl agsaIORequestDesc_t *pRequest = agNULL; 598285809Sscottl agsaSgl_t *pSgl = agNULL; 599285809Sscottl void *pMessage = agNULL; 600285809Sscottl bit32 ret = AGSA_RC_SUCCESS, retVal = 0; 601285809Sscottl bit32 DirDW4 = 0; /* no data and no AutoGR */ 602285809Sscottl bit32 encryptFlags = 0; 603285809Sscottl bit16 size = 0; 604285809Sscottl bit16 opCode = 0; 605285809Sscottl bit8 inq = 0, outq = 0; 606285809Sscottl 607285809Sscottl 608285809Sscottl OSSA_INP_ENTER(agRoot); 609285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa"); 610285809Sscottl 611285809Sscottl /* sanity check */ 612285809Sscottl SA_ASSERT((agNULL != agRoot), ""); 613285809Sscottl SA_ASSERT((agNULL != agIORequest), ""); 614285809Sscottl SA_ASSERT((agNULL != agDevHandle), ""); 615285809Sscottl SA_ASSERT((agNULL != agRequestBody), ""); 616285809Sscottl 617285809Sscottl DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody); 618285809Sscottl 619285809Sscottl /* Find the outgoing port for the device */ 620285809Sscottl pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 621285809Sscottl 622285809Sscottl if(pDevice == agNULL ) 623285809Sscottl { 624285809Sscottl SA_ASSERT((pDevice), "pDevice"); 625285809Sscottl ret = AGSA_RC_FAILURE; 626285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa"); 627285809Sscottl goto ext; 628285809Sscottl } 629285809Sscottl 630285809Sscottl pPort = pDevice->pPort; 631285809Sscottl /* Assign inbound and outbound Buffer */ 632285809Sscottl inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 633285809Sscottl outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 634285809Sscottl SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 635285809Sscottl 636285809Sscottl SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex)); 637285809Sscottl 638285809Sscottl /* Get request from free IORequests */ 639285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 640285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 641285809Sscottl 642285809Sscottl /* If no LL IO request entry available */ 643285809Sscottl if ( agNULL == pRequest ) 644285809Sscottl { 645285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 646285809Sscottl SA_DBG1(("saSSPStart, No request from free list\n" )); 647285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa"); 648285809Sscottl ret = AGSA_RC_BUSY; 649285809Sscottl goto ext; 650285809Sscottl } 651285809Sscottl /* If LL IO request entry avaliable */ 652285809Sscottl else 653285809Sscottl { 654285809Sscottl /* Remove the request from free list */ 655285809Sscottl saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 656285809Sscottl /* Add the request to the pendingIORequests list of the device */ 657285809Sscottl saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 658285809Sscottl 659285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 660285809Sscottl 661285809Sscottl SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 662285809Sscottl 663285809Sscottl SA_DBG3(("saSSPStart, request %p\n", pRequest )); 664285809Sscottl 665285809Sscottl /* Decode the flag settings in the standard I/O requests to decide what size we need. */ 666285809Sscottl /* All other requests will be fine with only 64 byte messages. */ 667285809Sscottl switch ( agRequestType ) 668285809Sscottl { 669285809Sscottl case AGSA_SSP_INIT_READ: 670285809Sscottl case AGSA_SSP_INIT_WRITE: 671285809Sscottl case AGSA_SSP_INIT_NONDATA: 672285809Sscottl case AGSA_SSP_INIT_READ_M: 673285809Sscottl case AGSA_SSP_INIT_WRITE_M: 674285809Sscottl { 675285809Sscottl agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 676285809Sscottl 677285809Sscottl if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 678285809Sscottl#ifdef SAFLAG_USE_DIF_ENC_IOMB 679285809Sscottl (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 680285809Sscottl#endif /* SAFLAG_USE_DIF_ENC_IOMB */ 681285809Sscottl (pIRequest->flag & AGSA_SAS_ENABLE_DIF) ) 682285809Sscottl { 683285809Sscottl opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 684285809Sscottl size = IOMB_SIZE128; 685285809Sscottl } 686285809Sscottl else 687285809Sscottl { 688285809Sscottl opCode = OPC_INB_SSPINIIOSTART; 689285809Sscottl size = IOMB_SIZE64; 690285809Sscottl } 691285809Sscottl break; 692285809Sscottl } 693285809Sscottl case AGSA_SSP_INIT_READ_EXT: 694285809Sscottl case AGSA_SSP_INIT_WRITE_EXT: 695285809Sscottl case AGSA_SSP_INIT_READ_EXT_M: 696285809Sscottl case AGSA_SSP_INIT_WRITE_EXT_M: 697285809Sscottl { 698285809Sscottl agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 699285809Sscottl 700285809Sscottl if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 701285809Sscottl (pIRequest->flag & AGSA_SAS_ENABLE_DIF) || 702285809Sscottl#ifdef SAFLAG_USE_DIF_ENC_IOMB 703285809Sscottl (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 704285809Sscottl#endif /* SAFLAG_USE_DIF_ENC_IOMB */ 705285809Sscottl (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)) 706285809Sscottl { 707285809Sscottl opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 708285809Sscottl size = IOMB_SIZE128; 709285809Sscottl } 710285809Sscottl else 711285809Sscottl { 712285809Sscottl SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 713285809Sscottl opCode = OPC_INB_SSPINIEXTIOSTART; 714285809Sscottl size = IOMB_SIZE96; 715285809Sscottl } 716285809Sscottl break; 717285809Sscottl } 718285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT: 719285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT: 720285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT_M: 721285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT_M: 722285809Sscottl { 723285809Sscottl SA_DBG3(("saSSPStart: agRequestType 0x%X INDIRECT\n", agRequestType)); 724285809Sscottl opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 725285809Sscottl size = IOMB_SIZE128; 726285809Sscottl break; 727285809Sscottl } 728285809Sscottl case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT): 729285809Sscottl case AGSA_SSP_TASK_MGNT_REQ_M: 730285809Sscottl case AGSA_SSP_TGT_READ_DATA: 731285809Sscottl case AGSA_SSP_TGT_READ_GOOD_RESP: 732285809Sscottl case AGSA_SSP_TGT_WRITE_DATA: 733285809Sscottl case AGSA_SSP_TGT_WRITE_GOOD_RESP: 734285809Sscottl case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 735285809Sscottl 736285809Sscottl SA_DBG3(("saSSPStart: agRequestType 0x%X (was default)\n", agRequestType)); 737285809Sscottl opCode = OPC_INB_SSPINIIOSTART; 738285809Sscottl size = IOMB_SIZE64; 739285809Sscottl break; 740285809Sscottl default: 741285809Sscottl SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType)); 742285809Sscottl /* OpCode is not used in this case, but Linux complains if it is not initialized. */ 743285809Sscottl opCode = OPC_INB_SSPINIIOSTART; 744285809Sscottl size = IOMB_SIZE64; 745285809Sscottl break; 746285809Sscottl } 747285809Sscottl 748285809Sscottl /* If free IOMB avaliable, set up pRequest*/ 749285809Sscottl pRequest->valid = agTRUE; 750285809Sscottl pRequest->pIORequestContext = agIORequest; 751285809Sscottl pRequest->pDevice = pDevice; 752285809Sscottl pRequest->requestType = agRequestType; 753285809Sscottl pRequest->pPort = pPort; 754285809Sscottl pRequest->startTick = saRoot->timeTick; 755285809Sscottl pRequest->completionCB = agCB; 756285809Sscottl 757285809Sscottl /* Set request to the sdkData of agIORequest */ 758285809Sscottl agIORequest->sdkData = pRequest; 759285809Sscottl 760285809Sscottl /* save tag and IOrequest pointer to IOMap */ 761285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 762285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 763285809Sscottl 764285809Sscottl#ifdef SA_LL_IBQ_PROTECT 765285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 766285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 767285809Sscottl 768285809Sscottl /* Get a free inbound queue entry */ 769285809Sscottl#ifdef LOOPBACK_MPI 770285809Sscottl if (loopback) 771285809Sscottl { 772285809Sscottl SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag)); 773285809Sscottl circularOQ = &saRoot->outboundQueue[outq]; 774285809Sscottl retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage); 775285809Sscottl } 776285809Sscottl else 777285809Sscottl#endif /* LOOPBACK_MPI */ 778285809Sscottl { 779285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 780285809Sscottl retVal = mpiMsgFreeGet(circularQ, size, &pMessage); 781285809Sscottl } 782285809Sscottl 783285809Sscottl /* if message size is too large return failure */ 784285809Sscottl if (AGSA_RC_FAILURE == retVal) 785285809Sscottl { 786285809Sscottl#ifdef SA_LL_IBQ_PROTECT 787285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 788285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 789285809Sscottl /* if not sending return to free list rare */ 790285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 791285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 792285809Sscottl pRequest->valid = agFALSE; 793285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 794285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 795285809Sscottl 796285809Sscottl SA_DBG1(("saSSPStart, error when get free IOMB\n")); 797285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa"); 798285809Sscottl ret = AGSA_RC_FAILURE; 799285809Sscottl goto ext; 800285809Sscottl } 801285809Sscottl 802285809Sscottl /* return busy if inbound queue is full */ 803285809Sscottl if (AGSA_RC_BUSY == retVal) 804285809Sscottl { 805285809Sscottl#ifdef SA_LL_IBQ_PROTECT 806285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 807285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 808285809Sscottl /* if not sending return to free list rare */ 809285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 810285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 811285809Sscottl pRequest->valid = agFALSE; 812285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 813285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 814285809Sscottl 815285809Sscottl SA_DBG1(("saSSPStart, no more IOMB\n")); 816285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa"); 817285809Sscottl ret = AGSA_RC_BUSY; 818285809Sscottl goto ext; 819285809Sscottl } 820285809Sscottl SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType)); 821285809Sscottl 822285809Sscottl switch ( agRequestType ) 823285809Sscottl { 824285809Sscottl case AGSA_SSP_INIT_READ: 825285809Sscottl case AGSA_SSP_INIT_WRITE: 826285809Sscottl case AGSA_SSP_INIT_NONDATA: 827285809Sscottl case AGSA_SSP_INIT_READ_EXT: 828285809Sscottl case AGSA_SSP_INIT_WRITE_EXT: 829285809Sscottl case AGSA_SSP_INIT_READ_M: 830285809Sscottl case AGSA_SSP_INIT_WRITE_M: 831285809Sscottl case AGSA_SSP_INIT_READ_EXT_M: 832285809Sscottl case AGSA_SSP_INIT_WRITE_EXT_M: 833285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT: 834285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT: 835285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT_M: 836285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT_M: 837285809Sscottl { 838285809Sscottl if (!(agRequestType & AGSA_SSP_EXT_BIT)) 839285809Sscottl { 840285809Sscottl agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 841285809Sscottl agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 842285809Sscottl agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage; 843285809Sscottl 844285809Sscottl /* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */ 845285809Sscottl /* Be careful with the scatter/gather lists, encryption and DIF options. */ 846285809Sscottl 847285809Sscottl/* if( pIRequest->sspCmdIU.cdb[ 0] == 0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A) 848285809Sscottl { 849285809Sscottl pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) | 850285809Sscottl (pIRequest->sspCmdIU.cdb[3] << 16 ) | 851285809Sscottl (pIRequest->sspCmdIU.cdb[4] << 8 ) | 852285809Sscottl (pIRequest->sspCmdIU.cdb[5] ) ); 853285809Sscottl } 854285809Sscottl*/ 855285809Sscottl#ifdef LOOPBACK_MPI 856285809Sscottl if (loopback) 857285809Sscottl { 858285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag); 859285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS); 860285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0); 861285809Sscottl //OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0); 862285809Sscottl } 863285809Sscottl else 864285809Sscottl#endif /* LOOPBACK_MPI */ 865285809Sscottl { 866285809Sscottl /* SSPIU less equal 28 bytes */ 867285809Sscottl /* Configure DWORD 1 */ 868285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag); 869285809Sscottl /* Configure DWORD 2 */ 870285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 871285809Sscottl /* Configure DWORD 3 */ 872285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength); 873285809Sscottl } 874285809Sscottl 875285809Sscottl#ifdef SA_TESTBASE_EXTRA 876285809Sscottl /* TestBase - Set the host BST entry */ 877285809Sscottl DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16; 878285809Sscottl#endif /* SA_TESTBASE_EXTRA */ 879285809Sscottl 880285809Sscottl if (!(agRequestType & AGSA_SSP_INDIRECT_BIT)) 881285809Sscottl { 882285809Sscottl /* Configure DWORD 5-12 */ 883285809Sscottl si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit)); 884285809Sscottl pPayload->dirMTlr = 0; 885285809Sscottl /* Mask DIR for Read/Write command */ 886285809Sscottl /* Configure DWORD 4 bit 8-9 */ 887285809Sscottl DirDW4 |= agRequestType & AGSA_DIR_MASK; 888285809Sscottl } 889285809Sscottl else /* AGSA_SSP_INDIRECT_BIT was set */ 890285809Sscottl { 891285809Sscottl 892285809Sscottl agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect); 893285809Sscottl 894285809Sscottl /* Configure DWORD 5 */ 895285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32); 896285809Sscottl /* Configure DWORD 6 */ 897285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 ); 898285809Sscottl /* Configure DWORD 7 */ 899285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0); 900285809Sscottl /* Configure DWORD 8 */ 901285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0); 902285809Sscottl /* Configure DWORD 9 */ 903285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0); 904285809Sscottl /* Configure DWORD 10 */ 905285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0); 906285809Sscottl /* Configure DWORD 11 */ 907285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0); 908285809Sscottl /* Mask DIR for Read/Write command */ 909285809Sscottl /* Configure DWORD 4 bit 8-9 */ 910285809Sscottl DirDW4 |= agRequestType & AGSA_DIR_MASK; 911285809Sscottl /* Configure DWORD 4 bit 24-31 */ 912285809Sscottl DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24; 913285809Sscottl /* Configure DWORD 4 bit 4 */ 914285809Sscottl DirDW4 |= 1 << SHIFT3; 915285809Sscottl } 916285809Sscottl 917285809Sscottl /* set TLR */ 918285809Sscottl DirDW4 |= pIRequest->flag & TLR_MASK; 919285809Sscottl if (agRequestType & AGSA_MSG) 920285809Sscottl { 921285809Sscottl /* set M bit */ 922285809Sscottl DirDW4 |= AGSA_MSG_BIT; 923285809Sscottl } 924285809Sscottl 925285809Sscottl /* check for skipmask operation */ 926285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 927285809Sscottl { 928285809Sscottl DirDW4 |= AGSA_SKIP_MASK_BIT; 929285809Sscottl /* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5 */ 930285809Sscottl DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8; 931285809Sscottl } 932285809Sscottl 933285809Sscottl 934285809Sscottl /* Configure DWORDS 12-14 */ 935285809Sscottl if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA) 936285809Sscottl { 937285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 938285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 939285809Sscottl pIRequest->encrypt.EncryptionPerLAAddrLo ); 940285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 941285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 942285809Sscottl pIRequest->dif.DIFPerLAAddrLo ); 943285809Sscottl 944285809Sscottl SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal"); 945285809Sscottl 946285809Sscottl if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi ) 947285809Sscottl { 948285809Sscottl 949285809Sscottl SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" )); 950285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa"); 951285809Sscottl ret = AGSA_RC_FAILURE; 952285809Sscottl goto ext; 953285809Sscottl } 954285809Sscottl 955285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 956285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 957285809Sscottl pIRequest->encrypt.EncryptionPerLAAddrHi ); 958285809Sscottl } 959285809Sscottl else if( pIRequest->encrypt.enableEncryptionPerLA) 960285809Sscottl { 961285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 962285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 963285809Sscottl pIRequest->encrypt.EncryptionPerLAAddrLo ); 964285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 965285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 966285809Sscottl 0); 967285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 968285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 969285809Sscottl pIRequest->encrypt.EncryptionPerLAAddrHi ); 970285809Sscottl } 971285809Sscottl else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */ 972285809Sscottl { 973285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 974285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 975285809Sscottl 0); 976285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 977285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 978285809Sscottl pIRequest->dif.DIFPerLAAddrLo ); 979285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 980285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 981285809Sscottl pIRequest->dif.DIFPerLAAddrHi); 982285809Sscottl } 983285809Sscottl else /* Not EPL or DPL */ 984285809Sscottl { 985285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 986285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 987285809Sscottl 0); 988285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 989285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 990285809Sscottl 0); 991285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 992285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 993285809Sscottl 0); 994285809Sscottl } 995285809Sscottl 996285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 997285809Sscottl { 998285809Sscottl bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 999285809Sscottl bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1000285809Sscottl bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1001285809Sscottl 1002285809Sscottl SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1003285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1004285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1005285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1006285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1007285809Sscottl 1008285809Sscottl SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n", 1009285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1010285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1011285809Sscottl pIRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1012285809Sscottl 1013285809Sscottl SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1014285809Sscottl pIRequest->dif.udtArray[0], 1015285809Sscottl pIRequest->dif.udtArray[1], 1016285809Sscottl pIRequest->dif.udtArray[2], 1017285809Sscottl pIRequest->dif.udtArray[3], 1018285809Sscottl pIRequest->dif.udtArray[4], 1019285809Sscottl pIRequest->dif.udtArray[5])); 1020285809Sscottl 1021285809Sscottl SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1022285809Sscottl pIRequest->dif.udrtArray[0], 1023285809Sscottl pIRequest->dif.udrtArray[1], 1024285809Sscottl pIRequest->dif.udrtArray[2], 1025285809Sscottl pIRequest->dif.udrtArray[3], 1026285809Sscottl pIRequest->dif.udrtArray[4], 1027285809Sscottl pIRequest->dif.udrtArray[5])); 1028285809Sscottl 1029285809Sscottl SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1030285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1031285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1032285809Sscottl pIRequest->dif.DIFPerLAAddrLo, 1033285809Sscottl pIRequest->dif.DIFPerLAAddrHi)); 1034285809Sscottl 1035285809Sscottl DirDW4 |= AGSA_DIF_BIT; 1036285809Sscottl 1037285809Sscottl /* DWORD 15 */ 1038285809Sscottl SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags )); 1039285809Sscottl 1040285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1041285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags), 1042285809Sscottl pIRequest->dif.flags); 1043285809Sscottl 1044285809Sscottl /* Populate the UDT and UDTR bytes as necessary. */ 1045285809Sscottl if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1046285809Sscottl { 1047285809Sscottl UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 | 1048285809Sscottl pIRequest->dif.udtArray[0]); 1049285809Sscottl UDT5_UDT4_UDT3_UDT2 = (pIRequest->dif.udtArray[5] << SHIFT24 | 1050285809Sscottl pIRequest->dif.udtArray[4] << SHIFT16 | 1051285809Sscottl pIRequest->dif.udtArray[3] << SHIFT8 | 1052285809Sscottl pIRequest->dif.udtArray[2]); 1053285809Sscottl } 1054285809Sscottl 1055285809Sscottl if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1056285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1057285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1058285809Sscottl { 1059285809Sscottl UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 | 1060285809Sscottl pIRequest->dif.udrtArray[0] << SHIFT16 ); 1061285809Sscottl UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 | 1062285809Sscottl pIRequest->dif.udrtArray[4] << SHIFT16 | 1063285809Sscottl pIRequest->dif.udrtArray[3] << SHIFT8 | 1064285809Sscottl pIRequest->dif.udrtArray[2]); 1065285809Sscottl } 1066285809Sscottl 1067285809Sscottl /* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */ 1068285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1069285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt), 1070285809Sscottl UDTR1_UDTR0_UDT1_UDT0); 1071285809Sscottl 1072285809Sscottl /* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */ 1073285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1074285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo), 1075285809Sscottl UDT5_UDT4_UDT3_UDT2); 1076285809Sscottl 1077285809Sscottl /* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1078285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1079285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi), 1080285809Sscottl UDTR5_UDTR4_UDTR3_UDTR2); 1081285809Sscottl 1082285809Sscottl /* DWORD 19 */ 1083285809Sscottl /* Get IOS IOSeed enable bit */ 1084285809Sscottl if( pIRequest->dif.enableDIFPerLA || 1085285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) ) 1086285809Sscottl { 1087285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1088285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1089285809Sscottl ((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1090285809Sscottl (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 ))); 1091285809Sscottl } 1092285809Sscottl else 1093285809Sscottl { 1094285809Sscottl if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1095285809Sscottl { 1096285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1097285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1098285809Sscottl pIRequest->dif.initialIOSeed ); 1099285809Sscottl } 1100285809Sscottl else 1101285809Sscottl { 1102285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1103285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 0 ); 1104285809Sscottl } 1105285809Sscottl } 1106285809Sscottl } 1107285809Sscottl 1108285809Sscottl /* configure encryption */ 1109285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1110285809Sscottl { 1111285809Sscottl 1112285809Sscottl SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n", 1113285809Sscottl pIRequest->encrypt.dekInfo.dekTable, 1114285809Sscottl pIRequest->encrypt.dekInfo.dekIndex)); 1115285809Sscottl 1116285809Sscottl SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n", 1117285809Sscottl pIRequest->encrypt.kekIndex, 1118285809Sscottl pIRequest->encrypt.sectorSizeIndex, 1119285809Sscottl pIRequest->encrypt.cipherMode)); 1120285809Sscottl 1121285809Sscottl SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n", 1122285809Sscottl pIRequest->encrypt.keyTag_W0, 1123285809Sscottl pIRequest->encrypt.keyTag_W1)); 1124285809Sscottl SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n", 1125285809Sscottl pIRequest->encrypt.tweakVal_W0, 1126285809Sscottl pIRequest->encrypt.tweakVal_W1)); 1127285809Sscottl SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n", 1128285809Sscottl pIRequest->encrypt.tweakVal_W2, 1129285809Sscottl pIRequest->encrypt.tweakVal_W3)); 1130285809Sscottl 1131285809Sscottl DirDW4 |= AGSA_ENCRYPT_BIT; 1132285809Sscottl 1133285809Sscottl encryptFlags = 0; 1134285809Sscottl 1135285809Sscottl if (pIRequest->encrypt.keyTagCheck == agTRUE) 1136285809Sscottl { 1137285809Sscottl encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT; 1138285809Sscottl } 1139285809Sscottl 1140285809Sscottl if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS ) 1141285809Sscottl { 1142285809Sscottl encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4; 1143285809Sscottl } 1144285809Sscottl 1145285809Sscottl encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2; 1146285809Sscottl 1147285809Sscottl /* Always use encryption for DIF fields, skip SKPD */ 1148285809Sscottl 1149285809Sscottl encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8; 1150285809Sscottl /* Configure DWORD 20 */ 1151285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1152285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo), 1153285809Sscottl encryptFlags); 1154285809Sscottl 1155285809Sscottl encryptFlags = pIRequest->encrypt.sectorSizeIndex; 1156285809Sscottl 1157285809Sscottl encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5; 1158285809Sscottl 1159285809Sscottl encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16; 1160285809Sscottl /* Configure DWORD 21 */ 1161285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1162285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi), 1163285809Sscottl encryptFlags); 1164285809Sscottl 1165285809Sscottl /* Configure DWORD 22 */ 1166285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1167285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0), 1168285809Sscottl pIRequest->encrypt.keyTag_W0); 1169285809Sscottl /* Configure DWORD 23 */ 1170285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1171285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1), 1172285809Sscottl pIRequest->encrypt.keyTag_W1); 1173285809Sscottl 1174285809Sscottl /* Configure DWORD 24 */ 1175285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1176285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0), 1177285809Sscottl pIRequest->encrypt.tweakVal_W0); 1178285809Sscottl /* Configure DWORD 25 */ 1179285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1180285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1), 1181285809Sscottl pIRequest->encrypt.tweakVal_W1); 1182285809Sscottl /* Configure DWORD 26 */ 1183285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1184285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2), 1185285809Sscottl pIRequest->encrypt.tweakVal_W2); 1186285809Sscottl /* Configure DWORD 27 */ 1187285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1188285809Sscottl OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3), 1189285809Sscottl pIRequest->encrypt.tweakVal_W3); 1190285809Sscottl } 1191285809Sscottl 1192285809Sscottl /* Setup SGL */ 1193285809Sscottl if (pIRequest->dataLength) 1194285809Sscottl { 1195285809Sscottl pSgl = &(pIRequest->agSgl); 1196285809Sscottl 1197285809Sscottl SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode, 1198285809Sscottl pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1199285809Sscottl 1200285809Sscottl /* Get DIF PER LA flag */ 1201285809Sscottl DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0); 1202285809Sscottl DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0); 1203285809Sscottl /* Configure DWORD 4 */ 1204285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1205285809Sscottl 1206285809Sscottl if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1207285809Sscottl { 1208285809Sscottl /* Configure DWORD 28 */ 1209285809Sscottl pEncryptPayload->AddrLow0 = pSgl->sgLower; 1210285809Sscottl /* Configure DWORD 29 */ 1211285809Sscottl pEncryptPayload->AddrHi0 = pSgl->sgUpper; 1212285809Sscottl /* Configure DWORD 30 */ 1213285809Sscottl pEncryptPayload->Len0 = pSgl->len; 1214285809Sscottl /* Configure DWORD 31 */ 1215285809Sscottl pEncryptPayload->E0 = pSgl->extReserved; 1216285809Sscottl } 1217285809Sscottl else 1218285809Sscottl { 1219285809Sscottl pPayload->AddrLow0 = pSgl->sgLower; 1220285809Sscottl pPayload->AddrHi0 = pSgl->sgUpper; 1221285809Sscottl pPayload->Len0 = pSgl->len; 1222285809Sscottl pPayload->E0 = pSgl->extReserved; 1223285809Sscottl } 1224285809Sscottl } 1225285809Sscottl else 1226285809Sscottl { 1227285809Sscottl /* no data transfer */ 1228285809Sscottl /* Configure DWORD 4 */ 1229285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1230285809Sscottl 1231285809Sscottl if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1232285809Sscottl { 1233285809Sscottl pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload; 1234285809Sscottl 1235285809Sscottl pEncryptPayload->AddrLow0 = 0; 1236285809Sscottl pEncryptPayload->AddrHi0 = 0; 1237285809Sscottl pEncryptPayload->Len0 = 0; 1238285809Sscottl pEncryptPayload->E0 = 0; 1239285809Sscottl } 1240285809Sscottl else 1241285809Sscottl { 1242285809Sscottl pPayload->AddrLow0 = 0; 1243285809Sscottl pPayload->AddrHi0 = 0; 1244285809Sscottl pPayload->Len0 = 0; 1245285809Sscottl pPayload->E0 = 0; 1246285809Sscottl } 1247285809Sscottl } 1248285809Sscottl 1249285809Sscottl /* post the IOMB to SPC */ 1250285809Sscottl#ifdef LOOPBACK_MPI 1251285809Sscottl if (loopback) 1252285809Sscottl ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority); 1253285809Sscottl else 1254285809Sscottl#endif /* LOOPBACK_MPI */ 1255285809Sscottl ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority); 1256285809Sscottl if (AGSA_RC_FAILURE == ret) 1257285809Sscottl { 1258285809Sscottl SA_DBG1(("saSSPStart, error when post SSP IOMB\n")); 1259285809Sscottl ret = AGSA_RC_FAILURE; 1260285809Sscottl } 1261285809Sscottl } 1262285809Sscottl else 1263285809Sscottl { 1264285809Sscottl /* additionalCdbLen is not zero and type is Ext - use EXT mode */ 1265285809Sscottl agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 1266285809Sscottl agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage; 1267285809Sscottl bit32 sspiul; 1268285809Sscottl 1269285809Sscottl /* 1270285809Sscottl * Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. 1271285809Sscottl * Be careful with the scatter/gather lists, encryption and DIF options. 1272285809Sscottl */ 1273285809Sscottl /* CDB > 16 bytes */ 1274285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag); 1275285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1276285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength); 1277285809Sscottl /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 1278285809Sscottl /* setup standard CDB bytes + additional CDB bytes in length field */ 1279285809Sscottl sspiul = sizeof(agsaSSPCmdInfoUnit_t) + 1280285809Sscottl (pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC); 1281285809Sscottl DirDW4 = sspiul << 16; 1282285809Sscottl si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul); 1283285809Sscottl pPayload->SSPIuLendirMTlr = 0; 1284285809Sscottl 1285285809Sscottl /* Mask DIR for Read/Write command */ 1286285809Sscottl DirDW4 |= agRequestType & AGSA_DIR_MASK; 1287285809Sscottl 1288285809Sscottl /* set TLR */ 1289285809Sscottl DirDW4 |= pIRequest->flag & TLR_MASK; 1290285809Sscottl if (agRequestType & AGSA_MSG) 1291285809Sscottl { 1292285809Sscottl /* set M bit */ 1293285809Sscottl DirDW4 |= AGSA_MSG_BIT; 1294285809Sscottl } 1295285809Sscottl 1296285809Sscottl /* check for skipmask operation */ 1297285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 1298285809Sscottl { 1299285809Sscottl SA_ASSERT(0, "Mode not supported"); 1300285809Sscottl } 1301285809Sscottl 1302285809Sscottl /* configure DIF */ 1303285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 1304285809Sscottl { 1305285809Sscottl SA_ASSERT(0, "Mode not supported"); 1306285809Sscottl } 1307285809Sscottl 1308285809Sscottl /* configure encryption */ 1309285809Sscottl if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1310285809Sscottl { 1311285809Sscottl SA_ASSERT(0, "Mode not supported"); 1312285809Sscottl } 1313285809Sscottl /* Setup SGL */ 1314285809Sscottl if (pIRequest->dataLength) 1315285809Sscottl { 1316285809Sscottl pSgl = &(pIRequest->agSgl); 1317285809Sscottl 1318285809Sscottl SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n", 1319285809Sscottl pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1320285809Sscottl 1321285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1322285809Sscottl 1323285809Sscottl if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1324285809Sscottl { 1325285809Sscottl si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t)); 1326285809Sscottl } 1327285809Sscottl else 1328285809Sscottl { 1329285809Sscottl si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t)); 1330285809Sscottl } 1331285809Sscottl } 1332285809Sscottl else 1333285809Sscottl { 1334285809Sscottl /* no data transfer */ 1335285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1336285809Sscottl pPayload->dataLen = 0; 1337285809Sscottl } 1338285809Sscottl 1339285809Sscottl /* post the IOMB to SPC */ 1340285809Sscottl if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority )) 1341285809Sscottl { 1342285809Sscottl SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n")); 1343285809Sscottl ret = AGSA_RC_FAILURE; 1344285809Sscottl } 1345285809Sscottl } 1346285809Sscottl break; 1347285809Sscottl } 1348285809Sscottl case AGSA_SSP_TASK_MGNT_REQ: 1349285809Sscottl case AGSA_SSP_TASK_MGNT_REQ_M: 1350285809Sscottl { 1351285809Sscottl agsaIORequestDesc_t *pTMRequestToAbort = agNULL; 1352285809Sscottl agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage; 1353285809Sscottl 1354285809Sscottl if (agRequestType & AGSA_MSG) 1355285809Sscottl { 1356285809Sscottl /* set M bit */ 1357285809Sscottl DirDW4 = AGSA_MSG_BIT; 1358285809Sscottl } 1359285809Sscottl 1360285809Sscottl /* set DS and ADS bit */ 1361285809Sscottl DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3; 1362285809Sscottl 1363285809Sscottl /* Prepare the SSP TASK Management payload */ 1364285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag); 1365285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1366285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged); 1367285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction); 1368285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4); 1369285809Sscottl pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0]; 1370285809Sscottl pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1]; 1371285809Sscottl pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2]; 1372285809Sscottl pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3]; 1373285809Sscottl pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4]; 1374285809Sscottl pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5]; 1375285809Sscottl pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6]; 1376285809Sscottl pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7]; 1377285809Sscottl 1378285809Sscottl if (agTMRequest) 1379285809Sscottl { 1380285809Sscottl pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData; 1381285809Sscottl if (pTMRequestToAbort) 1382285809Sscottl { 1383285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag); 1384285809Sscottl } 1385285809Sscottl } 1386285809Sscottl 1387285809Sscottl SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n", 1388285809Sscottl pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId)); 1389285809Sscottl 1390285809Sscottl siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs); 1391285809Sscottl 1392285809Sscottl /* post the IOMB to SPC */ 1393285809Sscottl if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority)) 1394285809Sscottl { 1395285809Sscottl SA_DBG1(("saSSPStart, error when post TM IOMB\n")); 1396285809Sscottl ret = AGSA_RC_FAILURE; 1397285809Sscottl } 1398285809Sscottl 1399285809Sscottl break; 1400285809Sscottl } 1401285809Sscottl case AGSA_SSP_TGT_READ_DATA: 1402285809Sscottl case AGSA_SSP_TGT_READ_GOOD_RESP: 1403285809Sscottl case AGSA_SSP_TGT_WRITE_DATA: 1404285809Sscottl case AGSA_SSP_TGT_WRITE_GOOD_RESP: 1405285809Sscottl { 1406285809Sscottl agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 1407285809Sscottl agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage; 1408285809Sscottl bit32 DirDW5 = 0; 1409285809Sscottl /* Prepare the SSP TGT IO Start payload */ 1410285809Sscottl /* Configure DWORD 1 */ 1411285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag); 1412285809Sscottl /* Configure DWORD 2 */ 1413285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1414285809Sscottl /* Configure DWORD 3 */ 1415285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength); 1416285809Sscottl /* Configure DWORD 4 */ 1417285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset); 1418285809Sscottl 1419285809Sscottl SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption )); 1420285809Sscottl 1421285809Sscottl /* Mask DIR and AutoGR bits for Read/Write command */ 1422285809Sscottl DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16); 1423285809Sscottl 1424285809Sscottl if (pTRequest->sspOption & SSP_OPTION_DIF ) 1425285809Sscottl { 1426285809Sscottl bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 1427285809Sscottl bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1428285809Sscottl bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1429285809Sscottl SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1430285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1431285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1432285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1433285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1434285809Sscottl 1435285809Sscottl SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n", 1436285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1437285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1438285809Sscottl pTRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1439285809Sscottl 1440285809Sscottl SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1441285809Sscottl pTRequest->dif.udtArray[0], 1442285809Sscottl pTRequest->dif.udtArray[1], 1443285809Sscottl pTRequest->dif.udtArray[2], 1444285809Sscottl pTRequest->dif.udtArray[3], 1445285809Sscottl pTRequest->dif.udtArray[4], 1446285809Sscottl pTRequest->dif.udtArray[5])); 1447285809Sscottl 1448285809Sscottl SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1449285809Sscottl pTRequest->dif.udrtArray[0], 1450285809Sscottl pTRequest->dif.udrtArray[1], 1451285809Sscottl pTRequest->dif.udrtArray[2], 1452285809Sscottl pTRequest->dif.udrtArray[3], 1453285809Sscottl pTRequest->dif.udrtArray[4], 1454285809Sscottl pTRequest->dif.udrtArray[5])); 1455285809Sscottl 1456285809Sscottl SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1457285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1458285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1459285809Sscottl pTRequest->dif.DIFPerLAAddrLo, 1460285809Sscottl pTRequest->dif.DIFPerLAAddrHi)); 1461285809Sscottl 1462285809Sscottl DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF; 1463285809Sscottl 1464285809Sscottl 1465285809Sscottl SA_DBG3(("saSSPStart,tgt DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags )); 1466285809Sscottl 1467285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1468285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags), 1469285809Sscottl pTRequest->dif.flags); 1470285809Sscottl 1471285809Sscottl /* Populate the UDT and UDTR bytes as necessary. */ 1472285809Sscottl if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1473285809Sscottl { 1474285809Sscottl UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 | 1475285809Sscottl pTRequest->dif.udtArray[0]); 1476285809Sscottl UDT5_UDT4_UDT3_UDT2 = (pTRequest->dif.udtArray[5] << SHIFT24 | 1477285809Sscottl pTRequest->dif.udtArray[4] << SHIFT16 | 1478285809Sscottl pTRequest->dif.udtArray[3] << SHIFT8 | 1479285809Sscottl pTRequest->dif.udtArray[2]); 1480285809Sscottl } 1481285809Sscottl 1482285809Sscottl if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1483285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1484285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1485285809Sscottl { 1486285809Sscottl UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 | 1487285809Sscottl pTRequest->dif.udrtArray[0] << SHIFT16 ); 1488285809Sscottl UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 | 1489285809Sscottl pTRequest->dif.udrtArray[4] << SHIFT16 | 1490285809Sscottl pTRequest->dif.udrtArray[3] << SHIFT8 | 1491285809Sscottl pTRequest->dif.udrtArray[2]); 1492285809Sscottl } 1493285809Sscottl /* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */ 1494285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1495285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt), 1496285809Sscottl UDTR1_UDTR0_UDT1_UDT0); 1497285809Sscottl 1498285809Sscottl /* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */ 1499285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1500285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo), 1501285809Sscottl UDT5_UDT4_UDT3_UDT2); 1502285809Sscottl 1503285809Sscottl /* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1504285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1505285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi), 1506285809Sscottl UDTR5_UDTR4_UDTR3_UDTR2); 1507285809Sscottl /* DWORD 11 */ 1508285809Sscottl /* Get IOS IOSeed enable bit */ 1509285809Sscottl if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) 1510285809Sscottl { 1511285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1512285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1513285809Sscottl ((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1514285809Sscottl (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 ))); 1515285809Sscottl } 1516285809Sscottl else 1517285809Sscottl { 1518285809Sscottl /* Get IOS IOSeed enable bit */ 1519285809Sscottl if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1520285809Sscottl { 1521285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1522285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1523285809Sscottl pTRequest->dif.initialIOSeed ); 1524285809Sscottl } 1525285809Sscottl else 1526285809Sscottl { 1527285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, 1528285809Sscottl OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 0 ); 1529285809Sscottl } 1530285809Sscottl } 1531285809Sscottl } 1532285809Sscottl 1533285809Sscottl /* Mask DIR and AutoGR bits for Read/Write command */ 1534285809Sscottl if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE) 1535285809Sscottl { 1536285809Sscottl DirDW5 |= AGSA_SSP_TGT_BITS_AGR; 1537285809Sscottl } 1538285809Sscottl 1539285809Sscottl /* AN, RTE, RDF bits */ 1540285809Sscottl DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2; 1541285809Sscottl 1542285809Sscottl /* ODS */ 1543285809Sscottl if(pTRequest->sspOption & SSP_OPTION_ODS) 1544285809Sscottl { 1545285809Sscottl DirDW5 |= AGSA_SSP_TGT_BITS_ODS; 1546285809Sscottl } 1547285809Sscottl 1548285809Sscottl /* Setup SGL */ 1549285809Sscottl if (pTRequest->dataLength) 1550285809Sscottl { 1551285809Sscottl pSgl = &(pTRequest->agSgl); 1552285809Sscottl 1553285809Sscottl SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n", 1554285809Sscottl pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1555285809Sscottl 1556285809Sscottl /* set up dir on the payload */ 1557285809Sscottl /* Configure DWORD 5 */ 1558285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1559285809Sscottl 1560285809Sscottl pPayload->AddrLow0 = pSgl->sgLower; 1561285809Sscottl pPayload->AddrHi0 = pSgl->sgUpper; 1562285809Sscottl pPayload->Len0 = pSgl->len; 1563285809Sscottl pPayload->E0 = pSgl->extReserved; 1564285809Sscottl } 1565285809Sscottl else 1566285809Sscottl { 1567285809Sscottl /* no data transfer */ 1568285809Sscottl /* Configure DWORD 5 */ 1569285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1570285809Sscottl pPayload->AddrLow0 = 0; 1571285809Sscottl pPayload->AddrHi0 = 0; 1572285809Sscottl pPayload->Len0 = 0; 1573285809Sscottl } 1574285809Sscottl /* Configure DWORD 6 */ 1575285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0); 1576285809Sscottl 1577285809Sscottl /* Build TGT IO START command and send it to SPC */ 1578285809Sscottl if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority)) 1579285809Sscottl { 1580285809Sscottl SA_DBG1(("saSSPStart, error when post TGT IOMB\n")); 1581285809Sscottl ret = AGSA_RC_FAILURE; 1582285809Sscottl } 1583285809Sscottl 1584285809Sscottl break; 1585285809Sscottl } 1586285809Sscottl case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 1587285809Sscottl { 1588285809Sscottl agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 1589285809Sscottl agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage; 1590285809Sscottl bit32 ip, an, ods; 1591285809Sscottl 1592285809Sscottl if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)) 1593285809Sscottl { 1594285809Sscottl ip = 1; 1595285809Sscottl si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength); 1596285809Sscottl } 1597285809Sscottl else 1598285809Sscottl { 1599285809Sscottl ip = 0; 1600285809Sscottl /* NOTE: 1601285809Sscottl * 1. reserved field must be ZEROED out. FW depends on it 1602285809Sscottl * 2. trusted interface. indirect response buffer must be valid. 1603285809Sscottl */ 1604285809Sscottl si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved)); 1605285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower); 1606285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper); 1607285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength); 1608285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0); 1609285809Sscottl } 1610285809Sscottl 1611285809Sscottl /* TLR setting */ 1612285809Sscottl an = (pTResponse->respOption & RESP_OPTION_BITS); 1613285809Sscottl /* ODS */ 1614285809Sscottl ods = (pTResponse->respOption & RESP_OPTION_ODS); 1615285809Sscottl 1616285809Sscottl /* Prepare the SSP TGT RESPONSE Start payload */ 1617285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag); 1618285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1619285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength); 1620285809Sscottl OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN), 1621285809Sscottl (pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2)); 1622285809Sscottl 1623285809Sscottl /* Build TGT RESPONSE START command and send it to SPC */ 1624285809Sscottl if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority)) 1625285809Sscottl { 1626285809Sscottl SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n")); 1627285809Sscottl ret = AGSA_RC_FAILURE; 1628285809Sscottl } 1629285809Sscottl 1630285809Sscottl break; 1631285809Sscottl } 1632285809Sscottl default: 1633285809Sscottl { 1634285809Sscottl SA_DBG1(("saSSPStart, Unsupported Request IOMB\n")); 1635285809Sscottl ret = AGSA_RC_FAILURE; 1636285809Sscottl break; 1637285809Sscottl } 1638285809Sscottl } 1639285809Sscottl 1640285809Sscottl } /* LL IOrequest available */ 1641285809Sscottl 1642285809Sscottl#ifdef SA_LL_IBQ_PROTECT 1643285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1644285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 1645285809Sscottl 1646285809Sscottl#ifdef SALL_API_TEST 1647285809Sscottl if (ret == AGSA_RC_SUCCESS) 1648285809Sscottl saRoot->LLCounters.IOCounter.numSSPStarted++; 1649285809Sscottl#endif /*SALL_API_TEST */ 1650285809Sscottl 1651285809Sscottl#ifdef LOOPBACK_MPI 1652285809Sscottl if (loopback) 1653285809Sscottl saRoot->interruptVecIndexBitMap[0] |= (1 << outq); 1654285809Sscottl#endif /* LOOPBACK_MPI */ 1655285809Sscottl /* goto have leave and trace point info */ 1656285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa"); 1657285809Sscottlext: 1658285809Sscottl 1659285809Sscottl OSSA_INP_LEAVE(agRoot); 1660285809Sscottl return ret; 1661285809Sscottl} 1662285809Sscottl 1663285809Sscottl/******************************************************************************/ 1664285809Sscottl/*! \brief Abort SSP request 1665285809Sscottl * 1666285809Sscottl * Abort SSP request 1667285809Sscottl * 1668285809Sscottl * \param agRoot handles for this instance of SAS/SATA LLL 1669285809Sscottl * \param queueNum 1670285809Sscottl * \param agIORequest 1671285809Sscottl * \param agIOToBeAborted 1672285809Sscottl * 1673285809Sscottl * \return If request is aborted successfully 1674285809Sscottl * - \e AGSA_RC_SUCCESS request is aborted successfully 1675285809Sscottl * - \e AGSA_RC_FAILURE request is not aborted successfully 1676285809Sscottl */ 1677285809Sscottl/*******************************************************************************/ 1678285809SscottlGLOBAL bit32 saSSPAbort( 1679285809Sscottl agsaRoot_t *agRoot, 1680285809Sscottl agsaIORequest_t *agIORequest, 1681285809Sscottl bit32 queueNum, 1682285809Sscottl agsaDevHandle_t *agDevHandle, 1683285809Sscottl bit32 flag, 1684285809Sscottl void *abortParam, 1685285809Sscottl ossaGenericAbortCB_t agCB 1686285809Sscottl ) 1687285809Sscottl{ 1688285809Sscottl bit32 ret = AGSA_RC_SUCCESS, retVal; 1689285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 1690285809Sscottl agsaIORequestDesc_t *pRequest; 1691285809Sscottl agsaIORequestDesc_t *pRequestABT = NULL; 1692285809Sscottl agsaDeviceDesc_t *pDevice = NULL; 1693285809Sscottl agsaDeviceDesc_t *pDeviceABT = NULL; 1694285809Sscottl agsaPort_t *pPort = NULL; 1695285809Sscottl mpiICQueue_t *circularQ; 1696285809Sscottl void *pMessage; 1697285809Sscottl agsaSSPAbortCmd_t *payload; 1698285809Sscottl agsaIORequest_t *agIOToBeAborted; 1699285809Sscottl bit8 inq, outq; 1700285809Sscottl bit32 using_reserved = agFALSE; 1701285809Sscottl bit32 flag_copy = flag; 1702285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb"); 1703285809Sscottl 1704285809Sscottl /* sanity check */ 1705285809Sscottl SA_ASSERT((agNULL != agRoot), ""); 1706285809Sscottl SA_ASSERT((agNULL != agIORequest), ""); 1707285809Sscottl 1708285809Sscottl SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag)); 1709285809Sscottl 1710285809Sscottl /* Assign inbound and outbound Buffer */ 1711285809Sscottl inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 1712285809Sscottl outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 1713285809Sscottl SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 1714285809Sscottl 1715285809Sscottl#ifdef SA_PRINTOUT_IN_WINDBG 1716285809Sscottl#ifndef DBG 1717285809Sscottl DbgPrint("saSSPAbort flag %d\n", flag ); 1718285809Sscottl#endif /* DBG */ 1719285809Sscottl#endif /* SA_PRINTOUT_IN_WINDBG */ 1720285809Sscottl 1721285809Sscottl if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1722285809Sscottl { 1723285809Sscottl agIOToBeAborted = (agsaIORequest_t *)abortParam; 1724285809Sscottl /* Get LL IORequest entry for saSSPAbort() */ 1725285809Sscottl pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1726285809Sscottl if (agNULL == pRequest) 1727285809Sscottl { 1728285809Sscottl /* no pRequest found - can not Abort */ 1729285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n")); 1730285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb"); 1731285809Sscottl return AGSA_RC_FAILURE; 1732285809Sscottl } 1733285809Sscottl /* Find the device the request sent to */ 1734285809Sscottl pDevice = pRequest->pDevice; 1735285809Sscottl /* Get LL IORequest entry for IOToBeAborted */ 1736285809Sscottl pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1737285809Sscottl if (agNULL == pRequestABT) 1738285809Sscottl { 1739285809Sscottl /* The IO to Be Abort is no longer exist */ 1740285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n")); 1741285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb"); 1742285809Sscottl return AGSA_RC_FAILURE; 1743285809Sscottl } 1744285809Sscottl /* Find the device the request Abort to */ 1745285809Sscottl pDeviceABT = pRequestABT->pDevice; 1746285809Sscottl 1747285809Sscottl if (agNULL == pDeviceABT) 1748285809Sscottl { 1749285809Sscottl /* no deviceID - can not build IOMB */ 1750285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n")); 1751285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb"); 1752285809Sscottl return AGSA_RC_FAILURE; 1753285809Sscottl } 1754285809Sscottl 1755285809Sscottl if (agNULL != pDevice) 1756285809Sscottl { 1757285809Sscottl /* Find the port the request was sent to */ 1758285809Sscottl pPort = pDevice->pPort; 1759285809Sscottl } 1760285809Sscottl else 1761285809Sscottl { 1762285809Sscottl /* no deviceID - can not build IOMB */ 1763285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n")); 1764285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb"); 1765285809Sscottl return AGSA_RC_FAILURE; 1766285809Sscottl } 1767285809Sscottl 1768285809Sscottl /* Get request from free IORequests */ 1769285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1770285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1771285809Sscottl } 1772285809Sscottl else 1773285809Sscottl { 1774285809Sscottl if (ABORT_ALL == (flag & ABORT_MASK)) 1775285809Sscottl { 1776285809Sscottl /* abort All with Device or Port */ 1777285809Sscottl /* Find the outgoing port for the device */ 1778285809Sscottl if (agDevHandle == agNULL) 1779285809Sscottl { 1780285809Sscottl /* no deviceID - can not build IOMB */ 1781285809Sscottl SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n")); 1782285809Sscottl return AGSA_RC_FAILURE; 1783285809Sscottl } 1784285809Sscottl pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 1785285809Sscottl if (agNULL == pDevice) 1786285809Sscottl { 1787285809Sscottl /* no deviceID - can not build IOMB */ 1788285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n")); 1789285809Sscottl return AGSA_RC_FAILURE; 1790285809Sscottl } 1791285809Sscottl pPort = pDevice->pPort; 1792285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1793285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1794285809Sscottl } 1795285809Sscottl else 1796285809Sscottl { 1797285809Sscottl /* only support 00, 01 and 02 for flag */ 1798285809Sscottl SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag)); 1799285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb"); 1800285809Sscottl return AGSA_RC_FAILURE; 1801285809Sscottl } 1802285809Sscottl } 1803285809Sscottl 1804285809Sscottl if ( agNULL == pRequest ) 1805285809Sscottl { 1806285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 1807285809Sscottl if(agNULL != pRequest) 1808285809Sscottl { 1809285809Sscottl using_reserved = agTRUE; 1810285809Sscottl SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n")); 1811285809Sscottl } 1812285809Sscottl else 1813285809Sscottl { 1814285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1815285809Sscottl /* If no LL IO request entry available */ 1816285809Sscottl SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n")); 1817285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb"); 1818285809Sscottl return AGSA_RC_BUSY; 1819285809Sscottl } 1820285809Sscottl } 1821285809Sscottl 1822285809Sscottl /* If free IOMB avaliable */ 1823285809Sscottl /* Remove the request from free list */ 1824285809Sscottl if( using_reserved ) 1825285809Sscottl { 1826285809Sscottl saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1827285809Sscottl } 1828285809Sscottl else 1829285809Sscottl { 1830285809Sscottl saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1831285809Sscottl } 1832285809Sscottl 1833285809Sscottl /* Add the request to the pendingIORequests list of the device */ 1834285809Sscottl pRequest->valid = agTRUE; 1835285809Sscottl saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1836285809Sscottl 1837285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1838285809Sscottl 1839285809Sscottl /* set up pRequest */ 1840285809Sscottl pRequest->pIORequestContext = agIORequest; 1841285809Sscottl pRequest->requestType = AGSA_SSP_REQTYPE; 1842285809Sscottl pRequest->pDevice = pDevice; 1843285809Sscottl pRequest->pPort = pPort; 1844285809Sscottl pRequest->completionCB = (void*)agCB; 1845285809Sscottl/* pRequest->abortCompletionCB = agCB;*/ 1846285809Sscottl pRequest->startTick = saRoot->timeTick; 1847285809Sscottl 1848285809Sscottl /* Set request to the sdkData of agIORequest */ 1849285809Sscottl agIORequest->sdkData = pRequest; 1850285809Sscottl 1851285809Sscottl /* save tag and IOrequest pointer to IOMap */ 1852285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1853285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1854285809Sscottl 1855285809Sscottl 1856285809Sscottl#ifdef SA_LL_IBQ_PROTECT 1857285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1858285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 1859285809Sscottl 1860285809Sscottl /* If LL IO request entry avaliable */ 1861285809Sscottl /* Get a free inbound queue entry */ 1862285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 1863285809Sscottl retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage); 1864285809Sscottl 1865285809Sscottl /* if message size is too large return failure */ 1866285809Sscottl if (AGSA_RC_FAILURE == retVal) 1867285809Sscottl { 1868285809Sscottl#ifdef SA_LL_IBQ_PROTECT 1869285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1870285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 1871285809Sscottl 1872285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1873285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1874285809Sscottl pRequest->valid = agFALSE; 1875285809Sscottl if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1876285809Sscottl { 1877285809Sscottl SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1878285809Sscottl saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1879285809Sscottl } 1880285809Sscottl else 1881285809Sscottl { 1882285809Sscottl /* return the request to free pool */ 1883285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1884285809Sscottl } 1885285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1886285809Sscottl 1887285809Sscottl SA_DBG1(("saSSPAbort: error when get free IOMB\n")); 1888285809Sscottl 1889285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb"); 1890285809Sscottl return AGSA_RC_FAILURE; 1891285809Sscottl } 1892285809Sscottl 1893285809Sscottl /* return busy if inbound queue is full */ 1894285809Sscottl if (AGSA_RC_BUSY == retVal) 1895285809Sscottl { 1896285809Sscottl#ifdef SA_LL_IBQ_PROTECT 1897285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1898285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 1899285809Sscottl 1900285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1901285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1902285809Sscottl pRequest->valid = agFALSE; 1903285809Sscottl if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1904285809Sscottl { 1905285809Sscottl SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1906285809Sscottl saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1907285809Sscottl } 1908285809Sscottl else 1909285809Sscottl { 1910285809Sscottl /* return the request to free pool */ 1911285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1912285809Sscottl } 1913285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1914285809Sscottl 1915285809Sscottl SA_DBG1(("saSSPAbort: no more IOMB\n")); 1916285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb"); 1917285809Sscottl return AGSA_RC_BUSY; 1918285809Sscottl } 1919285809Sscottl 1920285809Sscottl /* setup payload */ 1921285809Sscottl payload = (agsaSSPAbortCmd_t*)pMessage; 1922285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag); 1923285809Sscottl 1924285809Sscottl if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1925285809Sscottl { 1926285809Sscottl if ( agNULL == pDeviceABT ) 1927285809Sscottl { 1928285809Sscottl SA_DBG1(("saSSPSAbort: no device\n" )); 1929285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb"); 1930285809Sscottl return AGSA_RC_FAILURE; 1931285809Sscottl } 1932285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex); 1933285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag); 1934285809Sscottl } 1935285809Sscottl else 1936285809Sscottl { 1937285809Sscottl /* abort all */ 1938285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex); 1939285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0); 1940285809Sscottl } 1941285809Sscottl 1942285809Sscottl if(flag & ABORT_TSDK_QUARANTINE) 1943285809Sscottl { 1944285809Sscottl if(smIS_SPCV(agRoot)) 1945285809Sscottl { 1946285809Sscottl flag_copy &= ABORT_SCOPE; 1947285809Sscottl flag_copy |= ABORT_QUARANTINE_SPCV; 1948285809Sscottl } 1949285809Sscottl } 1950285809Sscottl OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy); 1951285809Sscottl 1952285809Sscottl SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag)); 1953285809Sscottl 1954285809Sscottl siCountActiveIORequestsOnDevice( agRoot, payload->deviceId ); 1955285809Sscottl 1956285809Sscottl /* post the IOMB to SPC */ 1957285809Sscottl ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority); 1958285809Sscottl 1959285809Sscottl#ifdef SA_LL_IBQ_PROTECT 1960285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1961285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 1962285809Sscottl 1963285809Sscottl#ifdef SALL_API_TEST 1964285809Sscottl if (AGSA_RC_SUCCESS == ret) 1965285809Sscottl { 1966285809Sscottl saRoot->LLCounters.IOCounter.numSSPAborted++; 1967285809Sscottl } 1968285809Sscottl#endif 1969285809Sscottl 1970285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb"); 1971285809Sscottl 1972285809Sscottl return ret; 1973285809Sscottl} 1974285809Sscottl 1975285809Sscottl 1976285809Sscottl#if defined(SALLSDK_DEBUG) 1977285809Sscottl/******************************************************************************/ 1978285809Sscottl/*! \brief 1979285809Sscottl * 1980285809Sscottl * Dump StartSSP information 1981285809Sscottl * 1982285809Sscottl * Debug helper routine 1983285809Sscottl * 1984285809Sscottl * \return -none - 1985285809Sscottl */ 1986285809Sscottl/*******************************************************************************/ 1987285809SscottlLOCAL void siDumpSSPStartIu( 1988285809Sscottl agsaDevHandle_t *agDevHandle, 1989285809Sscottl bit32 agRequestType, 1990285809Sscottl agsaSASRequestBody_t *agRequestBody 1991285809Sscottl ) 1992285809Sscottl { 1993285809Sscottl switch ( agRequestType ) 1994285809Sscottl { 1995285809Sscottl case AGSA_SSP_INIT_READ: 1996285809Sscottl case AGSA_SSP_INIT_WRITE: 1997285809Sscottl { 1998285809Sscottl agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 1999285809Sscottl 2000285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2001285809Sscottl agDevHandle, 2002285809Sscottl (agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE", 2003285809Sscottl pIRequest->dataLength, 2004285809Sscottl pIRequest->sspCmdIU.efb_tp_taskAttribute, 2005285809Sscottl pIRequest->sspCmdIU.cdb[0], 2006285809Sscottl pIRequest->sspCmdIU.cdb[1], 2007285809Sscottl pIRequest->sspCmdIU.cdb[2], 2008285809Sscottl pIRequest->sspCmdIU.cdb[3], 2009285809Sscottl pIRequest->sspCmdIU.cdb[4], 2010285809Sscottl pIRequest->sspCmdIU.cdb[5], 2011285809Sscottl pIRequest->sspCmdIU.cdb[6], 2012285809Sscottl pIRequest->sspCmdIU.cdb[7], 2013285809Sscottl pIRequest->sspCmdIU.cdb[8], 2014285809Sscottl pIRequest->sspCmdIU.cdb[9] 2015285809Sscottl )); 2016285809Sscottl break; 2017285809Sscottl } 2018285809Sscottl 2019285809Sscottl case AGSA_SSP_INIT_READ_EXT: 2020285809Sscottl case AGSA_SSP_INIT_WRITE_EXT: 2021285809Sscottl { 2022285809Sscottl agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2023285809Sscottl 2024285809Sscottl SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2025285809Sscottl agDevHandle, 2026285809Sscottl (agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT", 2027285809Sscottl pIRequest->dataLength, 2028285809Sscottl pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2029285809Sscottl pIRequest->sspCmdIUExt.cdb[0], 2030285809Sscottl pIRequest->sspCmdIUExt.cdb[1], 2031285809Sscottl pIRequest->sspCmdIUExt.cdb[2], 2032285809Sscottl pIRequest->sspCmdIUExt.cdb[3], 2033285809Sscottl pIRequest->sspCmdIUExt.cdb[4], 2034285809Sscottl pIRequest->sspCmdIUExt.cdb[5], 2035285809Sscottl pIRequest->sspCmdIUExt.cdb[6], 2036285809Sscottl pIRequest->sspCmdIUExt.cdb[7], 2037285809Sscottl pIRequest->sspCmdIUExt.cdb[8], 2038285809Sscottl pIRequest->sspCmdIUExt.cdb[9] 2039285809Sscottl )); 2040285809Sscottl break; 2041285809Sscottl } 2042285809Sscottl 2043285809Sscottl case AGSA_SSP_INIT_READ_EXT_M: 2044285809Sscottl case AGSA_SSP_INIT_WRITE_EXT_M: 2045285809Sscottl { 2046285809Sscottl agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2047285809Sscottl 2048285809Sscottl SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2049285809Sscottl agDevHandle, 2050285809Sscottl (agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M", 2051285809Sscottl pIRequest->dataLength, 2052285809Sscottl pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2053285809Sscottl pIRequest->sspCmdIUExt.cdb[0], 2054285809Sscottl pIRequest->sspCmdIUExt.cdb[1], 2055285809Sscottl pIRequest->sspCmdIUExt.cdb[2], 2056285809Sscottl pIRequest->sspCmdIUExt.cdb[3], 2057285809Sscottl pIRequest->sspCmdIUExt.cdb[4], 2058285809Sscottl pIRequest->sspCmdIUExt.cdb[5], 2059285809Sscottl pIRequest->sspCmdIUExt.cdb[6], 2060285809Sscottl pIRequest->sspCmdIUExt.cdb[7], 2061285809Sscottl pIRequest->sspCmdIUExt.cdb[8], 2062285809Sscottl pIRequest->sspCmdIUExt.cdb[9] 2063285809Sscottl )); 2064285809Sscottl break; 2065285809Sscottl } 2066285809Sscottl 2067285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT: 2068285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT: 2069285809Sscottl case AGSA_SSP_INIT_READ_INDIRECT_M: 2070285809Sscottl case AGSA_SSP_INIT_WRITE_INDIRECT_M: 2071285809Sscottl { 2072285809Sscottl agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect); 2073285809Sscottl 2074285809Sscottl SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n", 2075285809Sscottl agDevHandle, 2076285809Sscottl (agRequestType==AGSA_SSP_INIT_READ_INDIRECT || 2077285809Sscottl agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT", 2078285809Sscottl pIRequest->dataLength, 2079285809Sscottl pIRequest->sspInitiatorReqLen, 2080285809Sscottl pIRequest->sspInitiatorReqAddrUpper32, 2081285809Sscottl pIRequest->sspInitiatorReqAddrLower32 )); 2082285809Sscottl break; 2083285809Sscottl } 2084285809Sscottl 2085285809Sscottl 2086285809Sscottl case AGSA_SSP_TASK_MGNT_REQ: 2087285809Sscottl { 2088285809Sscottl agsaSSPScsiTaskMgntReq_t *pTaskCmd =&agRequestBody->sspTaskMgntReq; 2089285809Sscottl /* copy payload */ 2090285809Sscottl 2091285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x", 2092285809Sscottl agDevHandle, 2093285809Sscottl "AGSA_SSP_TASK_MGNT_REQ", 2094285809Sscottl pTaskCmd->taskMgntFunction, 2095285809Sscottl pTaskCmd->tagOfTaskToBeManaged 2096285809Sscottl )); 2097285809Sscottl break; 2098285809Sscottl } 2099285809Sscottl case AGSA_SSP_TGT_READ_DATA: 2100285809Sscottl { 2101285809Sscottl agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2102285809Sscottl 2103285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2104285809Sscottl agDevHandle, 2105285809Sscottl "AGSA_SSP_TGT_READ_DATA", 2106285809Sscottl pTRequest->dataLength, 2107285809Sscottl pTRequest->offset )); 2108285809Sscottl break; 2109285809Sscottl } 2110285809Sscottl case AGSA_SSP_TGT_READ_GOOD_RESP: 2111285809Sscottl { 2112285809Sscottl agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2113285809Sscottl 2114285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2115285809Sscottl agDevHandle, 2116285809Sscottl "AGSA_SSP_TGT_READ_GOOD_RESP", 2117285809Sscottl pTRequest->dataLength, 2118285809Sscottl pTRequest->offset)); 2119285809Sscottl break; 2120285809Sscottl } 2121285809Sscottl case AGSA_SSP_TGT_WRITE_GOOD_RESP: 2122285809Sscottl { 2123285809Sscottl agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2124285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2125285809Sscottl agDevHandle, 2126285809Sscottl "AGSA_SSP_TGT_WRITE_GOOD_RESP", 2127285809Sscottl pTRequest->dataLength, 2128285809Sscottl pTRequest->offset )); 2129285809Sscottl 2130285809Sscottl break; 2131285809Sscottl } 2132285809Sscottl case AGSA_SSP_TGT_WRITE_DATA: 2133285809Sscottl { 2134285809Sscottl agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2135285809Sscottl 2136285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2137285809Sscottl agDevHandle, 2138285809Sscottl "AGSA_SSP_TGT_WRITE_DATA", 2139285809Sscottl pTRequest->dataLength, 2140285809Sscottl pTRequest->offset )); 2141285809Sscottl break; 2142285809Sscottl } 2143285809Sscottl case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 2144285809Sscottl { 2145285809Sscottl agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 2146285809Sscottl 2147285809Sscottl SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x Tag=%x\n", 2148285809Sscottl agDevHandle, 2149285809Sscottl "AGSA_SSP_TGT_CMD_OR_TASK_RSP", 2150285809Sscottl pTResponse->respBufLength, 2151285809Sscottl pTResponse->respBufUpper, 2152285809Sscottl pTResponse->respBufLower, 2153285809Sscottl pTResponse->agTag )); 2154285809Sscottl break; 2155285809Sscottl } 2156285809Sscottl 2157285809Sscottl default: 2158285809Sscottl { 2159285809Sscottl SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n", 2160285809Sscottl agDevHandle, 2161285809Sscottl "Unknown SSP cmd type", 2162285809Sscottl agRequestType 2163285809Sscottl )); 2164285809Sscottl break; 2165285809Sscottl } 2166285809Sscottl } 2167285809Sscottl return; 2168285809Sscottl} 2169285809Sscottl#endif /* SALLSDK_DEBUG */ 2170