1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ********************************************************************************/ 22 /*******************************************************************************/ 23 /** \file 24 * 25 * 26 * This file contains initiator IO related functions in TD layer 27 * 28 */ 29 #include <sys/cdefs.h> 30 #include <dev/pms/config.h> 31 32 #include <dev/pms/freebsd/driver/common/osenv.h> 33 #include <dev/pms/freebsd/driver/common/ostypes.h> 34 #include <dev/pms/freebsd/driver/common/osdebug.h> 35 36 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 37 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 38 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 39 40 #include <dev/pms/RefTisa/tisa/api/titypes.h> 41 #include <dev/pms/RefTisa/tisa/api/ostiapi.h> 42 #include <dev/pms/RefTisa/tisa/api/tiapi.h> 43 #include <dev/pms/RefTisa/tisa/api/tiglobal.h> 44 45 #ifdef FDS_SM 46 #include <dev/pms/RefTisa/sat/api/sm.h> 47 #include <dev/pms/RefTisa/sat/api/smapi.h> 48 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 49 #endif 50 51 #ifdef FDS_DM 52 #include <dev/pms/RefTisa/discovery/api/dm.h> 53 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 54 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 55 #endif 56 57 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h> 58 #include <dev/pms/freebsd/driver/common/osstring.h> 59 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h> 60 61 #ifdef INITIATOR_DRIVER 62 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h> 63 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h> 64 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h> 65 #endif 66 67 #ifdef TARGET_DRIVER 68 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h> 69 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h> 70 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h> 71 #endif 72 73 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 74 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h> 75 76 /***************************************************************************** 77 *! \brief tiINIIOStart 78 * 79 * Purpose: This routine is called to initiate a new SCSI request. 80 * 81 * \param tiRoot: Pointer to initiator driver/port instance. 82 * \param tiIORequest: Pointer to the I/O request context for this I/O. 83 * \param tiDeviceHandle: Pointer to device handle for this I/O. 84 * \param tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list. 85 * \param tiRequestBody: Pointer to the OS Specific module allocated storage 86 * to be used by the TD layer for executing this I/O. 87 * \param interruptContext: The interrupt context within which this function 88 * is called. 89 * \return: 90 * 91 * tiSuccess: I/O request successfully initiated. 92 * tiBusy: No resources available, try again later. 93 * tiIONoDevice: Invalid device handle. 94 * tiError: Other errors that prevent the I/O request to be started. 95 * 96 * 97 *****************************************************************************/ 98 osGLOBAL bit32 99 tiINIIOStart( 100 tiRoot_t *tiRoot, 101 tiIORequest_t *tiIORequest, 102 tiDeviceHandle_t *tiDeviceHandle, 103 tiScsiInitiatorRequest_t *tiScsiRequest, 104 void *tiRequestBody, 105 bit32 interruptContext 106 ) 107 { 108 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 109 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 110 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 111 tdsaDeviceData_t *oneDeviceData; 112 agsaRoot_t *agRoot = agNULL; 113 agsaIORequest_t *agIORequest = agNULL; 114 agsaDevHandle_t *agDevHandle = agNULL; 115 bit32 agRequestType; 116 agsaSASRequestBody_t *agSASRequestBody = agNULL; 117 bit32 tiStatus = tiError; 118 bit32 saStatus = AGSA_RC_FAILURE; 119 120 tdIORequestBody_t *tdIORequestBody; 121 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest; 122 #ifdef REMOVED 123 /* only for debugging */ 124 bit32 i; 125 #endif 126 127 #ifdef SATA_ENABLE 128 #ifndef FDS_SM 129 satIOContext_t *satIOContext; 130 #endif 131 #endif 132 #ifdef FDS_SM 133 smRoot_t *smRoot = &(tdsaAllShared->smRoot); 134 smIORequest_t *smIORequest; 135 smDeviceHandle_t *smDeviceHandle; 136 smScsiInitiatorRequest_t *smSCSIRequest; 137 #endif 138 139 TDSA_INP_ENTER(tiRoot); 140 TI_DBG6(("tiINIIOStart: start\n")); 141 TI_DBG6(("tiINIIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared)); 142 143 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 144 145 TI_DBG6(("tiINIIOStart: onedevicedata %p\n", oneDeviceData)); 146 147 if(oneDeviceData == agNULL) 148 { 149 TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle )); 150 tiStatus = tiIONoDevice; 151 goto ext; 152 } 153 154 /* for hotplug */ 155 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 156 oneDeviceData->tdPortContext == agNULL ) 157 { 158 TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id)); 159 TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n", 160 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 161 // for debugging 162 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 163 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed; 164 TI_DBG6(("tiINIIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc)); 165 tiStatus = tiIONoDevice; 166 goto ext; 167 } 168 #if 1 169 if (tiIORequest->osData == agNULL) 170 { 171 TI_DBG1(("tiINIIOStart: tiIORequest->osData is NULL, wrong\n")); 172 } 173 #endif 174 175 /* starting IO with SAS device */ 176 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 177 { 178 TI_DBG6(("tiINIIOStart: calling saSSPStart\n")); 179 180 agRoot = oneDeviceData->agRoot; 181 agDevHandle = oneDeviceData->agDevHandle; 182 183 /* OS layer has tdlayer data structure pointer in 184 tdIORequestBody_t tdIOReqBody; 185 in ccb_t in agtiapi.h 186 */ 187 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 188 189 /* initialize */ 190 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t)); 191 192 /* let's initialize tdIOrequestBody */ 193 /* initialize callback */ 194 tdIORequestBody->IOCompletionFunc = itdssIOCompleted; 195 196 /* initialize tiDevhandle */ 197 tdIORequestBody->tiDevHandle = tiDeviceHandle; 198 199 /* initialize tiIORequest */ 200 tdIORequestBody->tiIORequest = tiIORequest; 201 202 /* save context if we need to abort later */ 203 tiIORequest->tdData = tdIORequestBody; 204 205 /* initialize expDataLength */ 206 tdIORequestBody->IOType.InitiatorRegIO.expDataLength 207 = tiScsiRequest->scsiCmnd.expDataLength; 208 209 tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr 210 = tiScsiRequest->sglVirtualAddr; 211 212 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */ 213 tiStatus = itdssIOPrepareSGL( 214 tiRoot, 215 tdIORequestBody, 216 &tiScsiRequest->agSgl1, 217 tiScsiRequest->sglVirtualAddr 218 ); 219 220 if (tiStatus != tiSuccess) 221 { 222 TI_DBG1(("tiINIIOStart: can't get SGL\n")); 223 goto ext; 224 } 225 226 227 /* initialize agIORequest */ 228 agIORequest = &(tdIORequestBody->agIORequest); 229 agIORequest->osData = (void *) tdIORequestBody; 230 agIORequest->sdkData = agNULL; /* LL takes care of this */ 231 232 233 /* 234 initialize 235 tdIORequestBody_t tdIORequestBody -> agSASRequestBody 236 */ 237 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); 238 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq); 239 240 agSSPInitiatorRequest->flag = 0; 241 242 /* copy cdb bytes */ 243 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16); 244 245 /* copy lun field */ 246 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, 247 tiScsiRequest->scsiCmnd.lun.lun, 8); 248 249 250 /* setting the data length */ 251 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength; 252 TI_DBG6(("tiINIIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength)); 253 254 agSSPInitiatorRequest->firstBurstSize = 0; 255 256 /* 257 process taskattribute 258 */ 259 if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE) 260 { 261 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 262 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE; 263 } 264 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED) 265 { 266 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 267 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED; 268 } 269 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE) 270 { 271 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 272 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE; 273 } 274 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA) 275 { 276 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 277 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA; 278 } 279 280 if (tiScsiRequest->dataDirection == tiDirectionIn) 281 { 282 agRequestType = AGSA_SSP_INIT_READ; 283 TI_DBG6(("tiINIIOStart: READ\n")); 284 } 285 else if (tiScsiRequest->dataDirection == tiDirectionOut) 286 { 287 agRequestType = AGSA_SSP_INIT_WRITE; 288 TI_DBG6(("tiINIIOStart: WRITE\n")); 289 } 290 else 291 { 292 agRequestType = AGSA_REQ_TYPE_UNKNOWN; 293 TI_DBG1(("tiINIIOStart: unknown data direction\n")); 294 } 295 296 tdIORequestBody->agRequestType = agRequestType; 297 298 TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 299 TI_DBG6(("tiINIIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 300 301 /* for debugging */ 302 if (tdIORequestBody->IOCompletionFunc == agNULL) 303 { 304 TI_DBG1(("tiINIIOStart: Error!!!! IOCompletionFunc is NULL\n")); 305 } 306 saStatus = saSSPStart(agRoot, 307 agIORequest, 308 tdsaRotateQnumber(tiRoot, oneDeviceData), 309 agDevHandle, 310 agRequestType, 311 agSASRequestBody, 312 agNULL, 313 &ossaSSPCompleted); 314 315 tdIORequestBody->ioStarted = agTRUE; 316 tdIORequestBody->ioCompleted = agFALSE; 317 tdIORequestBody->reTries = 0; 318 319 if (saStatus == AGSA_RC_SUCCESS) 320 { 321 Initiator->NumIOsActive++; 322 tiStatus = tiSuccess; 323 } 324 else 325 { 326 tdIORequestBody->ioStarted = agFALSE; 327 tdIORequestBody->ioCompleted = agTRUE; 328 if (saStatus == AGSA_RC_BUSY) 329 { 330 TI_DBG4(("tiINIIOStart: saSSPStart busy\n")); 331 tiStatus = tiBusy; 332 } 333 else 334 { 335 tiStatus = tiError; 336 } 337 goto ext; 338 } 339 } 340 #ifdef FDS_SM 341 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 342 { 343 TI_DBG5(("tiINIIOStart: calling satIOStart\n")); 344 TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id)); 345 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 346 /* initialize */ 347 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t)); 348 /* initialize tiDevhandle */ 349 tdIORequestBody->tiDevHandle = tiDeviceHandle; 350 tdIORequestBody->superIOFlag = agFALSE; 351 352 tiIORequest->tdData = tdIORequestBody; 353 tdIORequestBody->tiIORequest = tiIORequest; 354 smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest); 355 smIORequest->tdData = tdIORequestBody; 356 357 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle); 358 smDeviceHandle->tdData = oneDeviceData; 359 360 smSCSIRequest = (smScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSCSIRequest); 361 osti_memcpy(smSCSIRequest, tiScsiRequest, sizeof(smScsiInitiatorRequest_t)); 362 363 tiStatus = smIOStart(smRoot, 364 smIORequest, 365 smDeviceHandle, 366 smSCSIRequest, 367 interruptContext); 368 /* 369 osGLOBAL bit32 370 smIOStart( 371 smRoot_t *smRoot, 372 smIORequest_t *smIORequest, 373 smDeviceHandle_t *smDeviceHandle, 374 smScsiInitiatorRequest_t *smSCSIRequest, 375 bit32 interruptContext 376 ) 377 378 379 */ 380 } 381 #else 382 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 383 { 384 TI_DBG5(("tiINIIOStart: calling satIOStart\n")); 385 TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id)); 386 387 #ifdef SATA_ENABLE 388 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 389 390 /* initialize */ 391 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t)); 392 393 /* initialize tiDevhandle */ 394 tdIORequestBody->tiDevHandle = tiDeviceHandle; 395 396 /* initialize tiIORequest */ 397 tdIORequestBody->tiIORequest = tiIORequest; 398 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed; 399 400 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 401 402 /* 403 * Need to initialize all the fields within satIOContext except 404 * reqType and satCompleteCB which will be set in sat.c depending on cmd. 405 */ 406 tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL; 407 tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0; 408 satIOContext->pSatDevData = &oneDeviceData->satDevData; 409 satIOContext->pFis = 410 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 411 satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd; 412 satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload; 413 satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData; 414 satIOContext->pTiSenseData->senseData = satIOContext->pSense; 415 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */ 416 satIOContext->tiRequestBody = tiRequestBody; 417 satIOContext->interruptContext = interruptContext; 418 satIOContext->ptiDeviceHandle = tiDeviceHandle; 419 satIOContext->tiScsiXchg = tiScsiRequest; 420 satIOContext->satIntIoContext = agNULL; 421 satIOContext->satOrgIOContext = agNULL; 422 /* satIOContext->tiIORequest = tiIORequest; */ 423 424 /* save context if we need to abort later */ 425 tiIORequest->tdData = tdIORequestBody; 426 427 /* followings are used only for internal IO */ 428 satIOContext->currentLBA = 0; 429 satIOContext->OrgTL = 0; 430 431 TI_DBG5(("tiINIIOStart: pSatDevData=%p\n", satIOContext->pSatDevData )); 432 433 tiStatus = satIOStart( tiRoot, 434 tiIORequest, 435 tiDeviceHandle, 436 tiScsiRequest, 437 satIOContext); 438 goto ext; 439 #endif 440 } 441 #endif /* else of FDS_SM */ 442 else 443 { 444 445 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 446 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed; 447 TI_DBG1(("tiINIIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType)); 448 /* 449 error. unsupported IO 450 */ 451 } 452 ext: 453 TDSA_INP_LEAVE(tiRoot); 454 return tiStatus; 455 } 456 457 #ifdef FAST_IO_TEST 458 osGLOBAL bit32 459 tiINIFastIOSend(void *ioh) 460 { 461 bit32 saStatus, tiStatus; 462 463 saStatus = saFastSSPSend(ioh); 464 if (saStatus == AGSA_RC_SUCCESS) 465 tiStatus = tiSuccess; 466 else 467 tiStatus = tiError; 468 return tiStatus; 469 } 470 471 osGLOBAL bit32 472 tiINIFastIOCancel(void *ioh) 473 { 474 bit32 saStatus, tiStatus; 475 476 saStatus = saFastSSPCancel(ioh); 477 if (saStatus == AGSA_RC_SUCCESS) 478 tiStatus = tiSuccess; 479 else 480 tiStatus = tiError; 481 return tiStatus; 482 } 483 484 osGLOBAL void* 485 tiINIFastIOPrepare( 486 tiRoot_t *tiRoot, 487 void *ioHandle, 488 agsaFastCommand_t *fc) 489 { 490 tdsaDeviceData_t *oneDeviceData; 491 tiDeviceHandle_t *tiDeviceHandle = fc->devHandle; 492 bit32 taskAttribute = fc->taskAttribute; 493 void *ioh = ioHandle; 494 495 TDSA_INP_ENTER(tiRoot); 496 TI_DBG6(("tiINIFastIOPrepare: enter\n")); 497 498 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 499 if(oneDeviceData == agNULL) 500 { 501 TI_DBG1(("tiINIFastIOPrepare: tiDeviceHandle=%p DeviceData is NULL\n", 502 tiDeviceHandle)); 503 ioHandle = 0; 504 TD_ASSERT((0), ""); 505 goto ext; 506 } 507 TI_DBG6(("tiINIFastIOPrepare: onedevicedata %p\n", oneDeviceData)); 508 509 /* starting IO with SAS device */ 510 if (oneDeviceData->DeviceType != TD_SAS_DEVICE) 511 { 512 TI_DBG1(("tiINISuperIOSend: wrong Device %d\n", oneDeviceData->DeviceType)); 513 /* error: unsupported IO */ 514 ioHandle = 0; 515 TD_ASSERT((0), ""); 516 goto ext; 517 } 518 519 fc->agRoot = oneDeviceData->agRoot; 520 TD_ASSERT((NULL != fc->agRoot), ""); 521 522 fc->devHandle = oneDeviceData->agDevHandle; 523 TD_ASSERT((NULL != fc->devHandle), ""); 524 fc->safb->oneDeviceData = oneDeviceData; 525 526 /* 527 process taskattribute 528 */ 529 switch (taskAttribute) 530 { 531 case TASK_SIMPLE: 532 fc->taskAttribute = TD_TASK_SIMPLE; 533 break; 534 case TASK_ORDERED: 535 fc->taskAttribute = TD_TASK_ORDERED; 536 break; 537 case TASK_HEAD_OF_QUEUE: 538 fc->taskAttribute = TD_TASK_HEAD_OF_QUEUE; 539 break; 540 case TASK_ACA: 541 fc->taskAttribute = TD_TASK_ACA; 542 break; 543 /* compile out for "iniload" */ 544 } 545 546 547 TI_DBG3(("tiINIFastIOPrepare: data direction: %x\n", fc->agRequestType)); 548 TI_DBG6(("tiINIFastIOPrepare: device AddrHi/Lo 0x%08x / 0x%08x\n", 549 oneDeviceData->SASAddressID.sasAddressHi, 550 oneDeviceData->SASAddressID.sasAddressLo)); 551 552 fc->queueNum = tdsaRotateQnumber(tiRoot, oneDeviceData); 553 554 ioHandle = saFastSSPPrepare(ioHandle, fc, ossaFastSSPCompleted, fc->safb); 555 if (!ioHandle) 556 { 557 TI_DBG1(("tiINIFastIOPrepare: saSuperSSPSend error\n")); 558 TD_ASSERT((0), ""); 559 //goto ext; 560 } 561 562 ext: 563 if (ioh && !ioHandle) 564 { 565 saFastSSPCancel(ioh); 566 } 567 568 TI_DBG6(("tiINIFastIOPrepare: leave\n")); 569 570 TDSA_INP_LEAVE(tiRoot); 571 return ioHandle; 572 } /* tiINIFastIOPrepare */ 573 #endif 574 575 /***************************************************************************** 576 * 577 * tiINIIOStartDif 578 * 579 * Purpose: This routine is called to initiate a new SCSI request with 580 * DIF enable. 581 * 582 * Parameters: 583 * tiRoot: Pointer to initiator driver/port instance. 584 * tiIORequest: Pointer to the I/O request context for this I/O. 585 * tiDeviceHandle: Pointer to device handle for this I/O. 586 * tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list. 587 * tiRequestBody: Pointer to the OS Specific module allocated storage 588 * to be used by the TD layer for executing this I/O. 589 * interruptContext: The interrupt context within which this function 590 * is called. 591 * difOption: DIF option. 592 * 593 * Return: 594 * 595 * tiSuccess: I/O request successfully initiated. 596 * tiBusy: No resources available, try again later. 597 * tiIONoDevice: Invalid device handle. 598 * tiError: Other errors that prevent the I/O request to be started. 599 * 600 * 601 *****************************************************************************/ 602 osGLOBAL bit32 tiINIIOStartDif( 603 tiRoot_t *tiRoot, 604 tiIORequest_t *tiIORequest, 605 tiDeviceHandle_t *tiDeviceHandle, 606 tiScsiInitiatorRequest_t *tiScsiRequest, 607 void *tiRequestBody, 608 bit32 interruptContext, 609 tiDif_t *difOption 610 ) 611 { 612 613 /* This function was never used by SAS/SATA. Use tiINISuperIOStart() instead. */ 614 return tiBusy; 615 } 616 617 618 /***************************************************************************** 619 * 620 * tiINISuperIOStart 621 * 622 * Purpose: This routine is called to initiate a new SCSI request. 623 * 624 * Parameters: 625 * tiRoot: Pointer to initiator driver/port instance. 626 * tiIORequest: Pointer to the I/O request context for this I/O. 627 * tiDeviceHandle: Pointer to device handle for this I/O. 628 * tiScsiRequest: Pointer to the SCSI-3 I/O request and SGL list. 629 * tiRequestBody: Pointer to the OS Specific module allocated storage 630 * to be used by the TD layer for executing this I/O. 631 * interruptContext: The interrupt context within which this function 632 * is called. 633 * Return: 634 * 635 * tiSuccess: I/O request successfully initiated. 636 * tiBusy: No resources available, try again later. 637 * tiIONoDevice: Invalid device handle. 638 * tiError: Other errors that prevent the I/O request to be started. 639 * 640 * 641 *****************************************************************************/ 642 osGLOBAL bit32 643 tiINISuperIOStart( 644 tiRoot_t *tiRoot, 645 tiIORequest_t *tiIORequest, 646 tiDeviceHandle_t *tiDeviceHandle, 647 tiSuperScsiInitiatorRequest_t *tiScsiRequest, 648 void *tiRequestBody, 649 bit32 interruptContext 650 ) 651 { 652 tdsaRoot_t *tdsaRoot = agNULL; 653 tdsaContext_t *tdsaAllShared = agNULL; 654 itdsaIni_t *Initiator = agNULL; 655 tdsaDeviceData_t *oneDeviceData = agNULL; 656 tdIORequestBody_t *tdIORequestBody = agNULL; 657 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest = agNULL; 658 agsaRoot_t *agRoot = agNULL; 659 agsaIORequest_t *agIORequest = agNULL; 660 agsaDevHandle_t *agDevHandle = agNULL; 661 agsaSASRequestBody_t *agSASRequestBody = agNULL; 662 bit32 tiStatus = tiError; 663 bit32 saStatus = AGSA_RC_FAILURE; 664 bit32 adjusted_length = 0; 665 bit32 agRequestType = 0; 666 agBOOLEAN needPlusDataLenAdjustment = agFALSE; 667 agBOOLEAN needMinusDataLenAdjustment = agFALSE; 668 669 #ifdef SATA_ENABLE 670 #ifndef FDS_SM 671 satIOContext_t *satIOContext; 672 #endif 673 #endif 674 #ifdef FDS_SM 675 smRoot_t *smRoot; 676 smIORequest_t *smIORequest; 677 smDeviceHandle_t *smDeviceHandle; 678 smSuperScsiInitiatorRequest_t *smSuperSCSIRequest; 679 #endif 680 #ifdef CCBUILD_INDIRECT_CDB 681 agsaSSPInitiatorRequestIndirect_t *agSSPInitiatorIndRequest = agNULL; 682 #endif 683 TD_ASSERT(tiRoot , "tiRoot"); 684 TD_ASSERT(tiIORequest, "tiIORequest"); 685 TD_ASSERT(tiDeviceHandle, "tiDeviceHandle"); 686 TD_ASSERT(tiRequestBody, "tiRequestBody"); 687 TD_ASSERT(tiRoot->tdData, "tiRoot->tdData"); 688 TD_ASSERT(tiDeviceHandle, "tiDeviceHandle"); 689 690 tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 691 TD_ASSERT(tdsaRoot, "tdsaRoot"); 692 693 tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 694 TD_ASSERT(tdsaAllShared, "tdsaAllShared"); 695 696 Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 697 TD_ASSERT(Initiator, "Initiator"); 698 699 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 700 TD_ASSERT(oneDeviceData, "oneDeviceData"); 701 702 703 #ifdef FDS_SM 704 smRoot = &(tdsaAllShared->smRoot); 705 TD_ASSERT(smRoot , "smRoot"); 706 #endif 707 708 709 TI_DBG6(("tiINISuperIOStart: start\n")); 710 TI_DBG6(("tiINISuperIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared)); 711 712 TI_DBG6(("tiINISuperIOStart: onedevicedata %p\n", oneDeviceData)); 713 714 if (oneDeviceData == agNULL) 715 { 716 TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle )); 717 return tiIONoDevice; 718 } 719 720 /* for hotplug */ 721 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 722 oneDeviceData->tdPortContext == agNULL ) 723 { 724 TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id)); 725 TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n", 726 oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 727 // for debugging 728 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 729 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed; 730 TI_DBG6(("tiINISuperIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc)); 731 return tiIONoDevice; 732 } 733 734 #ifdef DBG 735 if (tiIORequest->osData == agNULL) 736 { 737 TI_DBG1(("tiINISuperIOStart: tiIORequest->osData is NULL, wrong\n")); 738 return tiError; 739 } 740 #endif 741 /* starting IO with SAS device */ 742 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 743 { 744 TI_DBG3(("tiINISuperIOStart: calling saSSPStart\n")); 745 746 agRoot = oneDeviceData->agRoot; 747 agDevHandle = oneDeviceData->agDevHandle; 748 749 /* OS layer has tdlayer data structure pointer in tdIORequestBody_t tdIOReqBody; in ccb_t in agtiapi.h */ 750 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 751 752 /* initialize */ 753 /*the tdIORequestBody has been initialized in HwBuildIo routine */ 754 /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/ 755 756 /* let's initialize tdIOrequestBody */ 757 /* initialize callback */ 758 tdIORequestBody->IOCompletionFunc = itdssIOCompleted; 759 760 /* initialize tiDevhandle */ 761 tdIORequestBody->tiDevHandle = tiDeviceHandle; 762 763 /* initialize tiIORequest */ 764 tdIORequestBody->tiIORequest = tiIORequest; 765 766 /* save context if we need to abort later */ 767 tiIORequest->tdData = tdIORequestBody; 768 769 /* initialize expDataLength */ 770 tdIORequestBody->IOType.InitiatorRegIO.expDataLength 771 = tiScsiRequest->scsiCmnd.expDataLength; 772 773 tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr 774 = tiScsiRequest->sglVirtualAddr; 775 776 /* initialize agIORequest */ 777 agIORequest = &(tdIORequestBody->agIORequest); 778 agIORequest->osData = (void *) tdIORequestBody; 779 780 /* initialize tdIORequestBody_t tdIORequestBody -> agSASRequestBody */ 781 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); 782 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq); 783 784 agSSPInitiatorRequest->flag = 0; 785 if (tiScsiRequest->flags & TI_SCSI_INITIATOR_ENCRYPT) 786 { 787 TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_ENCRYPT\n")); 788 789 /* Copy all of the relevant encrypt information */ 790 agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_ENCRYPTION; 791 TD_ASSERT( sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t) , "sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t)"); 792 osti_memcpy(&agSSPInitiatorRequest->encrypt, &tiScsiRequest->Encrypt, sizeof(agsaEncrypt_t)); 793 } 794 795 if ((tiScsiRequest->flags & TI_SCSI_INITIATOR_DIF) && 796 (tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_10 || 797 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_10 || 798 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_6 || 799 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_6 || 800 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_12 || 801 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_12 || 802 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_16 || 803 tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_16 )) 804 { 805 TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_DIF\n")); 806 /* Copy all of the relevant DIF information */ 807 agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_DIF; 808 osti_memcpy(&agSSPInitiatorRequest->dif, &tiScsiRequest->Dif, sizeof(agsaDif_t)); 809 810 /* Check if need to adjust dataLength. */ 811 switch (tiScsiRequest->dataDirection) 812 { 813 case tiDirectionOut: /* Write/Outbound */ 814 break; 815 816 case tiDirectionIn: /* Read/Inbound */ 817 if ((agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK) == DIF_INSERT) 818 { 819 needPlusDataLenAdjustment = agTRUE; 820 } 821 break; 822 } 823 824 /* Set SGL data len XXX This code needs to support more sector sizes */ 825 /* Length adjustment for PCIe DMA only not SAS */ 826 if (needPlusDataLenAdjustment == agTRUE) 827 { 828 adjusted_length = tiScsiRequest->scsiCmnd.expDataLength; 829 adjusted_length += (adjusted_length/512) * 8; 830 agSSPInitiatorRequest->dataLength = adjusted_length; 831 } 832 else if (needMinusDataLenAdjustment == agTRUE) 833 { 834 adjusted_length = tiScsiRequest->scsiCmnd.expDataLength; 835 adjusted_length -= (adjusted_length/520) * 8; 836 agSSPInitiatorRequest->dataLength = adjusted_length; 837 } 838 else 839 { 840 /* setting the data length */ 841 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength; 842 } 843 844 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */ 845 tiStatus = itdssIOPrepareSGL( 846 tiRoot, 847 tdIORequestBody, 848 &tiScsiRequest->agSgl1, 849 tiScsiRequest->sglVirtualAddr 850 ); 851 TI_DBG2(("tiINISuperIOStart:TI_SCSI_INITIATOR_DIF needMinusDataLenAdjustment %d needPlusDataLenAdjustment %d difAction %X\n", 852 needMinusDataLenAdjustment, 853 needPlusDataLenAdjustment, 854 agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK)); 855 856 } 857 else 858 { 859 /* setting the data length */ 860 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength; 861 862 /* initializes "agsaSgl_t agSgl" of "agsaSSPInitiatorRequest_t" */ 863 tiStatus = itdssIOPrepareSGL( 864 tiRoot, 865 tdIORequestBody, 866 &tiScsiRequest->agSgl1, 867 tiScsiRequest->sglVirtualAddr 868 ); 869 } 870 871 if (tiStatus != tiSuccess) 872 { 873 TI_DBG1(("tiINISuperIOStart: can't get SGL\n")); 874 return tiStatus; 875 } 876 877 TI_DBG6(("tiINISuperIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength)); 878 879 /* process taskattribute */ 880 if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE) 881 { 882 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 883 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE; 884 } 885 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED) 886 { 887 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 888 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED; 889 } 890 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE) 891 { 892 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 893 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE; 894 } 895 else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA) 896 { 897 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8) 898 agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA; 899 } 900 901 /* copy cdb bytes */ 902 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16); 903 /* copy lun field */ 904 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, tiScsiRequest->scsiCmnd.lun.lun, 8); 905 #ifdef CCBUILD_INDIRECT_CDB 906 /* check the Indirect CDB flag */ 907 if (tiScsiRequest->flags & TI_SCSI_INITIATOR_INDIRECT_CDB) 908 { 909 /* Indirect CDB */ 910 if (tiScsiRequest->dataDirection == tiDirectionIn) 911 { 912 agRequestType = AGSA_SSP_INIT_READ_INDIRECT; 913 TI_DBG6(("tiINISuperIOStart: Indirect READ\n")); 914 } 915 else if (tiScsiRequest->dataDirection == tiDirectionOut) 916 { 917 agRequestType = AGSA_SSP_INIT_WRITE_INDIRECT; 918 TI_DBG6(("tiINISuperIOStart: Indirect WRITE\n")); 919 } 920 else 921 { 922 agRequestType = AGSA_REQ_TYPE_UNKNOWN; 923 TI_DBG1(("tiINISuperIOStart: unknown data direction\n")); 924 } 925 agSSPInitiatorIndRequest = &(agSASRequestBody->sspInitiatorReqIndirect); 926 /* copy the constructed SSPIU info to indirect SSPIU buffer */ 927 osti_memcpy(tiScsiRequest->IndCDBBuffer, &agSSPInitiatorRequest->sspCmdIU, sizeof(agsaSSPCmdInfoUnit_t)); 928 /* initialize the indirect CDB buffer address and length */ 929 agSSPInitiatorIndRequest->sspInitiatorReqAddrLower32 = tiScsiRequest->IndCDBLowAddr; 930 agSSPInitiatorIndRequest->sspInitiatorReqAddrUpper32 = tiScsiRequest->IndCDBHighAddr; 931 agSSPInitiatorIndRequest->sspInitiatorReqLen = sizeof(agsaSSPCmdInfoUnit_t); 932 } 933 else 934 #endif //CCBUILD_INDIRECT_CDB 935 { 936 /* Direct CDB */ 937 if (tiScsiRequest->dataDirection == tiDirectionIn) 938 { 939 agRequestType = AGSA_SSP_INIT_READ; 940 TI_DBG6(("tiINISuperIOStart: READ\n")); 941 } 942 else if (tiScsiRequest->dataDirection == tiDirectionOut) 943 { 944 agRequestType = AGSA_SSP_INIT_WRITE; 945 TI_DBG6(("tiINISuperIOStart: WRITE\n")); 946 } 947 else 948 { 949 agRequestType = AGSA_REQ_TYPE_UNKNOWN; 950 TI_DBG1(("tiINISuperIOStart: unknown data direction\n")); 951 } 952 } 953 954 tdIORequestBody->agRequestType = agRequestType; 955 956 TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 957 TI_DBG6(("tiINISuperIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 958 959 #ifdef DBG 960 /* for debugging */ 961 if (tdIORequestBody->IOCompletionFunc == agNULL) 962 { 963 TI_DBG1(("tiINISuperIOStart: Error!!!! IOCompletionFunc is NULL\n")); 964 return tiError; 965 } 966 #endif 967 saStatus = saSSPStart(agRoot, 968 agIORequest, 969 tdsaRotateQnumber(tiRoot, oneDeviceData), 970 agDevHandle, 971 agRequestType, 972 agSASRequestBody, 973 agNULL, 974 &ossaSSPCompleted); 975 976 if (saStatus == AGSA_RC_SUCCESS) 977 { 978 Initiator->NumIOsActive++; 979 tdIORequestBody->ioStarted = agTRUE; 980 tdIORequestBody->ioCompleted = agFALSE; 981 tiStatus = tiSuccess; 982 } 983 else 984 { 985 tdIORequestBody->ioStarted = agFALSE; 986 tdIORequestBody->ioCompleted = agTRUE; 987 if (saStatus == AGSA_RC_BUSY) 988 { 989 TI_DBG4(("tiINISuperIOStart: saSSPStart busy\n")); 990 tiStatus = tiBusy; 991 } 992 else 993 { 994 tiStatus = tiError; 995 } 996 return tiStatus; 997 } 998 } 999 #ifdef FDS_SM 1000 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1001 { 1002 TI_DBG5(("tiINISuperIOStart: calling satIOStart\n")); 1003 TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id)); 1004 TI_DBG5(("tiINISuperIOStart: SATA sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1005 TI_DBG5(("tiINISuperIOStart: SATA sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1006 1007 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1008 /* initialize */ 1009 /* the tdIORequestBody has been initialized by Storport in SRB Extension */ 1010 /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/ 1011 /* initialize tiDevhandle */ 1012 tdIORequestBody->tiDevHandle = tiDeviceHandle; 1013 tdIORequestBody->superIOFlag = agTRUE; 1014 1015 tiIORequest->tdData = tdIORequestBody; 1016 tdIORequestBody->tiIORequest = tiIORequest; 1017 smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest); 1018 smIORequest->tdData = tdIORequestBody; 1019 smIORequest->smData = &tdIORequestBody->smIORequestBody; 1020 1021 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle); 1022 smDeviceHandle->tdData = oneDeviceData; 1023 1024 smSuperSCSIRequest = (smSuperScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSuperSCSIRequest); 1025 osti_memcpy(smSuperSCSIRequest, tiScsiRequest, sizeof(smSuperScsiInitiatorRequest_t)); 1026 1027 tiStatus = smSuperIOStart(smRoot, 1028 smIORequest, 1029 smDeviceHandle, 1030 smSuperSCSIRequest, 1031 oneDeviceData->SASAddressID.sasAddressHi, 1032 oneDeviceData->SASAddressID.sasAddressLo, 1033 interruptContext); 1034 1035 } 1036 #else 1037 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1038 { 1039 1040 TI_DBG5(("tiINISuperIOStart: calling satIOStart\n")); 1041 TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id)); 1042 1043 #ifdef SATA_ENABLE 1044 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1045 1046 /* initialize */ 1047 osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t)); 1048 1049 /* initialize tiDevhandle */ 1050 tdIORequestBody->tiDevHandle = tiDeviceHandle; 1051 1052 /* initialize tiIORequest */ 1053 tdIORequestBody->tiIORequest = tiIORequest; 1054 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed; 1055 1056 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 1057 1058 /* 1059 * Need to initialize all the fields within satIOContext except 1060 * reqType and satCompleteCB which will be set in sat.c depending on cmd. 1061 */ 1062 tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL; 1063 tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0; 1064 satIOContext->pSatDevData = &oneDeviceData->satDevData; 1065 satIOContext->pFis = 1066 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 1067 satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd; 1068 satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload; 1069 satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData; 1070 satIOContext->pTiSenseData->senseData = satIOContext->pSense; 1071 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */ 1072 satIOContext->tiRequestBody = tiRequestBody; 1073 satIOContext->interruptContext = interruptContext; 1074 satIOContext->ptiDeviceHandle = tiDeviceHandle; 1075 /* 1076 This code uses a kludge for the tiScsiXchg. Many subroutines in the SATA code 1077 require a tiScsiInitiatorRequest. Since it would be a lot of work to replicate 1078 those functions for a tiSuperScsiInitiatorRequest, we will use a short cut. 1079 The standard pointer will be passed, but the superIOFlag marks the real type of the structure. 1080 */ 1081 satIOContext->tiScsiXchg = tiScsiRequest; 1082 satIOContext->superIOFlag = agTRUE; 1083 1084 satIOContext->satIntIoContext = agNULL; 1085 satIOContext->satOrgIOContext = agNULL; 1086 /* satIOContext->tiIORequest = tiIORequest; */ 1087 1088 /* save context if we need to abort later */ 1089 tiIORequest->tdData = tdIORequestBody; 1090 1091 /* followings are used only for internal IO */ 1092 satIOContext->currentLBA = 0; 1093 satIOContext->OrgTL = 0; 1094 1095 TI_DBG5(("tiINISuperIOStart: pSatDevData=%p\n", satIOContext->pSatDevData )); 1096 1097 tiStatus = satIOStart( tiRoot, 1098 tiIORequest, 1099 tiDeviceHandle, 1100 satIOContext->tiScsiXchg, 1101 satIOContext); 1102 1103 return tiStatus; 1104 #endif 1105 } 1106 #endif /* else of FDS_SM */ 1107 1108 else 1109 { 1110 1111 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1112 tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed; 1113 TI_DBG1(("tiINISuperIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType)); 1114 /* 1115 error. unsupported IO 1116 */ 1117 } 1118 return tiStatus; 1119 } 1120 1121 osGLOBAL bit32 1122 tiINISMPStart( 1123 tiRoot_t *tiRoot, 1124 tiIORequest_t *tiIORequest, 1125 tiDeviceHandle_t *tiDeviceHandle, 1126 tiSMPFrame_t *tiSMPFrame, 1127 void *tiSMPBody, 1128 bit32 interruptContext 1129 ) 1130 { 1131 tdsaDeviceData_t *oneDeviceData; 1132 agsaIORequest_t *agIORequest = agNULL; 1133 tdIORequestBody_t *tdSMPRequestBody = agNULL; 1134 agsaRoot_t *agRoot = agNULL; 1135 agsaDevHandle_t *agDevHandle = agNULL; 1136 agsaSASRequestBody_t *agRequestBody = agNULL; 1137 agsaSMPFrame_t *agSMPFrame = agNULL; 1138 bit32 agRequestType; 1139 bit32 tiStatus = tiError; 1140 bit32 saStatus = AGSA_RC_FAILURE; 1141 bit32 queueNum; 1142 TDSA_INP_ENTER(tiRoot); 1143 TI_DBG6(("tiINISMPStart: start\n")); 1144 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1145 TI_DBG6(("tiINISMPStart: onedevicedata %p\n", oneDeviceData)); 1146 TI_DBG6(("tiINISMPStart: tiDeviceHandle %p\n", tiDeviceHandle)); 1147 if (oneDeviceData == agNULL) 1148 { 1149 TI_DBG1(("tiINISMPStart: tiDeviceHandle=%p Expander DeviceData is NULL\n", tiDeviceHandle )); 1150 return tiError; 1151 } 1152 if (tiIORequest->osData == agNULL) 1153 { 1154 TI_DBG1(("tiINISMPStart: tiIORequest->osData is NULL, wrong\n")); 1155 return tiError; 1156 } 1157 agRoot = oneDeviceData->agRoot; 1158 agDevHandle = oneDeviceData->agDevHandle; 1159 tdSMPRequestBody = (tdIORequestBody_t *)tiSMPBody; 1160 tdSMPRequestBody->tiIORequest = tiIORequest; 1161 tiIORequest->tdData = tdSMPRequestBody; 1162 agIORequest = &(tdSMPRequestBody->agIORequest); 1163 agIORequest->osData = (void *) tdSMPRequestBody; 1164 agRequestBody = &(tdSMPRequestBody->transport.SAS.agSASRequestBody); 1165 agSMPFrame = &(agRequestBody->smpFrame); 1166 if (!DEVICE_IS_SMP_TARGET(oneDeviceData)) 1167 { 1168 TI_DBG1(("tiINISMPStart: Target Device is not SMP device\n")); 1169 return tiError; 1170 } 1171 if (tiSMPFrame->flag == 0) // define DIRECT SMP at td layer? 1172 { 1173 TI_DBG6(("tiINISMPStart: Direct SMP\n")); 1174 agSMPFrame->outFrameBuf = tiSMPFrame->outFrameBuf; 1175 agSMPFrame->outFrameLen = tiSMPFrame->outFrameLen; 1176 tdhexdump("tiINISMPStart agSMPFrame", (bit8 *)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 1177 agSMPFrame->expectedRespLen = tiSMPFrame->expectedRespLen; 1178 agSMPFrame->inFrameLen = 0; 1179 agSMPFrame->flag = tiSMPFrame->flag; 1180 agRequestType = AGSA_SMP_INIT_REQ; 1181 queueNum = 0; 1182 saStatus = saSMPStart(agRoot, 1183 agIORequest, 1184 queueNum, 1185 agDevHandle, 1186 agRequestType, 1187 agRequestBody, 1188 &ossaSMPCAMCompleted 1189 ); 1190 if (saStatus == AGSA_RC_SUCCESS) 1191 { 1192 tiStatus = tiSuccess; 1193 } 1194 else 1195 { 1196 if (saStatus == AGSA_RC_BUSY) 1197 { 1198 TI_DBG1(("tiINISMPStart: saSSPStart busy\n")); 1199 tiStatus = tiBusy; 1200 } 1201 else 1202 { 1203 TI_DBG1(("tiINISMPStart: saSSPStart error\n")); 1204 tiStatus = tiError; 1205 } 1206 return tiStatus; 1207 } 1208 } 1209 else 1210 { 1211 TI_DBG1(("tiINISMPStart: Indirect SMP! Not supported yet\n")); 1212 tiStatus = tiError; 1213 } 1214 return tiStatus; 1215 } 1216 #ifdef TD_INT_COALESCE 1217 osGLOBAL bit32 1218 tiINIIOStartIntCoalesce( 1219 tiRoot_t *tiRoot, 1220 tiIORequest_t *tiIORequest, 1221 tiDeviceHandle_t *tiDeviceHandle, 1222 tiScsiInitiatorRequest_t *tiScsiRequest, 1223 void *tiRequestBody, 1224 bit32 interruptContext, 1225 tiIntCoalesceContext_t *tiIntCoalesceCxt 1226 ) 1227 { 1228 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1229 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1230 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 1231 tdsaDeviceData_t *oneDeviceData; 1232 agsaRoot_t *agRoot = agNULL; 1233 agsaIORequest_t *agIORequest = agNULL; 1234 agsaDevHandle_t *agDevHandle = agNULL; 1235 bit32 agRequestType; 1236 agsaSASRequestBody_t *agSASRequestBody = agNULL; 1237 bit32 tiStatus = tiError; 1238 bit32 saStatus = AGSA_RC_FAILURE; 1239 1240 tdIORequestBody_t *tdIORequestBody; 1241 agsaSSPInitiatorRequest_t *agSSPInitiatorRequest; 1242 tdsaIntCoalesceContext_t *tdsaIntCoalCxt; 1243 agsaIntCoalesceContext_t *agIntCoalCxt; 1244 1245 TI_DBG1(("tiINIIOStartIntCoalesce: start\n")); 1246 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1247 1248 TI_DBG6(("tiINIIOStartIntCoalesce: onedevicedata %p\n", oneDeviceData)); 1249 1250 if(oneDeviceData == agNULL) 1251 { 1252 TI_DBG1(("tiINIIOStartIntCoalesce: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle )); 1253 return tiIONoDevice; 1254 } 1255 1256 /* starting IO with SAS device */ 1257 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 1258 { 1259 TI_DBG6(("tiINIIOStartIntCoalesce: calling saSSPStart\n")); 1260 1261 agRoot = oneDeviceData->agRoot; 1262 agDevHandle = oneDeviceData->agDevHandle; 1263 1264 /* OS layer has tdlayer data structure pointer in 1265 tdIORequestBody_t tdIOReqBody; 1266 in ccb_t in agtiapi.h 1267 */ 1268 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1269 1270 /* let's initialize tdIOrequestBody */ 1271 /* initialize callback */ 1272 tdIORequestBody->IOCompletionFunc = itdssIOCompleted; 1273 1274 /* initialize tiDevhandle */ 1275 tdIORequestBody->tiDevHandle = tiDeviceHandle; 1276 1277 /* initialize tiIORequest */ 1278 tdIORequestBody->tiIORequest = tiIORequest; 1279 1280 /* save context if we need to abort later */ 1281 tiIORequest->tdData = tdIORequestBody; 1282 1283 /* initialize expDataLength */ 1284 tdIORequestBody->IOType.InitiatorRegIO.expDataLength 1285 = tiScsiRequest->scsiCmnd.expDataLength; 1286 1287 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */ 1288 tiStatus = itdssIOPrepareSGL( 1289 tiRoot, 1290 tdIORequestBody, 1291 &tiScsiRequest->agSgl1, 1292 tiScsiRequest->sglVirtualAddr 1293 ); 1294 1295 if (tiStatus != tiSuccess) 1296 { 1297 TI_DBG1(("tiINIIOStartIntCoalesce: can't get SGL\n")); 1298 return tiStatus; 1299 } 1300 1301 1302 /* initialize agIORequest */ 1303 agIORequest = &(tdIORequestBody->agIORequest); 1304 agIORequest->osData = (void *) tdIORequestBody; 1305 agIORequest->sdkData = agNULL; /* LL takes care of this */ 1306 1307 1308 /* 1309 initialize 1310 tdIORequestBody_t tdIORequestBody -> agSASRequestBody 1311 */ 1312 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); 1313 agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq); 1314 1315 1316 /* copy cdb bytes */ 1317 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16); 1318 1319 /* copy lun field */ 1320 osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, 1321 tiScsiRequest->scsiCmnd.lun.lun, 8); 1322 1323 /* setting the data length */ 1324 agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength; 1325 TI_DBG6(("tiINIIOStartIntCoalesce: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength)); 1326 1327 agSSPInitiatorRequest->firstBurstSize = 0; 1328 1329 if (tiScsiRequest->dataDirection == tiDirectionIn) 1330 { 1331 agRequestType = AGSA_SSP_INIT_READ; 1332 TI_DBG6(("tiINIIOStartIntCoalesce: READ\n")); 1333 } 1334 else if (tiScsiRequest->dataDirection == tiDirectionOut) 1335 { 1336 agRequestType = AGSA_SSP_INIT_WRITE; 1337 TI_DBG6(("tiINIIOStartIntCoalesce: WRITE\n")); 1338 } 1339 else 1340 { 1341 agRequestType = AGSA_REQ_TYPE_UNKNOWN; 1342 TI_DBG1(("tiINIIOStartIntCoalesce: unknown data direction\n")); 1343 } 1344 1345 tdIORequestBody->agRequestType = agRequestType; 1346 1347 tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData; 1348 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt); 1349 1350 1351 1352 #ifdef LL_INT_COALESCE 1353 saStatus = saSSPStartIntCoalesce(agRoot, 1354 agIORequest, 1355 agIntCoalCxt, 1356 agDevHandle, 1357 agRequestType, 1358 agSASRequestBody, 1359 &ossaSSPCompleted); 1360 #endif 1361 1362 tdIORequestBody->ioStarted = agTRUE; 1363 tdIORequestBody->ioCompleted = agFALSE; 1364 1365 if (saStatus == AGSA_RC_SUCCESS) 1366 { 1367 Initiator->NumIOsActive++; 1368 tiStatus = tiSuccess; 1369 } 1370 else 1371 { 1372 TI_DBG1(("tiINIIOStartIntCoalesce: saSSPStart failed\n")); 1373 tdIORequestBody->ioStarted = agFALSE; 1374 tdIORequestBody->ioCompleted = agTRUE; 1375 if (saStatus == AGSA_RC_BUSY) 1376 { 1377 tiStatus = tiBusy; 1378 } 1379 else 1380 { 1381 tiStatus = tiError; 1382 } 1383 return tiStatus; 1384 } 1385 } 1386 1387 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1388 { 1389 /* 1390 satIOStart() -> saSATAStartIntCoalesce() 1391 */ 1392 TI_DBG1(("tiINIIOStartIntCoalesce: SATA not supported yet\n")); 1393 return tiStatus; 1394 } 1395 else 1396 { 1397 TI_DBG1(("tiINIIOStartIntCoalesce: wrong unspported Device %d\n", oneDeviceData->DeviceType)); 1398 /* 1399 error. unsupported IO 1400 */ 1401 } 1402 return tiStatus; 1403 1404 1405 } 1406 1407 osGLOBAL bit32 1408 tiINIIOStartIntCoalesceDif( 1409 tiRoot_t *tiRoot, 1410 tiIORequest_t *tiIORequest, 1411 tiDeviceHandle_t *tiDeviceHandle, 1412 tiScsiInitiatorRequest_t *tiScsiRequest, 1413 void *tiRequestBody, 1414 bit32 interruptContext, 1415 tiIntCoalesceContext_t *tiIntCoalesceCxt, 1416 tiDif_t *difOption 1417 ) 1418 { 1419 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1420 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1421 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 1422 tdsaDeviceData_t *oneDeviceData; 1423 agsaRoot_t *agRoot = agNULL; 1424 agsaIORequest_t *agIORequest = agNULL; 1425 agsaDevHandle_t *agDevHandle = agNULL; 1426 bit32 agRequestType; 1427 agsaDifSSPRequestBody_t *agEdcSSPRequestBody = agNULL; 1428 bit32 tiStatus = tiError; 1429 bit32 saStatus = AGSA_RC_FAILURE; 1430 1431 tdIORequestBody_t *tdIORequestBody; 1432 agsaDifSSPInitiatorRequest_t *agEdcSSPInitiatorRequest; 1433 agsaDif_t *agEdc; 1434 bit32 agUpdateMask = 0; 1435 bit32 agVerifyMask = 0; 1436 tdsaIntCoalesceContext_t *tdsaIntCoalCxt; 1437 agsaIntCoalesceContext_t *agIntCoalCxt; 1438 1439 TI_DBG1(("tiINIIOStartIntCoalesceDif: start\n")); 1440 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1441 1442 TI_DBG6(("tiINIIOStartIntCoalesceDif: onedevicedata %p\n", oneDeviceData)); 1443 1444 if(oneDeviceData == agNULL) 1445 { 1446 TI_DBG1(("tiINIIOStartIntCoalesceDif: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle )); 1447 return tiIONoDevice; 1448 } 1449 1450 /* starting IO with SAS device */ 1451 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 1452 { 1453 TI_DBG6(("tiINIIOStartIntCoalesceDif: calling saSSPStart\n")); 1454 1455 agRoot = oneDeviceData->agRoot; 1456 agDevHandle = oneDeviceData->agDevHandle; 1457 1458 /* OS layer has tdlayer data structure pointer in 1459 tdIORequestBody_t tdIOReqBody; 1460 in ccb_t in agtiapi.h 1461 */ 1462 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1463 1464 /* let's initialize tdIOrequestBody */ 1465 /* initialize callback */ 1466 tdIORequestBody->IOCompletionFunc = itdssIOCompleted; 1467 1468 /* initialize tiDevhandle */ 1469 tdIORequestBody->tiDevHandle = tiDeviceHandle; 1470 1471 /* initialize tiIORequest */ 1472 tdIORequestBody->tiIORequest = tiIORequest; 1473 1474 /* save context if we need to abort later */ 1475 tiIORequest->tdData = tdIORequestBody; 1476 1477 /* initialize expDataLength */ 1478 tdIORequestBody->IOType.InitiatorRegIO.expDataLength 1479 = tiScsiRequest->scsiCmnd.expDataLength; 1480 1481 /* initializes "agsaSgl_t agSgl" of "agsaDifSSPInitiatorRequest_t" */ 1482 tiStatus = itdssIOPrepareSGL( 1483 tiRoot, 1484 tdIORequestBody, 1485 &tiScsiRequest->agSgl1, 1486 tiScsiRequest->sglVirtualAddr 1487 ); 1488 1489 if (tiStatus != tiSuccess) 1490 { 1491 TI_DBG1(("tiINIIOStartIntCoalesceDif: can't get SGL\n")); 1492 return tiStatus; 1493 } 1494 1495 1496 /* initialize agIORequest */ 1497 agIORequest = &(tdIORequestBody->agIORequest); 1498 agIORequest->osData = (void *) tdIORequestBody; 1499 agIORequest->sdkData = agNULL; /* LL takes care of this */ 1500 1501 1502 /* 1503 initialize 1504 tdIORequestBody_t tdIORequestBody -> agSASRequestBody 1505 */ 1506 agEdcSSPRequestBody = &(tdIORequestBody->transport.SAS.agEdcSSPRequestBody); 1507 agEdcSSPInitiatorRequest = &(agEdcSSPRequestBody->edcSSPInitiatorReq); 1508 1509 1510 /* copy cdb bytes */ 1511 osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16); 1512 1513 /* copy lun field */ 1514 osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.lun, 1515 tiScsiRequest->scsiCmnd.lun.lun, 8); 1516 1517 1518 /* setting the data length */ 1519 agEdcSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength; 1520 TI_DBG6(("tiINIIOStartIntCoalesceDif: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength)); 1521 1522 agEdcSSPInitiatorRequest->firstBurstSize = 0; 1523 1524 1525 if (tiScsiRequest->dataDirection == tiDirectionIn) 1526 { 1527 agRequestType = AGSA_SSP_INIT_READ; 1528 TI_DBG1(("tiINIIOStartIntCoalesceDif: READ difAction %X\n",difOption->difAction)); 1529 } 1530 else if (tiScsiRequest->dataDirection == tiDirectionOut) 1531 { 1532 agRequestType = AGSA_SSP_INIT_WRITE; 1533 TI_DBG1(("tiINIIOStartIntCoalesceDif: WRITE difAction %X\n",difOption->difAction)); 1534 } 1535 else 1536 { 1537 agRequestType = AGSA_REQ_TYPE_UNKNOWN; 1538 TI_DBG1(("tiINIIOStartIntCoalesceDif: unknown data direction\n")); 1539 } 1540 1541 tdIORequestBody->agRequestType = agRequestType; 1542 1543 /* process interrupt coalesce context */ 1544 tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData; 1545 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt); 1546 1547 /* process DIF */ 1548 1549 agEdc = &(agEdcSSPInitiatorRequest->edc); 1550 1551 osti_memset(agEdc, 0, sizeof(agsaDif_t)); 1552 1553 /* setting edcFlag */ 1554 if (difOption->enableBlockCount) 1555 { 1556 /* enables block count; bit5 */ 1557 agEdc->edcFlag = agEdc->edcFlag | 0x20; /* 0010 0000 */ 1558 } 1559 1560 if (difOption->enableCrc) 1561 { 1562 /* enables CRC verification; bit6 */ 1563 agEdc->edcFlag = agEdc->edcFlag | 0x40; /* 0100 0000 */ 1564 } 1565 1566 if (difOption->enableIOSeed) 1567 { 1568 1569 } 1570 if (difOption->difAction == DIF_INSERT) 1571 { 1572 /* bit 0 - 2; 000 */ 1573 agEdc->edcFlag = agEdc->edcFlag & 0xFFFFFFF8; 1574 } 1575 else if (difOption->difAction == DIF_VERIFY_FORWARD) 1576 { 1577 /* bit 0 - 2; 001 */ 1578 agEdc->edcFlag = agEdc->edcFlag | 0x01; 1579 } 1580 else if (difOption->difAction == DIF_VERIFY_DELETE) 1581 { 1582 /* bit 0 - 2; 010 */ 1583 agEdc->edcFlag = agEdc->edcFlag | 0x02; 1584 } 1585 else 1586 { 1587 /* DIF_VERIFY_REPLACE */ 1588 /* bit 0 - 2; 011 */ 1589 agEdc->edcFlag = agEdc->edcFlag | 0x04; 1590 } 1591 1592 /* set Update Mask; bit 16-21 */ 1593 agUpdateMask = (difOption->tagUpdateMask) & 0x3F; /* 0011 1111 */ 1594 agUpdateMask = agUpdateMask << 16; 1595 agEdc->edcFlag = agEdc->edcFlag | agUpdateMask; 1596 1597 /* set Verify Mask bit 24-29 */ 1598 agVerifyMask = (difOption->tagVerifyMask) & 0x3F; /* 0011 1111 */ 1599 agVerifyMask = agVerifyMask << 24; 1600 agEdc->edcFlag = agEdc->edcFlag | agVerifyMask; 1601 1602 agEdc->appTag = difOption->udtArray[0]; 1603 agEdc->appTag = (agEdc->appTag << 8) | difOption->udtArray[1]; 1604 1605 agEdc->lbaReferenceTag = difOption->udtArray[2]; 1606 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[3]; 1607 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[4]; 1608 agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[5]; 1609 1610 /* currently TISA supports only 512 logical block size */ 1611 agEdc->lbSize = 512; 1612 1613 1614 #ifdef LL_INT_COALESCE 1615 saStatus = saSSPStartIntCoalesceEdc(agRoot, 1616 agIORequest, 1617 agIntCoalCxt, 1618 agDevHandle, 1619 agRequestType, 1620 agEdcSSPRequestBody, 1621 &ossaSSPCompleted); 1622 #endif 1623 1624 tdIORequestBody->ioStarted = agTRUE; 1625 tdIORequestBody->ioCompleted = agFALSE; 1626 1627 if (saStatus == AGSA_RC_SUCCESS) 1628 { 1629 Initiator->NumIOsActive++; 1630 tiStatus = tiSuccess; 1631 } 1632 else 1633 { 1634 TI_DBG1(("tiINIIOStartIntCoalesceDif: saSSPStart failed\n")); 1635 tdIORequestBody->ioStarted = agFALSE; 1636 tdIORequestBody->ioCompleted = agTRUE; 1637 if (saStatus == AGSA_RC_BUSY) 1638 { 1639 tiStatus = tiBusy; 1640 } 1641 else 1642 { 1643 tiStatus = tiError; 1644 } 1645 return tiStatus; 1646 } 1647 } 1648 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1649 { 1650 /* 1651 satIOStart() -> saSATAStartIntCoalesceEdc() 1652 */ 1653 TI_DBG1(("tiINIIOStartIntCoalesceDif: SATA not supported yet\n")); 1654 return tiStatus; 1655 } 1656 else 1657 { 1658 TI_DBG1(("tiINIIOStartIntCoalesceDif: wrong unspported Device %d\n", oneDeviceData->DeviceType)); 1659 /* 1660 error. unsupported IO 1661 */ 1662 } 1663 return tiStatus; 1664 } 1665 1666 1667 osGLOBAL bit32 1668 tiINIIntCoalesceInit( 1669 tiRoot_t *tiRoot, 1670 tiIntCoalesceContext_t *tiIntCoalesceCxt, 1671 bit32 count 1672 ) 1673 { 1674 1675 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1676 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1677 agsaRoot_t *agRoot = agNULL; 1678 tdsaIntCoalesceContext_t *tdsaIntCoalCxtHead 1679 = (tdsaIntCoalesceContext_t *)tdsaAllShared->IntCoalesce; 1680 tdsaIntCoalesceContext_t *tdsaIntCoalCxt; 1681 agsaIntCoalesceContext_t *agIntCoalCxt; 1682 tdList_t *tdsaIntCoalCxtList = agNULL; 1683 1684 bit32 tiStatus = tiError; 1685 1686 TI_DBG1(("tiINIIntCoalesceInit: start\n")); 1687 1688 tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK); 1689 if (TDLIST_NOT_EMPTY(&(tdsaIntCoalCxtHead->FreeLink))) 1690 { 1691 TDLIST_DEQUEUE_FROM_HEAD(&tdsaIntCoalCxtList, &(tdsaIntCoalCxtHead->FreeLink)); 1692 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK); 1693 tdsaIntCoalCxt 1694 = TDLIST_OBJECT_BASE(tdsaIntCoalesceContext_t, FreeLink, tdsaIntCoalCxtList); 1695 1696 TI_DBG1(("tiINIIntCoalesceInit: id %d\n", tdsaIntCoalCxt->id)); 1697 1698 agRoot = &(tdsaAllShared->agRootNonInt); 1699 1700 agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt); 1701 tdsaIntCoalCxt->tiIntCoalesceCxt = tiIntCoalesceCxt; 1702 tiIntCoalesceCxt->tdData = tdsaIntCoalCxt; 1703 agIntCoalCxt->osData = tdsaIntCoalCxt; 1704 1705 tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK); 1706 TDLIST_ENQUEUE_AT_TAIL(&(tdsaIntCoalCxt->MainLink), &(tdsaIntCoalCxtHead->MainLink)); 1707 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK); 1708 1709 /* 1710 note: currently asynchronously call is assumed. In other words, 1711 "ossaIntCoalesceInitCB()" -> "ostiInitiatorCoalesceInitCB()" are used 1712 */ 1713 #ifdef LL_INT_COALESCE 1714 tiStatus = saIntCoalesceInit(agRoot, agIntCoalCxt, count); 1715 #endif 1716 1717 TI_DBG6(("tiINIIntCoalesceInit: status %d\n", tiStatus)); 1718 return tiStatus; 1719 } 1720 else 1721 { 1722 tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK); 1723 TI_DBG1(("tiINIIntCoalesceInit: no more interrupt coalesce context; return fail\n")); 1724 return tiStatus; 1725 } 1726 } 1727 #endif /* TD_INT_COALESCE */ 1728 1729 /***************************************************************************** 1730 *! \brief itdssIOPrepareSGL 1731 * 1732 * Purpose: This function is called to translate TISA SGL information to the 1733 * LL layer SGL. 1734 * 1735 * \param tiRoot: Pointer to initiator driver/port instance. 1736 * \param IORequestBody: TD layer request body for the I/O. 1737 * \param tiSgl1: First TISA SGL info. 1738 * \param sglVirtualAddr: The virtual address of the first element in 1739 * tiSgl1 when tiSgl1 is used with the type tiSglList. 1740 * 1741 * \return: 1742 * 1743 * tiSuccess: SGL initialized successfully. 1744 * tiError: Failed to initialize SGL. 1745 * 1746 * 1747 *****************************************************************************/ 1748 osGLOBAL FORCEINLINE bit32 1749 itdssIOPrepareSGL( 1750 tiRoot_t *tiRoot, 1751 tdIORequestBody_t *tdIORequestBody, 1752 tiSgl_t *tiSgl1, 1753 void *sglVirtualAddr 1754 ) 1755 { 1756 agsaSgl_t *agSgl; 1757 1758 TI_DBG6(("itdssIOPrepareSGL: start\n")); 1759 1760 agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspInitiatorReq.agSgl); 1761 1762 agSgl->len = 0; 1763 1764 if (tiSgl1 == agNULL) 1765 { 1766 TI_DBG1(("itdssIOPrepareSGL: Error tiSgl1 is NULL\n")); 1767 return tiError; 1768 } 1769 1770 if (tdIORequestBody->IOType.InitiatorRegIO.expDataLength == 0) 1771 { 1772 TI_DBG6(("itdssIOPrepareSGL: expDataLength is 0\n")); 1773 agSgl->sgUpper = 0; 1774 agSgl->sgLower = 0; 1775 agSgl->len = 0; 1776 CLEAR_ESGL_EXTEND(agSgl->extReserved); 1777 return tiSuccess; 1778 } 1779 1780 agSgl->sgUpper = tiSgl1->upper; 1781 agSgl->sgLower = tiSgl1->lower; 1782 agSgl->len = tiSgl1->len; 1783 agSgl->extReserved = tiSgl1->type; 1784 1785 return tiSuccess; 1786 } 1787 1788 osGLOBAL bit32 1789 tiNumOfLunIOCTLreq( 1790 tiRoot_t *tiRoot, 1791 tiIORequest_t *tiIORequest, 1792 tiDeviceHandle_t *tiDeviceHandle, 1793 void *tiRequestBody, 1794 tiIOCTLPayload_t *agIOCTLPayload, 1795 void *agParam1, 1796 void *agParam2 1797 ) 1798 { 1799 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1800 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1801 agsaRoot_t *agRoot = &(tdsaAllShared->agRootInt); 1802 void *respBuffer = agNULL; 1803 void *osMemHandle = agNULL; 1804 bit32 ostiMemoryStatus = 0; 1805 tdsaDeviceData_t *oneDeviceData = agNULL; 1806 agsaSSPInitiatorRequest_t *agSSPFrame = agNULL; 1807 bit32 status = IOCTL_CALL_SUCCESS; 1808 bit32 agRequestType = 0; 1809 agsaDevHandle_t *agDevHandle = agNULL; 1810 agsaIORequest_t *agIORequest = agNULL; 1811 tdIORequestBody_t *tdIORequestBody = agNULL; 1812 agsaSASRequestBody_t *agSASRequestBody = agNULL; 1813 1814 do 1815 { 1816 if((tiIORequest == agNULL) || (tiRequestBody == agNULL)) 1817 { 1818 status = IOCTL_CALL_FAIL; 1819 break; 1820 } 1821 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 1822 tdIORequestBody->tiIORequest = tiIORequest; 1823 1824 /* save context if we need to abort later */ 1825 tiIORequest->tdData = tdIORequestBody; 1826 1827 agIORequest = &(tdIORequestBody->agIORequest); 1828 agIORequest->osData = (void *) tdIORequestBody; 1829 agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); 1830 agSSPFrame = &(agSASRequestBody->sspInitiatorReq); 1831 1832 ostiMemoryStatus = ostiAllocMemory( tiRoot, 1833 &osMemHandle, 1834 (void **)&respBuffer, 1835 &(agSSPFrame->agSgl.sgUpper), 1836 &(agSSPFrame->agSgl.sgLower), 1837 8, 1838 REPORT_LUN_LEN, 1839 agFALSE); 1840 if((ostiMemoryStatus != tiSuccess) && (respBuffer == agNULL )) 1841 { 1842 status = IOCTL_CALL_FAIL; 1843 break; 1844 } 1845 1846 osti_memset((void *)respBuffer, 0, REPORT_LUN_LEN); 1847 1848 // use FW control place in shared structure to keep the neccesary information 1849 tdsaAllShared->tdFWControlEx.virtAddr = respBuffer; 1850 tdsaAllShared->tdFWControlEx.len = REPORT_LUN_LEN; 1851 tdsaAllShared->tdFWControlEx.param1 = agParam1; 1852 tdsaAllShared->tdFWControlEx.param2 = agParam2; 1853 tdsaAllShared->tdFWControlEx.payload = agIOCTLPayload; 1854 tdsaAllShared->tdFWControlEx.inProgress = 1; 1855 agRequestType = AGSA_SSP_INIT_READ; 1856 1857 status = IOCTL_CALL_PENDING; 1858 oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData); 1859 agDevHandle = oneDeviceData->agDevHandle; 1860 1861 agSSPFrame->sspCmdIU.cdb[0] = REPORT_LUN_OPCODE; 1862 agSSPFrame->sspCmdIU.cdb[1] = 0x0; 1863 agSSPFrame->sspCmdIU.cdb[2] = 0x0; 1864 agSSPFrame->sspCmdIU.cdb[3] = 0x0; 1865 agSSPFrame->sspCmdIU.cdb[4] = 0x0; 1866 agSSPFrame->sspCmdIU.cdb[5] = 0x0; 1867 agSSPFrame->sspCmdIU.cdb[6] = 0x0; 1868 agSSPFrame->sspCmdIU.cdb[7] = 0x0; 1869 agSSPFrame->sspCmdIU.cdb[8] = 0x0; 1870 agSSPFrame->sspCmdIU.cdb[9] = REPORT_LUN_LEN; 1871 agSSPFrame->sspCmdIU.cdb[10] = 0x0; 1872 agSSPFrame->sspCmdIU.cdb[11] = 0x0; 1873 1874 agSSPFrame->dataLength = REPORT_LUN_LEN; 1875 agSSPFrame->agSgl.len = sizeof(agsaSSPCmdInfoUnit_t); 1876 agSSPFrame->agSgl.extReserved = 0; 1877 CLEAR_ESGL_EXTEND(agSSPFrame->agSgl.extReserved); 1878 1879 status = saSSPStart(agRoot, agIORequest, 0, agDevHandle, agRequestType,agSASRequestBody,agNULL, 1880 &ossaSSPIoctlCompleted); 1881 if(status != AGSA_RC_SUCCESS) 1882 { 1883 ostiFreeMemory(tiRoot, 1884 tdsaAllShared->tdFWControlEx.virtAddr, 1885 tdsaAllShared->tdFWControlEx.len); 1886 tdsaAllShared->tdFWControlEx.payload = NULL; 1887 tdsaAllShared->tdFWControlEx.inProgress = 0; 1888 status = IOCTL_CALL_FAIL; 1889 } 1890 }while(0); 1891 return status; 1892 } 1893 1894 1895