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