1 /******************************************************************************* 2 ** 3 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4 * 5 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 *that the following conditions are met: 7 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 8 *following disclaimer. 9 *2. Redistributions in binary form must reproduce the above copyright notice, 10 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 11 *with the distribution. 12 * 13 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 15 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 18 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 19 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 21 22 ********************************************************************************/ 23 /*******************************************************************************/ 24 /*! \file sassp.c 25 * \brief The file implements the functions for SSP request/response 26 * 27 */ 28 /*******************************************************************************/ 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 #include <dev/pms/config.h> 32 33 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 34 #ifdef SA_ENABLE_TRACE_FUNCTIONS 35 #ifdef siTraceFileID 36 #undef siTraceFileID 37 #endif 38 #define siTraceFileID 'O' 39 #endif 40 41 #ifdef LOOPBACK_MPI 42 extern int loopback; 43 #endif 44 45 #ifdef SALLSDK_DEBUG 46 LOCAL void siDumpSSPStartIu( 47 agsaDevHandle_t *agDevHandle, 48 bit32 agRequestType, 49 agsaSASRequestBody_t *agRequestBody 50 ); 51 #endif 52 53 #ifdef FAST_IO_TEST 54 LOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot, 55 bit32 queueNum) 56 { 57 bit8 inq; 58 mpiICQueue_t *circularQ; 59 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 60 61 inq = INQ(queueNum); 62 circularQ = &saRoot->inboundQueue[inq]; 63 return circularQ->producerIdx; 64 } 65 66 LOCAL void saSetIBQPI(agsaRoot_t *agRoot, 67 bit32 queueNum, 68 bit32 pi) 69 { 70 bit8 inq; 71 mpiICQueue_t *circularQ; 72 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 73 74 inq = INQ(queueNum); 75 circularQ = &saRoot->inboundQueue[inq]; 76 circularQ->producerIdx = pi; 77 } 78 79 osLOCAL void* 80 siFastSSPReqAlloc(agsaRoot_t *agRoot) 81 { 82 int idx; 83 agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 84 saFastRequest_t *fr; 85 86 if (!saRoot->freeFastIdx) 87 { 88 SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n")); 89 SA_ASSERT((0), ""); 90 return 0; 91 } 92 93 ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 94 saRoot->freeFastIdx--; 95 idx = saRoot->freeFastIdx; 96 ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 97 98 fr = saRoot->freeFastReq[idx]; 99 SA_ASSERT((fr), ""); 100 fr->valid = 1; 101 102 return fr; 103 } 104 105 LOCAL void 106 siFastSSPReqFree( 107 agsaRoot_t *agRoot, 108 void *freq) 109 { 110 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 111 saFastRequest_t *fr = (saFastRequest_t*)freq; 112 113 SA_DBG2(("siFastSSPReqFree: enter\n")); 114 SA_ASSERT((fr->valid), ""); 115 if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) / 116 sizeof(saRoot->freeFastReq[0])) 117 { 118 SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n", 119 saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) / 120 sizeof(saRoot->freeFastReq[0])))); 121 SA_ASSERT((0), ""); 122 return; 123 } 124 ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK); 125 /* not need if only one entry */ 126 /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq; */ 127 saRoot->freeFastIdx++; 128 ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK); 129 130 fr->valid = 0; 131 SA_DBG6(("siFastSSPReqFree: leave\n")); 132 } 133 134 LOCAL bit32 siFastSSPResAlloc( 135 agsaRoot_t *agRoot, 136 bit32 queueNum, 137 bit32 agRequestType, 138 agsaDeviceDesc_t *pDevice, 139 agsaIORequestDesc_t **pRequest, 140 void **pPayload 141 ) 142 { 143 agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 144 mpiICQueue_t *circularQ; 145 bit8 inq; 146 bit16 size = IOMB_SIZE64; 147 bit32 ret = AGSA_RC_SUCCESS, retVal; 148 149 smTraceFuncEnter(hpDBG_VERY_LOUD,"2D"); 150 151 SA_DBG4(("Entering function siFastSSPResAlloc:\n")); 152 153 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 154 *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests); 155 156 /* If no LL IO request entry available */ 157 if (agNULL == *pRequest ) 158 { 159 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 160 SA_DBG1(("siFastSSPResAlloc: No request from free list\n" )); 161 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D"); 162 ret = AGSA_RC_BUSY; 163 goto ext; 164 } 165 166 /* Get IO request from free IORequests */ 167 /* Assign inbound and outbound Buffer */ 168 inq = INQ(queueNum); 169 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 170 171 /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */ 172 if (agRequestType & AGSA_SSP_EXT_BIT) 173 { 174 size = IOMB_SIZE96; 175 } 176 /* If LL IO request entry avaliable */ 177 /* Get a free inbound queue entry */ 178 circularQ = &saRoot->inboundQueue[inq]; 179 retVal = mpiMsgFreeGet(circularQ, size, pPayload); 180 181 /* if message size is too large return failure */ 182 if (AGSA_RC_SUCCESS != retVal) 183 { 184 if (AGSA_RC_FAILURE == retVal) 185 { 186 SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n")); 187 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D"); 188 } 189 190 /* return busy if inbound queue is full */ 191 if (AGSA_RC_BUSY == retVal) 192 { 193 SA_DBG3(("siFastSSPResAlloc: no more IOMB\n")); 194 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D"); 195 } 196 ret = retVal; 197 goto ext; 198 } 199 200 /* But add it to the pending queue during FastStart */ 201 /* If free IOMB avaliable */ 202 /* Remove the request from free list */ 203 saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode); 204 205 /* Add the request to the pendingIORequests list of the device */ 206 saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode); 207 208 ext: 209 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 210 211 if (AGSA_RC_SUCCESS == ret) 212 { 213 /* save tag and IOrequest pointer to IOMap */ 214 saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag; 215 saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest; 216 } 217 218 return ret; 219 } /* siFastSSPResAlloc */ 220 221 222 GLOBAL bit32 saFastSSPCancel(void *ioHandle) 223 { 224 agsaRoot_t *agRoot; 225 agsaLLRoot_t *saRoot; 226 saFastRequest_t *fr; 227 bit32 i; 228 agsaIORequestDesc_t *ior; 229 230 SA_ASSERT((ioHandle), ""); 231 fr = (saFastRequest_t*)ioHandle; 232 SA_ASSERT((fr->valid), ""); 233 agRoot = (agsaRoot_t*)fr->agRoot; 234 SA_ASSERT((agRoot), ""); 235 saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 236 SA_ASSERT((saRoot), ""); 237 238 smTraceFuncEnter(hpDBG_VERY_LOUD,"2E"); 239 240 /* rollback the previously set IBQ PI */ 241 for (i = 0; i < fr->inqMax - 1; i++) 242 saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]); 243 244 /* free all the previous Fast IO Requests */ 245 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 246 /* at least one entry, no need to check for NULL saLlistIOGetHead() */ 247 ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) - 248 OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 249 do 250 { 251 agsaDeviceDesc_t *pDevice; 252 void *tmp; 253 254 pDevice = ior->pDevice; 255 saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode); 256 saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode); 257 258 tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink); 259 if (!tmp) 260 { 261 break; /* end of list */ 262 } 263 ior = (agsaIORequestDesc_t*)((char*)tmp - 264 OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink)); 265 } while (1); 266 267 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 268 269 /* free the IBQ PI tracking struct */ 270 siFastSSPReqFree(agRoot, fr); 271 272 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E"); 273 return AGSA_RC_SUCCESS; 274 } /* saFastSSPCancel */ 275 276 GLOBAL void *saFastSSPPrepare( 277 void *ioh, 278 agsaFastCommand_t *fc, 279 ossaSSPCompletedCB_t cb, 280 void *cbArg) 281 { 282 bit32 ret = AGSA_RC_SUCCESS; 283 agsaRoot_t *agRoot; 284 agsaLLRoot_t *saRoot; 285 mpiICQueue_t *circularQ; 286 agsaDeviceDesc_t *pDevice; 287 agsaSgl_t *pSgl; 288 bit32 Dir = 0; 289 bit8 inq, outq; 290 saFastRequest_t *fr; 291 void *pMessage; 292 agsaIORequestDesc_t *pRequest; 293 bit16 opCode; 294 bitptr offsetTag; 295 bitptr offsetDeviceId; 296 bitptr offsetDataLen; 297 bitptr offsetDir; 298 299 agRoot = (agsaRoot_t*)fc->agRoot; 300 smTraceFuncEnter(hpDBG_VERY_LOUD,"2G"); 301 302 OSSA_INP_ENTER(agRoot); 303 304 saRoot = (agsaLLRoot_t*)(agRoot->sdkData); 305 /* sanity check */ 306 SA_ASSERT((agNULL != saRoot), ""); 307 308 SA_DBG4(("Entering function saFastSSPPrepare:\n")); 309 310 fr = (saFastRequest_t*)ioh; 311 if (!fr) 312 { 313 int i; 314 fr = siFastSSPReqAlloc(agRoot); 315 if (!fr) 316 { 317 SA_ASSERT((0), ""); 318 goto ext; 319 } 320 321 saLlistIOInitialize(&fr->requests); 322 for (i = 0; i < AGSA_MAX_INBOUND_Q; i++) 323 fr->beforePI[i] = (bit32)-1; 324 325 fr->inqMax = 0; 326 fr->agRoot = agRoot; 327 ioh = fr; 328 } 329 330 /* Find the outgoing port for the device */ 331 pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData); 332 333 ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType, 334 pDevice, &pRequest, &pMessage); 335 if (ret != AGSA_RC_SUCCESS) 336 { 337 SA_ASSERT((0), ""); 338 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G"); 339 goto ext; 340 } 341 342 /* Assign inbound and outbound Buffer */ 343 inq = INQ(fc->queueNum); 344 outq = OUQ(fc->queueNum); 345 circularQ = &saRoot->inboundQueue[inq]; 346 347 SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex)); 348 349 /* set up pRequest */ 350 pRequest->valid = agTRUE; 351 pRequest->pDevice = pDevice; 352 pRequest->requestType = fc->agRequestType; 353 354 pRequest->completionCB = cb; 355 pRequest->pIORequestContext = (agsaIORequest_t*)cbArg; 356 357 pSgl = fc->agSgl; 358 359 switch (fc->agRequestType) 360 { 361 /* case AGSA_SSP_INIT_NONDATA: */ 362 case AGSA_SSP_INIT_READ: 363 case AGSA_SSP_INIT_WRITE: 364 case AGSA_SSP_INIT_READ_M: 365 case AGSA_SSP_INIT_WRITE_M: 366 { 367 agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 368 agsaSSPCmdInfoUnit_t *piu; 369 370 /* SSPIU less equal 28 bytes */ 371 offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag); 372 offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId); 373 offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen); 374 offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr); 375 376 piu = &pPayload->SSPInfoUnit; 377 378 si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 379 si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb)); 380 piu->efb_tp_taskAttribute = fc->taskAttribute; 381 piu->additionalCdbLen = fc->additionalCdbLen; 382 383 /* Mask DIR for Read/Write command */ 384 Dir = fc->agRequestType & AGSA_DIR_MASK; 385 386 /* set TLR */ 387 Dir |= fc->flag & TLR_MASK; 388 if (fc->agRequestType & AGSA_MSG) 389 { 390 /* set M bit */ 391 Dir |= AGSA_MSG_BIT; 392 } 393 394 /* Setup SGL */ 395 if (fc->dataLength) 396 { 397 SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n", 398 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 399 /* 400 pPayload->AddrLow0 = pSgl->sgLower; 401 pPayload->AddrHi0 = pSgl->sgUpper; 402 pPayload->Len0 = pSgl->len; 403 pPayload->E0 = pSgl->extReserved; 404 */ 405 si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl)); 406 } 407 else 408 { 409 /* no data transfer */ 410 si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl)); 411 } 412 413 opCode = OPC_INB_SSPINIIOSTART; 414 break; 415 } 416 417 case AGSA_SSP_INIT_READ_EXT: 418 case AGSA_SSP_INIT_WRITE_EXT: 419 case AGSA_SSP_INIT_READ_EXT_M: 420 case AGSA_SSP_INIT_WRITE_EXT_M: 421 { 422 agsaSSPIniExtIOStartCmd_t *pPayload = 423 (agsaSSPIniExtIOStartCmd_t *)pMessage; 424 agsaSSPCmdInfoUnitExt_t *piu; 425 bit32 sspiul; 426 427 /* CDB > 16 bytes */ 428 offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag); 429 offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId); 430 offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen); 431 offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr); 432 433 /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 434 /* setup standard CDB bytes + additional CDB bytes in length field */ 435 sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC); 436 437 Dir = sspiul << 16; 438 piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu; 439 440 si_memcpy(piu->lun, fc->lun, sizeof(piu->lun)); 441 si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb), 442 16 + fc->additionalCdbLen)); 443 piu->efb_tp_taskAttribute = fc->taskAttribute; 444 piu->additionalCdbLen = fc->additionalCdbLen; 445 446 /* Mask DIR for Read/Write command */ 447 Dir |= fc->agRequestType & AGSA_DIR_MASK; 448 449 /* set TLR */ 450 Dir |= fc->flag & TLR_MASK; 451 if (fc->agRequestType & AGSA_MSG) 452 { 453 /* set M bit */ 454 Dir |= AGSA_MSG_BIT; 455 } 456 457 /* Setup SGL */ 458 if (fc->dataLength) 459 { 460 SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n", 461 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 462 463 si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl)); 464 } 465 else //? 466 { 467 /* no data transfer */ 468 //pPayload->dataLen = 0; 469 si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl)); 470 } 471 SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 472 opCode = OPC_INB_SSPINIEXTIOSTART; 473 break; 474 } 475 476 default: 477 { 478 SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n")); 479 ret = AGSA_RC_FAILURE; 480 SA_ASSERT((0), ""); 481 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G"); 482 goto ext; 483 } 484 } 485 486 OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag); 487 OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex); 488 OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength); 489 OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir); 490 491 if (fr->beforePI[inq] == -1) 492 { 493 /* save the new IBQ' PI */ 494 fr->beforePI[inq] = saGetIBQPI(agRoot, inq); 495 fr->inqList[fr->inqMax++] = inq; 496 } 497 498 /* post the IOMB to SPC */ 499 ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, 500 opCode, outq, 0); 501 if (AGSA_RC_SUCCESS != ret) 502 { 503 SA_ASSERT((0), ""); 504 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 505 /* Remove the request from pendingIORequests list */ 506 saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode); 507 508 /* Add the request to the free list of the device */ 509 saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode); 510 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 511 512 SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n")); 513 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G"); 514 goto ext; 515 } 516 517 /* Add the request to the pendingFastIORequests list of the device */ 518 saLlistIOAdd(&fr->requests, &pRequest->fastLink); 519 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G"); 520 521 ext: 522 if (fr && ret != AGSA_RC_SUCCESS) 523 { 524 saFastSSPCancel(fr); 525 ioh = 0; 526 } 527 OSSA_INP_LEAVE(agRoot); 528 return ioh; 529 } /* saFastSSPPrepare */ 530 531 GLOBAL bit32 saFastSSPSend(void *ioHandle) 532 { 533 bit8 inq; 534 agsaRoot_t *agRoot; 535 agsaLLRoot_t *saRoot; 536 saFastRequest_t *fr; 537 bit32 i; 538 539 SA_ASSERT((ioHandle), ""); 540 fr = (saFastRequest_t*)ioHandle; 541 agRoot = (agsaRoot_t*)fr->agRoot; 542 SA_ASSERT((agRoot), ""); 543 saRoot = (agsaLLRoot_t*)agRoot->sdkData; 544 SA_ASSERT((saRoot), ""); 545 546 SA_DBG4(("Entering function saFastSSPSend:\n")); 547 548 for (i = 0; i < fr->inqMax; i++) 549 { 550 inq = INQ(fr->inqList[i]); 551 /* FW interrupt */ 552 mpiIBQMsgSend(&saRoot->inboundQueue[inq]); 553 } 554 /* IORequests are freed in siIODone() */ 555 556 siFastSSPReqFree(agRoot, fr); 557 return AGSA_RC_SUCCESS; 558 } /* saFastSSPSend */ 559 #endif 560 561 /******************************************************************************/ 562 /*! \brief Start SSP request 563 * 564 * Start SSP request 565 * 566 * \param agRoot handles for this instance of SAS/SATA LLL 567 * \param queueNum 568 * \param agIORequest 569 * \param agDevHandle 570 * \param agRequestType 571 * \param agRequestBody 572 * \param agTMRequest valid for task management 573 * \param agCB 574 * 575 * \return If request is started successfully 576 * - \e AGSA_RC_SUCCESS request is started successfully 577 * - \e AGSA_RC_BUSY request is not started successfully 578 */ 579 /******************************************************************************/ 580 GLOBAL bit32 saSSPStart( 581 agsaRoot_t *agRoot, 582 agsaIORequest_t *agIORequest, 583 bit32 queueNum, 584 agsaDevHandle_t *agDevHandle, 585 bit32 agRequestType, 586 agsaSASRequestBody_t *agRequestBody, 587 agsaIORequest_t *agTMRequest, 588 ossaSSPCompletedCB_t agCB) 589 { 590 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 591 #ifdef LOOPBACK_MPI 592 mpiOCQueue_t *circularOQ = agNULL; 593 #endif 594 mpiICQueue_t *circularQ = agNULL; 595 agsaDeviceDesc_t *pDevice = agNULL; 596 agsaPort_t *pPort = agNULL; 597 agsaIORequestDesc_t *pRequest = agNULL; 598 agsaSgl_t *pSgl = agNULL; 599 void *pMessage = agNULL; 600 bit32 ret = AGSA_RC_SUCCESS, retVal = 0; 601 bit32 DirDW4 = 0; /* no data and no AutoGR */ 602 bit32 encryptFlags = 0; 603 bit16 size = 0; 604 bit16 opCode = 0; 605 bit8 inq = 0, outq = 0; 606 607 608 OSSA_INP_ENTER(agRoot); 609 smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa"); 610 611 /* sanity check */ 612 SA_ASSERT((agNULL != agRoot), ""); 613 SA_ASSERT((agNULL != agIORequest), ""); 614 SA_ASSERT((agNULL != agDevHandle), ""); 615 SA_ASSERT((agNULL != agRequestBody), ""); 616 617 DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody); 618 619 /* Find the outgoing port for the device */ 620 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 621 622 if(pDevice == agNULL ) 623 { 624 SA_ASSERT((pDevice), "pDevice"); 625 ret = AGSA_RC_FAILURE; 626 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa"); 627 goto ext; 628 } 629 630 pPort = pDevice->pPort; 631 /* Assign inbound and outbound Buffer */ 632 inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 633 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 634 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 635 636 SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex)); 637 638 /* Get request from free IORequests */ 639 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 640 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 641 642 /* If no LL IO request entry available */ 643 if ( agNULL == pRequest ) 644 { 645 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 646 SA_DBG1(("saSSPStart, No request from free list\n" )); 647 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa"); 648 ret = AGSA_RC_BUSY; 649 goto ext; 650 } 651 /* If LL IO request entry avaliable */ 652 else 653 { 654 /* Remove the request from free list */ 655 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 656 /* Add the request to the pendingIORequests list of the device */ 657 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 658 659 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 660 661 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 662 663 SA_DBG3(("saSSPStart, request %p\n", pRequest )); 664 665 /* Decode the flag settings in the standard I/O requests to decide what size we need. */ 666 /* All other requests will be fine with only 64 byte messages. */ 667 switch ( agRequestType ) 668 { 669 case AGSA_SSP_INIT_READ: 670 case AGSA_SSP_INIT_WRITE: 671 case AGSA_SSP_INIT_NONDATA: 672 case AGSA_SSP_INIT_READ_M: 673 case AGSA_SSP_INIT_WRITE_M: 674 { 675 agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 676 677 if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 678 #ifdef SAFLAG_USE_DIF_ENC_IOMB 679 (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 680 #endif /* SAFLAG_USE_DIF_ENC_IOMB */ 681 (pIRequest->flag & AGSA_SAS_ENABLE_DIF) ) 682 { 683 opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 684 size = IOMB_SIZE128; 685 } 686 else 687 { 688 opCode = OPC_INB_SSPINIIOSTART; 689 size = IOMB_SIZE64; 690 } 691 break; 692 } 693 case AGSA_SSP_INIT_READ_EXT: 694 case AGSA_SSP_INIT_WRITE_EXT: 695 case AGSA_SSP_INIT_READ_EXT_M: 696 case AGSA_SSP_INIT_WRITE_EXT_M: 697 { 698 agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 699 700 if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) || 701 (pIRequest->flag & AGSA_SAS_ENABLE_DIF) || 702 #ifdef SAFLAG_USE_DIF_ENC_IOMB 703 (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) || 704 #endif /* SAFLAG_USE_DIF_ENC_IOMB */ 705 (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)) 706 { 707 opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 708 size = IOMB_SIZE128; 709 } 710 else 711 { 712 SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); 713 opCode = OPC_INB_SSPINIEXTIOSTART; 714 size = IOMB_SIZE96; 715 } 716 break; 717 } 718 case AGSA_SSP_INIT_READ_INDIRECT: 719 case AGSA_SSP_INIT_WRITE_INDIRECT: 720 case AGSA_SSP_INIT_READ_INDIRECT_M: 721 case AGSA_SSP_INIT_WRITE_INDIRECT_M: 722 { 723 SA_DBG3(("saSSPStart: agRequestType 0x%X INDIRECT\n", agRequestType)); 724 opCode = OPC_INB_SSP_DIF_ENC_OPSTART; 725 size = IOMB_SIZE128; 726 break; 727 } 728 case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT): 729 case AGSA_SSP_TASK_MGNT_REQ_M: 730 case AGSA_SSP_TGT_READ_DATA: 731 case AGSA_SSP_TGT_READ_GOOD_RESP: 732 case AGSA_SSP_TGT_WRITE_DATA: 733 case AGSA_SSP_TGT_WRITE_GOOD_RESP: 734 case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 735 736 SA_DBG3(("saSSPStart: agRequestType 0x%X (was default)\n", agRequestType)); 737 opCode = OPC_INB_SSPINIIOSTART; 738 size = IOMB_SIZE64; 739 break; 740 default: 741 SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType)); 742 /* OpCode is not used in this case, but Linux complains if it is not initialized. */ 743 opCode = OPC_INB_SSPINIIOSTART; 744 size = IOMB_SIZE64; 745 break; 746 } 747 748 /* If free IOMB avaliable, set up pRequest*/ 749 pRequest->valid = agTRUE; 750 pRequest->pIORequestContext = agIORequest; 751 pRequest->pDevice = pDevice; 752 pRequest->requestType = agRequestType; 753 pRequest->pPort = pPort; 754 pRequest->startTick = saRoot->timeTick; 755 pRequest->completionCB = agCB; 756 757 /* Set request to the sdkData of agIORequest */ 758 agIORequest->sdkData = pRequest; 759 760 /* save tag and IOrequest pointer to IOMap */ 761 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 762 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 763 764 #ifdef SA_LL_IBQ_PROTECT 765 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 766 #endif /* SA_LL_IBQ_PROTECT */ 767 768 /* Get a free inbound queue entry */ 769 #ifdef LOOPBACK_MPI 770 if (loopback) 771 { 772 SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag)); 773 circularOQ = &saRoot->outboundQueue[outq]; 774 retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage); 775 } 776 else 777 #endif /* LOOPBACK_MPI */ 778 { 779 circularQ = &saRoot->inboundQueue[inq]; 780 retVal = mpiMsgFreeGet(circularQ, size, &pMessage); 781 } 782 783 /* if message size is too large return failure */ 784 if (AGSA_RC_FAILURE == retVal) 785 { 786 #ifdef SA_LL_IBQ_PROTECT 787 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 788 #endif /* SA_LL_IBQ_PROTECT */ 789 /* if not sending return to free list rare */ 790 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 791 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 792 pRequest->valid = agFALSE; 793 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 794 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 795 796 SA_DBG1(("saSSPStart, error when get free IOMB\n")); 797 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa"); 798 ret = AGSA_RC_FAILURE; 799 goto ext; 800 } 801 802 /* return busy if inbound queue is full */ 803 if (AGSA_RC_BUSY == retVal) 804 { 805 #ifdef SA_LL_IBQ_PROTECT 806 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 807 #endif /* SA_LL_IBQ_PROTECT */ 808 /* if not sending return to free list rare */ 809 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 810 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 811 pRequest->valid = agFALSE; 812 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 813 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 814 815 SA_DBG1(("saSSPStart, no more IOMB\n")); 816 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa"); 817 ret = AGSA_RC_BUSY; 818 goto ext; 819 } 820 SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType)); 821 822 switch ( agRequestType ) 823 { 824 case AGSA_SSP_INIT_READ: 825 case AGSA_SSP_INIT_WRITE: 826 case AGSA_SSP_INIT_NONDATA: 827 case AGSA_SSP_INIT_READ_EXT: 828 case AGSA_SSP_INIT_WRITE_EXT: 829 case AGSA_SSP_INIT_READ_M: 830 case AGSA_SSP_INIT_WRITE_M: 831 case AGSA_SSP_INIT_READ_EXT_M: 832 case AGSA_SSP_INIT_WRITE_EXT_M: 833 case AGSA_SSP_INIT_READ_INDIRECT: 834 case AGSA_SSP_INIT_WRITE_INDIRECT: 835 case AGSA_SSP_INIT_READ_INDIRECT_M: 836 case AGSA_SSP_INIT_WRITE_INDIRECT_M: 837 { 838 if (!(agRequestType & AGSA_SSP_EXT_BIT)) 839 { 840 agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 841 agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage; 842 agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage; 843 844 /* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */ 845 /* Be careful with the scatter/gather lists, encryption and DIF options. */ 846 847 /* if( pIRequest->sspCmdIU.cdb[ 0] == 0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A) 848 { 849 pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) | 850 (pIRequest->sspCmdIU.cdb[3] << 16 ) | 851 (pIRequest->sspCmdIU.cdb[4] << 8 ) | 852 (pIRequest->sspCmdIU.cdb[5] ) ); 853 } 854 */ 855 #ifdef LOOPBACK_MPI 856 if (loopback) 857 { 858 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag); 859 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS); 860 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0); 861 //OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0); 862 } 863 else 864 #endif /* LOOPBACK_MPI */ 865 { 866 /* SSPIU less equal 28 bytes */ 867 /* Configure DWORD 1 */ 868 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag); 869 /* Configure DWORD 2 */ 870 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 871 /* Configure DWORD 3 */ 872 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength); 873 } 874 875 #ifdef SA_TESTBASE_EXTRA 876 /* TestBase - Set the host BST entry */ 877 DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16; 878 #endif /* SA_TESTBASE_EXTRA */ 879 880 if (!(agRequestType & AGSA_SSP_INDIRECT_BIT)) 881 { 882 /* Configure DWORD 5-12 */ 883 si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit)); 884 pPayload->dirMTlr = 0; 885 /* Mask DIR for Read/Write command */ 886 /* Configure DWORD 4 bit 8-9 */ 887 DirDW4 |= agRequestType & AGSA_DIR_MASK; 888 } 889 else /* AGSA_SSP_INDIRECT_BIT was set */ 890 { 891 892 agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect); 893 894 /* Configure DWORD 5 */ 895 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32); 896 /* Configure DWORD 6 */ 897 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 ); 898 /* Configure DWORD 7 */ 899 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0); 900 /* Configure DWORD 8 */ 901 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0); 902 /* Configure DWORD 9 */ 903 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0); 904 /* Configure DWORD 10 */ 905 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0); 906 /* Configure DWORD 11 */ 907 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0); 908 /* Mask DIR for Read/Write command */ 909 /* Configure DWORD 4 bit 8-9 */ 910 DirDW4 |= agRequestType & AGSA_DIR_MASK; 911 /* Configure DWORD 4 bit 24-31 */ 912 DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24; 913 /* Configure DWORD 4 bit 4 */ 914 DirDW4 |= 1 << SHIFT3; 915 } 916 917 /* set TLR */ 918 DirDW4 |= pIRequest->flag & TLR_MASK; 919 if (agRequestType & AGSA_MSG) 920 { 921 /* set M bit */ 922 DirDW4 |= AGSA_MSG_BIT; 923 } 924 925 /* check for skipmask operation */ 926 if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 927 { 928 DirDW4 |= AGSA_SKIP_MASK_BIT; 929 /* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5 */ 930 DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8; 931 } 932 933 934 /* Configure DWORDS 12-14 */ 935 if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA) 936 { 937 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 938 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 939 pIRequest->encrypt.EncryptionPerLAAddrLo ); 940 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 941 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 942 pIRequest->dif.DIFPerLAAddrLo ); 943 944 SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal"); 945 946 if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi ) 947 { 948 949 SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" )); 950 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa"); 951 ret = AGSA_RC_FAILURE; 952 goto ext; 953 } 954 955 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 956 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 957 pIRequest->encrypt.EncryptionPerLAAddrHi ); 958 } 959 else if( pIRequest->encrypt.enableEncryptionPerLA) 960 { 961 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 962 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 963 pIRequest->encrypt.EncryptionPerLAAddrLo ); 964 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 965 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 966 0); 967 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 968 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 969 pIRequest->encrypt.EncryptionPerLAAddrHi ); 970 } 971 else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */ 972 { 973 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 974 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 975 0); 976 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 977 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 978 pIRequest->dif.DIFPerLAAddrLo ); 979 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 980 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 981 pIRequest->dif.DIFPerLAAddrHi); 982 } 983 else /* Not EPL or DPL */ 984 { 985 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */ 986 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ), 987 0); 988 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */ 989 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ), 990 0); 991 OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */ 992 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ), 993 0); 994 } 995 996 if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 997 { 998 bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 999 bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1000 bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1001 1002 SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1003 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1004 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1005 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1006 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1007 1008 SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n", 1009 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1010 (pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1011 pIRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1012 1013 SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1014 pIRequest->dif.udtArray[0], 1015 pIRequest->dif.udtArray[1], 1016 pIRequest->dif.udtArray[2], 1017 pIRequest->dif.udtArray[3], 1018 pIRequest->dif.udtArray[4], 1019 pIRequest->dif.udtArray[5])); 1020 1021 SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1022 pIRequest->dif.udrtArray[0], 1023 pIRequest->dif.udrtArray[1], 1024 pIRequest->dif.udrtArray[2], 1025 pIRequest->dif.udrtArray[3], 1026 pIRequest->dif.udrtArray[4], 1027 pIRequest->dif.udrtArray[5])); 1028 1029 SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1030 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1031 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1032 pIRequest->dif.DIFPerLAAddrLo, 1033 pIRequest->dif.DIFPerLAAddrHi)); 1034 1035 DirDW4 |= AGSA_DIF_BIT; 1036 1037 /* DWORD 15 */ 1038 SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags )); 1039 1040 OSSA_WRITE_LE_32(agRoot, pPayload, 1041 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags), 1042 pIRequest->dif.flags); 1043 1044 /* Populate the UDT and UDTR bytes as necessary. */ 1045 if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1046 { 1047 UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 | 1048 pIRequest->dif.udtArray[0]); 1049 UDT5_UDT4_UDT3_UDT2 = (pIRequest->dif.udtArray[5] << SHIFT24 | 1050 pIRequest->dif.udtArray[4] << SHIFT16 | 1051 pIRequest->dif.udtArray[3] << SHIFT8 | 1052 pIRequest->dif.udtArray[2]); 1053 } 1054 1055 if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1056 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1057 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1058 { 1059 UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 | 1060 pIRequest->dif.udrtArray[0] << SHIFT16 ); 1061 UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 | 1062 pIRequest->dif.udrtArray[4] << SHIFT16 | 1063 pIRequest->dif.udrtArray[3] << SHIFT8 | 1064 pIRequest->dif.udrtArray[2]); 1065 } 1066 1067 /* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */ 1068 OSSA_WRITE_LE_32(agRoot, pPayload, 1069 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt), 1070 UDTR1_UDTR0_UDT1_UDT0); 1071 1072 /* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */ 1073 OSSA_WRITE_LE_32(agRoot, pPayload, 1074 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo), 1075 UDT5_UDT4_UDT3_UDT2); 1076 1077 /* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1078 OSSA_WRITE_LE_32(agRoot, pPayload, 1079 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi), 1080 UDTR5_UDTR4_UDTR3_UDTR2); 1081 1082 /* DWORD 19 */ 1083 /* Get IOS IOSeed enable bit */ 1084 if( pIRequest->dif.enableDIFPerLA || 1085 (pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) ) 1086 { 1087 OSSA_WRITE_LE_32(agRoot, pPayload, 1088 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1089 ((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1090 (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 ))); 1091 } 1092 else 1093 { 1094 if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1095 { 1096 OSSA_WRITE_LE_32(agRoot, pPayload, 1097 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 1098 pIRequest->dif.initialIOSeed ); 1099 } 1100 else 1101 { 1102 OSSA_WRITE_LE_32(agRoot, pPayload, 1103 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 0 ); 1104 } 1105 } 1106 } 1107 1108 /* configure encryption */ 1109 if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1110 { 1111 1112 SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n", 1113 pIRequest->encrypt.dekInfo.dekTable, 1114 pIRequest->encrypt.dekInfo.dekIndex)); 1115 1116 SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n", 1117 pIRequest->encrypt.kekIndex, 1118 pIRequest->encrypt.sectorSizeIndex, 1119 pIRequest->encrypt.cipherMode)); 1120 1121 SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n", 1122 pIRequest->encrypt.keyTag_W0, 1123 pIRequest->encrypt.keyTag_W1)); 1124 SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n", 1125 pIRequest->encrypt.tweakVal_W0, 1126 pIRequest->encrypt.tweakVal_W1)); 1127 SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n", 1128 pIRequest->encrypt.tweakVal_W2, 1129 pIRequest->encrypt.tweakVal_W3)); 1130 1131 DirDW4 |= AGSA_ENCRYPT_BIT; 1132 1133 encryptFlags = 0; 1134 1135 if (pIRequest->encrypt.keyTagCheck == agTRUE) 1136 { 1137 encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT; 1138 } 1139 1140 if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS ) 1141 { 1142 encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4; 1143 } 1144 1145 encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2; 1146 1147 /* Always use encryption for DIF fields, skip SKPD */ 1148 1149 encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8; 1150 /* Configure DWORD 20 */ 1151 OSSA_WRITE_LE_32(agRoot, pPayload, 1152 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo), 1153 encryptFlags); 1154 1155 encryptFlags = pIRequest->encrypt.sectorSizeIndex; 1156 1157 encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5; 1158 1159 encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16; 1160 /* Configure DWORD 21 */ 1161 OSSA_WRITE_LE_32(agRoot, pPayload, 1162 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi), 1163 encryptFlags); 1164 1165 /* Configure DWORD 22 */ 1166 OSSA_WRITE_LE_32(agRoot, pPayload, 1167 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0), 1168 pIRequest->encrypt.keyTag_W0); 1169 /* Configure DWORD 23 */ 1170 OSSA_WRITE_LE_32(agRoot, pPayload, 1171 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1), 1172 pIRequest->encrypt.keyTag_W1); 1173 1174 /* Configure DWORD 24 */ 1175 OSSA_WRITE_LE_32(agRoot, pPayload, 1176 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0), 1177 pIRequest->encrypt.tweakVal_W0); 1178 /* Configure DWORD 25 */ 1179 OSSA_WRITE_LE_32(agRoot, pPayload, 1180 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1), 1181 pIRequest->encrypt.tweakVal_W1); 1182 /* Configure DWORD 26 */ 1183 OSSA_WRITE_LE_32(agRoot, pPayload, 1184 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2), 1185 pIRequest->encrypt.tweakVal_W2); 1186 /* Configure DWORD 27 */ 1187 OSSA_WRITE_LE_32(agRoot, pPayload, 1188 OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3), 1189 pIRequest->encrypt.tweakVal_W3); 1190 } 1191 1192 /* Setup SGL */ 1193 if (pIRequest->dataLength) 1194 { 1195 pSgl = &(pIRequest->agSgl); 1196 1197 SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode, 1198 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1199 1200 /* Get DIF PER LA flag */ 1201 DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0); 1202 DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0); 1203 /* Configure DWORD 4 */ 1204 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1205 1206 if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1207 { 1208 /* Configure DWORD 28 */ 1209 pEncryptPayload->AddrLow0 = pSgl->sgLower; 1210 /* Configure DWORD 29 */ 1211 pEncryptPayload->AddrHi0 = pSgl->sgUpper; 1212 /* Configure DWORD 30 */ 1213 pEncryptPayload->Len0 = pSgl->len; 1214 /* Configure DWORD 31 */ 1215 pEncryptPayload->E0 = pSgl->extReserved; 1216 } 1217 else 1218 { 1219 pPayload->AddrLow0 = pSgl->sgLower; 1220 pPayload->AddrHi0 = pSgl->sgUpper; 1221 pPayload->Len0 = pSgl->len; 1222 pPayload->E0 = pSgl->extReserved; 1223 } 1224 } 1225 else 1226 { 1227 /* no data transfer */ 1228 /* Configure DWORD 4 */ 1229 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4); 1230 1231 if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1232 { 1233 pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload; 1234 1235 pEncryptPayload->AddrLow0 = 0; 1236 pEncryptPayload->AddrHi0 = 0; 1237 pEncryptPayload->Len0 = 0; 1238 pEncryptPayload->E0 = 0; 1239 } 1240 else 1241 { 1242 pPayload->AddrLow0 = 0; 1243 pPayload->AddrHi0 = 0; 1244 pPayload->Len0 = 0; 1245 pPayload->E0 = 0; 1246 } 1247 } 1248 1249 /* post the IOMB to SPC */ 1250 #ifdef LOOPBACK_MPI 1251 if (loopback) 1252 ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority); 1253 else 1254 #endif /* LOOPBACK_MPI */ 1255 ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority); 1256 if (AGSA_RC_FAILURE == ret) 1257 { 1258 SA_DBG1(("saSSPStart, error when post SSP IOMB\n")); 1259 ret = AGSA_RC_FAILURE; 1260 } 1261 } 1262 else 1263 { 1264 /* additionalCdbLen is not zero and type is Ext - use EXT mode */ 1265 agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 1266 agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage; 1267 bit32 sspiul; 1268 1269 /* 1270 * Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. 1271 * Be careful with the scatter/gather lists, encryption and DIF options. 1272 */ 1273 /* CDB > 16 bytes */ 1274 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag); 1275 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1276 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength); 1277 /* dword (bit7-bit2) ==> bytes (bit7-bit0) */ 1278 /* setup standard CDB bytes + additional CDB bytes in length field */ 1279 sspiul = sizeof(agsaSSPCmdInfoUnit_t) + 1280 (pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC); 1281 DirDW4 = sspiul << 16; 1282 si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul); 1283 pPayload->SSPIuLendirMTlr = 0; 1284 1285 /* Mask DIR for Read/Write command */ 1286 DirDW4 |= agRequestType & AGSA_DIR_MASK; 1287 1288 /* set TLR */ 1289 DirDW4 |= pIRequest->flag & TLR_MASK; 1290 if (agRequestType & AGSA_MSG) 1291 { 1292 /* set M bit */ 1293 DirDW4 |= AGSA_MSG_BIT; 1294 } 1295 1296 /* check for skipmask operation */ 1297 if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK) 1298 { 1299 SA_ASSERT(0, "Mode not supported"); 1300 } 1301 1302 /* configure DIF */ 1303 if (pIRequest->flag & AGSA_SAS_ENABLE_DIF) 1304 { 1305 SA_ASSERT(0, "Mode not supported"); 1306 } 1307 1308 /* configure encryption */ 1309 if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) 1310 { 1311 SA_ASSERT(0, "Mode not supported"); 1312 } 1313 /* Setup SGL */ 1314 if (pIRequest->dataLength) 1315 { 1316 pSgl = &(pIRequest->agSgl); 1317 1318 SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n", 1319 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1320 1321 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1322 1323 if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART) 1324 { 1325 si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t)); 1326 } 1327 else 1328 { 1329 si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t)); 1330 } 1331 } 1332 else 1333 { 1334 /* no data transfer */ 1335 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4); 1336 pPayload->dataLen = 0; 1337 } 1338 1339 /* post the IOMB to SPC */ 1340 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority )) 1341 { 1342 SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n")); 1343 ret = AGSA_RC_FAILURE; 1344 } 1345 } 1346 break; 1347 } 1348 case AGSA_SSP_TASK_MGNT_REQ: 1349 case AGSA_SSP_TASK_MGNT_REQ_M: 1350 { 1351 agsaIORequestDesc_t *pTMRequestToAbort = agNULL; 1352 agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage; 1353 1354 if (agRequestType & AGSA_MSG) 1355 { 1356 /* set M bit */ 1357 DirDW4 = AGSA_MSG_BIT; 1358 } 1359 1360 /* set DS and ADS bit */ 1361 DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3; 1362 1363 /* Prepare the SSP TASK Management payload */ 1364 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag); 1365 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1366 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged); 1367 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction); 1368 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4); 1369 pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0]; 1370 pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1]; 1371 pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2]; 1372 pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3]; 1373 pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4]; 1374 pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5]; 1375 pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6]; 1376 pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7]; 1377 1378 if (agTMRequest) 1379 { 1380 pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData; 1381 if (pTMRequestToAbort) 1382 { 1383 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag); 1384 } 1385 } 1386 1387 SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n", 1388 pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId)); 1389 1390 siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs); 1391 1392 /* post the IOMB to SPC */ 1393 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority)) 1394 { 1395 SA_DBG1(("saSSPStart, error when post TM IOMB\n")); 1396 ret = AGSA_RC_FAILURE; 1397 } 1398 1399 break; 1400 } 1401 case AGSA_SSP_TGT_READ_DATA: 1402 case AGSA_SSP_TGT_READ_GOOD_RESP: 1403 case AGSA_SSP_TGT_WRITE_DATA: 1404 case AGSA_SSP_TGT_WRITE_GOOD_RESP: 1405 { 1406 agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 1407 agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage; 1408 bit32 DirDW5 = 0; 1409 /* Prepare the SSP TGT IO Start payload */ 1410 /* Configure DWORD 1 */ 1411 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag); 1412 /* Configure DWORD 2 */ 1413 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1414 /* Configure DWORD 3 */ 1415 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength); 1416 /* Configure DWORD 4 */ 1417 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset); 1418 1419 SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption )); 1420 1421 /* Mask DIR and AutoGR bits for Read/Write command */ 1422 DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16); 1423 1424 if (pTRequest->sspOption & SSP_OPTION_DIF ) 1425 { 1426 bit32 UDTR1_UDTR0_UDT1_UDT0 = 0; 1427 bit32 UDT5_UDT4_UDT3_UDT2 = 0; 1428 bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0; 1429 SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n", 1430 pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1431 pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0, 1432 pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0, 1433 pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 )); 1434 1435 SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n", 1436 pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0, 1437 (pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT, 1438 pTRequest->dif.flags & DIF_FLAG_BITS_ACTION )); 1439 1440 SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n", 1441 pTRequest->dif.udtArray[0], 1442 pTRequest->dif.udtArray[1], 1443 pTRequest->dif.udtArray[2], 1444 pTRequest->dif.udtArray[3], 1445 pTRequest->dif.udtArray[4], 1446 pTRequest->dif.udtArray[5])); 1447 1448 SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n", 1449 pTRequest->dif.udrtArray[0], 1450 pTRequest->dif.udrtArray[1], 1451 pTRequest->dif.udrtArray[2], 1452 pTRequest->dif.udrtArray[3], 1453 pTRequest->dif.udrtArray[4], 1454 pTRequest->dif.udrtArray[5])); 1455 1456 SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n", 1457 (pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT, 1458 (pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT, 1459 pTRequest->dif.DIFPerLAAddrLo, 1460 pTRequest->dif.DIFPerLAAddrHi)); 1461 1462 DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF; 1463 1464 1465 SA_DBG3(("saSSPStart,tgt DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags )); 1466 1467 OSSA_WRITE_LE_32(agRoot, pPayload, 1468 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags), 1469 pTRequest->dif.flags); 1470 1471 /* Populate the UDT and UDTR bytes as necessary. */ 1472 if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT) 1473 { 1474 UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 | 1475 pTRequest->dif.udtArray[0]); 1476 UDT5_UDT4_UDT3_UDT2 = (pTRequest->dif.udtArray[5] << SHIFT24 | 1477 pTRequest->dif.udtArray[4] << SHIFT16 | 1478 pTRequest->dif.udtArray[3] << SHIFT8 | 1479 pTRequest->dif.udtArray[2]); 1480 } 1481 1482 if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT || 1483 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE || 1484 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC) 1485 { 1486 UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 | 1487 pTRequest->dif.udrtArray[0] << SHIFT16 ); 1488 UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 | 1489 pTRequest->dif.udrtArray[4] << SHIFT16 | 1490 pTRequest->dif.udrtArray[3] << SHIFT8 | 1491 pTRequest->dif.udrtArray[2]); 1492 } 1493 /* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */ 1494 OSSA_WRITE_LE_32(agRoot, pPayload, 1495 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt), 1496 UDTR1_UDTR0_UDT1_UDT0); 1497 1498 /* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */ 1499 OSSA_WRITE_LE_32(agRoot, pPayload, 1500 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo), 1501 UDT5_UDT4_UDT3_UDT2); 1502 1503 /* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */ 1504 OSSA_WRITE_LE_32(agRoot, pPayload, 1505 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi), 1506 UDTR5_UDTR4_UDTR3_UDTR2); 1507 /* DWORD 11 */ 1508 /* Get IOS IOSeed enable bit */ 1509 if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) 1510 { 1511 OSSA_WRITE_LE_32(agRoot, pPayload, 1512 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1513 ((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) | 1514 (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 ))); 1515 } 1516 else 1517 { 1518 /* Get IOS IOSeed enable bit */ 1519 if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED) 1520 { 1521 OSSA_WRITE_LE_32(agRoot, pPayload, 1522 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 1523 pTRequest->dif.initialIOSeed ); 1524 } 1525 else 1526 { 1527 OSSA_WRITE_LE_32(agRoot, pPayload, 1528 OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 0 ); 1529 } 1530 } 1531 } 1532 1533 /* Mask DIR and AutoGR bits for Read/Write command */ 1534 if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE) 1535 { 1536 DirDW5 |= AGSA_SSP_TGT_BITS_AGR; 1537 } 1538 1539 /* AN, RTE, RDF bits */ 1540 DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2; 1541 1542 /* ODS */ 1543 if(pTRequest->sspOption & SSP_OPTION_ODS) 1544 { 1545 DirDW5 |= AGSA_SSP_TGT_BITS_ODS; 1546 } 1547 1548 /* Setup SGL */ 1549 if (pTRequest->dataLength) 1550 { 1551 pSgl = &(pTRequest->agSgl); 1552 1553 SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n", 1554 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved)); 1555 1556 /* set up dir on the payload */ 1557 /* Configure DWORD 5 */ 1558 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1559 1560 pPayload->AddrLow0 = pSgl->sgLower; 1561 pPayload->AddrHi0 = pSgl->sgUpper; 1562 pPayload->Len0 = pSgl->len; 1563 pPayload->E0 = pSgl->extReserved; 1564 } 1565 else 1566 { 1567 /* no data transfer */ 1568 /* Configure DWORD 5 */ 1569 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5); 1570 pPayload->AddrLow0 = 0; 1571 pPayload->AddrHi0 = 0; 1572 pPayload->Len0 = 0; 1573 } 1574 /* Configure DWORD 6 */ 1575 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0); 1576 1577 /* Build TGT IO START command and send it to SPC */ 1578 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority)) 1579 { 1580 SA_DBG1(("saSSPStart, error when post TGT IOMB\n")); 1581 ret = AGSA_RC_FAILURE; 1582 } 1583 1584 break; 1585 } 1586 case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 1587 { 1588 agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 1589 agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage; 1590 bit32 ip, an, ods; 1591 1592 if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)) 1593 { 1594 ip = 1; 1595 si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength); 1596 } 1597 else 1598 { 1599 ip = 0; 1600 /* NOTE: 1601 * 1. reserved field must be ZEROED out. FW depends on it 1602 * 2. trusted interface. indirect response buffer must be valid. 1603 */ 1604 si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved)); 1605 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower); 1606 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper); 1607 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength); 1608 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0); 1609 } 1610 1611 /* TLR setting */ 1612 an = (pTResponse->respOption & RESP_OPTION_BITS); 1613 /* ODS */ 1614 ods = (pTResponse->respOption & RESP_OPTION_ODS); 1615 1616 /* Prepare the SSP TGT RESPONSE Start payload */ 1617 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag); 1618 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex); 1619 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength); 1620 OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN), 1621 (pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2)); 1622 1623 /* Build TGT RESPONSE START command and send it to SPC */ 1624 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority)) 1625 { 1626 SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n")); 1627 ret = AGSA_RC_FAILURE; 1628 } 1629 1630 break; 1631 } 1632 default: 1633 { 1634 SA_DBG1(("saSSPStart, Unsupported Request IOMB\n")); 1635 ret = AGSA_RC_FAILURE; 1636 break; 1637 } 1638 } 1639 1640 } /* LL IOrequest available */ 1641 1642 #ifdef SA_LL_IBQ_PROTECT 1643 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1644 #endif /* SA_LL_IBQ_PROTECT */ 1645 1646 #ifdef SALL_API_TEST 1647 if (ret == AGSA_RC_SUCCESS) 1648 saRoot->LLCounters.IOCounter.numSSPStarted++; 1649 #endif /*SALL_API_TEST */ 1650 1651 #ifdef LOOPBACK_MPI 1652 if (loopback) 1653 saRoot->interruptVecIndexBitMap[0] |= (1 << outq); 1654 #endif /* LOOPBACK_MPI */ 1655 /* goto have leave and trace point info */ 1656 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa"); 1657 ext: 1658 1659 OSSA_INP_LEAVE(agRoot); 1660 return ret; 1661 } 1662 1663 /******************************************************************************/ 1664 /*! \brief Abort SSP request 1665 * 1666 * Abort SSP request 1667 * 1668 * \param agRoot handles for this instance of SAS/SATA LLL 1669 * \param queueNum 1670 * \param agIORequest 1671 * \param agIOToBeAborted 1672 * 1673 * \return If request is aborted successfully 1674 * - \e AGSA_RC_SUCCESS request is aborted successfully 1675 * - \e AGSA_RC_FAILURE request is not aborted successfully 1676 */ 1677 /*******************************************************************************/ 1678 GLOBAL bit32 saSSPAbort( 1679 agsaRoot_t *agRoot, 1680 agsaIORequest_t *agIORequest, 1681 bit32 queueNum, 1682 agsaDevHandle_t *agDevHandle, 1683 bit32 flag, 1684 void *abortParam, 1685 ossaGenericAbortCB_t agCB 1686 ) 1687 { 1688 bit32 ret = AGSA_RC_SUCCESS, retVal; 1689 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 1690 agsaIORequestDesc_t *pRequest; 1691 agsaIORequestDesc_t *pRequestABT = NULL; 1692 agsaDeviceDesc_t *pDevice = NULL; 1693 agsaDeviceDesc_t *pDeviceABT = NULL; 1694 agsaPort_t *pPort = NULL; 1695 mpiICQueue_t *circularQ; 1696 void *pMessage; 1697 agsaSSPAbortCmd_t *payload; 1698 agsaIORequest_t *agIOToBeAborted; 1699 bit8 inq, outq; 1700 bit32 using_reserved = agFALSE; 1701 bit32 flag_copy = flag; 1702 smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb"); 1703 1704 /* sanity check */ 1705 SA_ASSERT((agNULL != agRoot), ""); 1706 SA_ASSERT((agNULL != agIORequest), ""); 1707 1708 SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag)); 1709 1710 /* Assign inbound and outbound Buffer */ 1711 inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 1712 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 1713 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 1714 1715 #ifdef SA_PRINTOUT_IN_WINDBG 1716 #ifndef DBG 1717 DbgPrint("saSSPAbort flag %d\n", flag ); 1718 #endif /* DBG */ 1719 #endif /* SA_PRINTOUT_IN_WINDBG */ 1720 1721 if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1722 { 1723 agIOToBeAborted = (agsaIORequest_t *)abortParam; 1724 /* Get LL IORequest entry for saSSPAbort() */ 1725 pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1726 if (agNULL == pRequest) 1727 { 1728 /* no pRequest found - can not Abort */ 1729 SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n")); 1730 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb"); 1731 return AGSA_RC_FAILURE; 1732 } 1733 /* Find the device the request sent to */ 1734 pDevice = pRequest->pDevice; 1735 /* Get LL IORequest entry for IOToBeAborted */ 1736 pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 1737 if (agNULL == pRequestABT) 1738 { 1739 /* The IO to Be Abort is no longer exist */ 1740 SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n")); 1741 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb"); 1742 return AGSA_RC_FAILURE; 1743 } 1744 /* Find the device the request Abort to */ 1745 pDeviceABT = pRequestABT->pDevice; 1746 1747 if (agNULL == pDeviceABT) 1748 { 1749 /* no deviceID - can not build IOMB */ 1750 SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n")); 1751 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb"); 1752 return AGSA_RC_FAILURE; 1753 } 1754 1755 if (agNULL != pDevice) 1756 { 1757 /* Find the port the request was sent to */ 1758 pPort = pDevice->pPort; 1759 } 1760 else 1761 { 1762 /* no deviceID - can not build IOMB */ 1763 SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n")); 1764 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb"); 1765 return AGSA_RC_FAILURE; 1766 } 1767 1768 /* Get request from free IORequests */ 1769 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1770 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1771 } 1772 else 1773 { 1774 if (ABORT_ALL == (flag & ABORT_MASK)) 1775 { 1776 /* abort All with Device or Port */ 1777 /* Find the outgoing port for the device */ 1778 if (agDevHandle == agNULL) 1779 { 1780 /* no deviceID - can not build IOMB */ 1781 SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n")); 1782 return AGSA_RC_FAILURE; 1783 } 1784 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 1785 if (agNULL == pDevice) 1786 { 1787 /* no deviceID - can not build IOMB */ 1788 SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n")); 1789 return AGSA_RC_FAILURE; 1790 } 1791 pPort = pDevice->pPort; 1792 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1793 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1794 } 1795 else 1796 { 1797 /* only support 00, 01 and 02 for flag */ 1798 SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag)); 1799 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb"); 1800 return AGSA_RC_FAILURE; 1801 } 1802 } 1803 1804 if ( agNULL == pRequest ) 1805 { 1806 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 1807 if(agNULL != pRequest) 1808 { 1809 using_reserved = agTRUE; 1810 SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n")); 1811 } 1812 else 1813 { 1814 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1815 /* If no LL IO request entry available */ 1816 SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n")); 1817 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb"); 1818 return AGSA_RC_BUSY; 1819 } 1820 } 1821 1822 /* If free IOMB avaliable */ 1823 /* Remove the request from free list */ 1824 if( using_reserved ) 1825 { 1826 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1827 } 1828 else 1829 { 1830 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1831 } 1832 1833 /* Add the request to the pendingIORequests list of the device */ 1834 pRequest->valid = agTRUE; 1835 saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1836 1837 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1838 1839 /* set up pRequest */ 1840 pRequest->pIORequestContext = agIORequest; 1841 pRequest->requestType = AGSA_SSP_REQTYPE; 1842 pRequest->pDevice = pDevice; 1843 pRequest->pPort = pPort; 1844 pRequest->completionCB = (void*)agCB; 1845 /* pRequest->abortCompletionCB = agCB;*/ 1846 pRequest->startTick = saRoot->timeTick; 1847 1848 /* Set request to the sdkData of agIORequest */ 1849 agIORequest->sdkData = pRequest; 1850 1851 /* save tag and IOrequest pointer to IOMap */ 1852 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1853 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1854 1855 1856 #ifdef SA_LL_IBQ_PROTECT 1857 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1858 #endif /* SA_LL_IBQ_PROTECT */ 1859 1860 /* If LL IO request entry avaliable */ 1861 /* Get a free inbound queue entry */ 1862 circularQ = &saRoot->inboundQueue[inq]; 1863 retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage); 1864 1865 /* if message size is too large return failure */ 1866 if (AGSA_RC_FAILURE == retVal) 1867 { 1868 #ifdef SA_LL_IBQ_PROTECT 1869 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1870 #endif /* SA_LL_IBQ_PROTECT */ 1871 1872 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1873 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1874 pRequest->valid = agFALSE; 1875 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1876 { 1877 SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1878 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1879 } 1880 else 1881 { 1882 /* return the request to free pool */ 1883 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1884 } 1885 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1886 1887 SA_DBG1(("saSSPAbort: error when get free IOMB\n")); 1888 1889 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb"); 1890 return AGSA_RC_FAILURE; 1891 } 1892 1893 /* return busy if inbound queue is full */ 1894 if (AGSA_RC_BUSY == retVal) 1895 { 1896 #ifdef SA_LL_IBQ_PROTECT 1897 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1898 #endif /* SA_LL_IBQ_PROTECT */ 1899 1900 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1901 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 1902 pRequest->valid = agFALSE; 1903 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1904 { 1905 SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest)); 1906 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1907 } 1908 else 1909 { 1910 /* return the request to free pool */ 1911 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1912 } 1913 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1914 1915 SA_DBG1(("saSSPAbort: no more IOMB\n")); 1916 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb"); 1917 return AGSA_RC_BUSY; 1918 } 1919 1920 /* setup payload */ 1921 payload = (agsaSSPAbortCmd_t*)pMessage; 1922 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag); 1923 1924 if( ABORT_SINGLE == (flag & ABORT_MASK) ) 1925 { 1926 if ( agNULL == pDeviceABT ) 1927 { 1928 SA_DBG1(("saSSPSAbort: no device\n" )); 1929 smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb"); 1930 return AGSA_RC_FAILURE; 1931 } 1932 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex); 1933 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag); 1934 } 1935 else 1936 { 1937 /* abort all */ 1938 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex); 1939 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0); 1940 } 1941 1942 if(flag & ABORT_TSDK_QUARANTINE) 1943 { 1944 if(smIS_SPCV(agRoot)) 1945 { 1946 flag_copy &= ABORT_SCOPE; 1947 flag_copy |= ABORT_QUARANTINE_SPCV; 1948 } 1949 } 1950 OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy); 1951 1952 SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag)); 1953 1954 siCountActiveIORequestsOnDevice( agRoot, payload->deviceId ); 1955 1956 /* post the IOMB to SPC */ 1957 ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority); 1958 1959 #ifdef SA_LL_IBQ_PROTECT 1960 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 1961 #endif /* SA_LL_IBQ_PROTECT */ 1962 1963 #ifdef SALL_API_TEST 1964 if (AGSA_RC_SUCCESS == ret) 1965 { 1966 saRoot->LLCounters.IOCounter.numSSPAborted++; 1967 } 1968 #endif 1969 1970 smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb"); 1971 1972 return ret; 1973 } 1974 1975 1976 #if defined(SALLSDK_DEBUG) 1977 /******************************************************************************/ 1978 /*! \brief 1979 * 1980 * Dump StartSSP information 1981 * 1982 * Debug helper routine 1983 * 1984 * \return -none - 1985 */ 1986 /*******************************************************************************/ 1987 LOCAL void siDumpSSPStartIu( 1988 agsaDevHandle_t *agDevHandle, 1989 bit32 agRequestType, 1990 agsaSASRequestBody_t *agRequestBody 1991 ) 1992 { 1993 switch ( agRequestType ) 1994 { 1995 case AGSA_SSP_INIT_READ: 1996 case AGSA_SSP_INIT_WRITE: 1997 { 1998 agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq); 1999 2000 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2001 agDevHandle, 2002 (agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE", 2003 pIRequest->dataLength, 2004 pIRequest->sspCmdIU.efb_tp_taskAttribute, 2005 pIRequest->sspCmdIU.cdb[0], 2006 pIRequest->sspCmdIU.cdb[1], 2007 pIRequest->sspCmdIU.cdb[2], 2008 pIRequest->sspCmdIU.cdb[3], 2009 pIRequest->sspCmdIU.cdb[4], 2010 pIRequest->sspCmdIU.cdb[5], 2011 pIRequest->sspCmdIU.cdb[6], 2012 pIRequest->sspCmdIU.cdb[7], 2013 pIRequest->sspCmdIU.cdb[8], 2014 pIRequest->sspCmdIU.cdb[9] 2015 )); 2016 break; 2017 } 2018 2019 case AGSA_SSP_INIT_READ_EXT: 2020 case AGSA_SSP_INIT_WRITE_EXT: 2021 { 2022 agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2023 2024 SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2025 agDevHandle, 2026 (agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT", 2027 pIRequest->dataLength, 2028 pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2029 pIRequest->sspCmdIUExt.cdb[0], 2030 pIRequest->sspCmdIUExt.cdb[1], 2031 pIRequest->sspCmdIUExt.cdb[2], 2032 pIRequest->sspCmdIUExt.cdb[3], 2033 pIRequest->sspCmdIUExt.cdb[4], 2034 pIRequest->sspCmdIUExt.cdb[5], 2035 pIRequest->sspCmdIUExt.cdb[6], 2036 pIRequest->sspCmdIUExt.cdb[7], 2037 pIRequest->sspCmdIUExt.cdb[8], 2038 pIRequest->sspCmdIUExt.cdb[9] 2039 )); 2040 break; 2041 } 2042 2043 case AGSA_SSP_INIT_READ_EXT_M: 2044 case AGSA_SSP_INIT_WRITE_EXT_M: 2045 { 2046 agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt); 2047 2048 SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 2049 agDevHandle, 2050 (agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M", 2051 pIRequest->dataLength, 2052 pIRequest->sspCmdIUExt.efb_tp_taskAttribute, 2053 pIRequest->sspCmdIUExt.cdb[0], 2054 pIRequest->sspCmdIUExt.cdb[1], 2055 pIRequest->sspCmdIUExt.cdb[2], 2056 pIRequest->sspCmdIUExt.cdb[3], 2057 pIRequest->sspCmdIUExt.cdb[4], 2058 pIRequest->sspCmdIUExt.cdb[5], 2059 pIRequest->sspCmdIUExt.cdb[6], 2060 pIRequest->sspCmdIUExt.cdb[7], 2061 pIRequest->sspCmdIUExt.cdb[8], 2062 pIRequest->sspCmdIUExt.cdb[9] 2063 )); 2064 break; 2065 } 2066 2067 case AGSA_SSP_INIT_READ_INDIRECT: 2068 case AGSA_SSP_INIT_WRITE_INDIRECT: 2069 case AGSA_SSP_INIT_READ_INDIRECT_M: 2070 case AGSA_SSP_INIT_WRITE_INDIRECT_M: 2071 { 2072 agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect); 2073 2074 SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n", 2075 agDevHandle, 2076 (agRequestType==AGSA_SSP_INIT_READ_INDIRECT || 2077 agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT", 2078 pIRequest->dataLength, 2079 pIRequest->sspInitiatorReqLen, 2080 pIRequest->sspInitiatorReqAddrUpper32, 2081 pIRequest->sspInitiatorReqAddrLower32 )); 2082 break; 2083 } 2084 2085 2086 case AGSA_SSP_TASK_MGNT_REQ: 2087 { 2088 agsaSSPScsiTaskMgntReq_t *pTaskCmd =&agRequestBody->sspTaskMgntReq; 2089 /* copy payload */ 2090 2091 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x", 2092 agDevHandle, 2093 "AGSA_SSP_TASK_MGNT_REQ", 2094 pTaskCmd->taskMgntFunction, 2095 pTaskCmd->tagOfTaskToBeManaged 2096 )); 2097 break; 2098 } 2099 case AGSA_SSP_TGT_READ_DATA: 2100 { 2101 agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2102 2103 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2104 agDevHandle, 2105 "AGSA_SSP_TGT_READ_DATA", 2106 pTRequest->dataLength, 2107 pTRequest->offset )); 2108 break; 2109 } 2110 case AGSA_SSP_TGT_READ_GOOD_RESP: 2111 { 2112 agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2113 2114 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2115 agDevHandle, 2116 "AGSA_SSP_TGT_READ_GOOD_RESP", 2117 pTRequest->dataLength, 2118 pTRequest->offset)); 2119 break; 2120 } 2121 case AGSA_SSP_TGT_WRITE_GOOD_RESP: 2122 { 2123 agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2124 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2125 agDevHandle, 2126 "AGSA_SSP_TGT_WRITE_GOOD_RESP", 2127 pTRequest->dataLength, 2128 pTRequest->offset )); 2129 2130 break; 2131 } 2132 case AGSA_SSP_TGT_WRITE_DATA: 2133 { 2134 agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq); 2135 2136 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n", 2137 agDevHandle, 2138 "AGSA_SSP_TGT_WRITE_DATA", 2139 pTRequest->dataLength, 2140 pTRequest->offset )); 2141 break; 2142 } 2143 case AGSA_SSP_TGT_CMD_OR_TASK_RSP: 2144 { 2145 agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse); 2146 2147 SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x Tag=%x\n", 2148 agDevHandle, 2149 "AGSA_SSP_TGT_CMD_OR_TASK_RSP", 2150 pTResponse->respBufLength, 2151 pTResponse->respBufUpper, 2152 pTResponse->respBufLower, 2153 pTResponse->agTag )); 2154 break; 2155 } 2156 2157 default: 2158 { 2159 SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n", 2160 agDevHandle, 2161 "Unknown SSP cmd type", 2162 agRequestType 2163 )); 2164 break; 2165 } 2166 } 2167 return; 2168 } 2169 #endif /* SALLSDK_DEBUG */ 2170