1285242Sachim/******************************************************************************* 2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285242Sachim* 4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285242Sachim*that the following conditions are met: 6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285242Sachim*following disclaimer. 8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice, 9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285242Sachim*with the distribution. 11285242Sachim* 12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285242Sachim 21285242Sachim********************************************************************************/ 22285242Sachim#include <sys/cdefs.h> 23285242Sachim__FBSDID("$FreeBSD$"); 24285242Sachim#include <dev/pms/config.h> 25285242Sachim 26285242Sachim#include <dev/pms/freebsd/driver/common/osenv.h> 27285242Sachim#include <dev/pms/freebsd/driver/common/ostypes.h> 28285242Sachim#include <dev/pms/freebsd/driver/common/osdebug.h> 29285242Sachim 30285242Sachim#include <dev/pms/RefTisa/tisa/api/titypes.h> 31285242Sachim 32285242Sachim#include <dev/pms/RefTisa/sallsdk/api/sa.h> 33285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 34285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 35285242Sachim 36285242Sachim#include <dev/pms/RefTisa/sat/api/sm.h> 37285242Sachim#include <dev/pms/RefTisa/sat/api/smapi.h> 38285242Sachim#include <dev/pms/RefTisa/sat/api/tdsmapi.h> 39285242Sachim 40285242Sachim#include <dev/pms/RefTisa/sat/src/smdefs.h> 41285242Sachim#include <dev/pms/RefTisa/sat/src/smproto.h> 42285242Sachim#include <dev/pms/RefTisa/sat/src/smtypes.h> 43285242Sachim 44285242Sachim/* 45285242Sachim * This table is used to map LL Layer saSATAStart() status to TISA status. 46285242Sachim */ 47285242Sachim 48285242Sachim 49285242SachimFORCEINLINE bit32 50285242SachimsmsataLLIOStart( 51285242Sachim smRoot_t *smRoot, 52285242Sachim smIORequest_t *smIORequest, 53285242Sachim smDeviceHandle_t *smDeviceHandle, 54285242Sachim smScsiInitiatorRequest_t *smScsiRequest, 55285242Sachim smSatIOContext_t *satIOContext 56285242Sachim ) 57285242Sachim{ 58285242Sachim smDeviceData_t *oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 59285242Sachim smIntRoot_t *smIntRoot = (smIntRoot_t *) smRoot->smData; 60285242Sachim smIntContext_t *smAllShared = (smIntContext_t *)&(smIntRoot->smAllShared); 61285242Sachim smIORequestBody_t *smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 62285242Sachim smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 63285242Sachim smSatInternalIo_t *satIntIo = satIOContext->satIntIoContext; 64285242Sachim agsaRoot_t *agRoot = smAllShared->agRoot; 65285242Sachim agsaIORequest_t *agIORequest = &(smIORequestBody->agIORequest); 66285242Sachim agsaDevHandle_t *agDevHandle = oneDeviceData->agDevHandle; 67285242Sachim agsaSATAInitiatorRequest_t *agSATAReq = &(smIORequestBody->transport.SATA.agSATARequestBody); 68285242Sachim bit32 RLERecovery = agFALSE; 69285242Sachim bit32 status = SM_RC_FAILURE; 70285242Sachim bit32 nQNumber = 0; 71285242Sachim /* 72285242Sachim * If this is a super I/O request, check for optional settings. 73285242Sachim * Be careful. Use the superRequest pointer for all references 74285242Sachim * in this block of code. 75285242Sachim */ 76285242Sachim agSATAReq->option = 0; 77285242Sachim if (satIOContext->superIOFlag) 78285242Sachim { 79285242Sachim smSuperScsiInitiatorRequest_t *superRequest = (smSuperScsiInitiatorRequest_t *) smScsiRequest; 80285242Sachim 81285242Sachim if (superRequest->flags & SM_SCSI_INITIATOR_ENCRYPT) 82285242Sachim { 83285242Sachim /* Copy all of the relevant encrypt information */ 84285242Sachim agSATAReq->option |= AGSA_SATA_ENABLE_ENCRYPTION; 85285242Sachim sm_memcpy(&agSATAReq->encrypt, &superRequest->Encrypt, sizeof(agsaEncrypt_t)); 86285242Sachim } 87285242Sachim { 88285242Sachim /* initialize expDataLength */ 89285242Sachim if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA || 90285242Sachim satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT || 91285242Sachim satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT ) 92285242Sachim { 93285242Sachim smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 94285242Sachim } 95285242Sachim else 96285242Sachim { 97285242Sachim smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength; 98285242Sachim } 99285242Sachim 100285242Sachim agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength; 101285242Sachim } 102285242Sachim } 103285242Sachim else 104285242Sachim { 105285242Sachim /* initialize expDataLength */ 106285242Sachim if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA || 107285242Sachim satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT || 108285242Sachim satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT ) 109285242Sachim { 110285242Sachim smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 111285242Sachim } 112285242Sachim else 113285242Sachim { 114285242Sachim smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength; 115285242Sachim } 116285242Sachim 117285242Sachim agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength; 118285242Sachim } 119285242Sachim 120285242Sachim if ( (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) && 121285242Sachim (satIOContext->pFis->h.command == SAT_READ_LOG_EXT) ) 122285242Sachim { 123285242Sachim RLERecovery = agTRUE; 124285242Sachim } 125285242Sachim 126285242Sachim /* check max io, be sure to free */ 127285242Sachim if ( (pSatDevData->satDriveState != SAT_DEV_STATE_IN_RECOVERY) || 128285242Sachim (RLERecovery == agTRUE) ) 129285242Sachim { 130285242Sachim if (RLERecovery == agFALSE) /* RLE is not checked against pending IO's */ 131285242Sachim { 132285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 133285242Sachim bit32 volatile satPendingNCQIO = 0; 134285242Sachim bit32 volatile satPendingNONNCQIO = 0; 135285242Sachim bit32 volatile satPendingIO = 0; 136285242Sachim 137285242Sachim tdsmInterlockedExchange(smRoot, &satPendingNCQIO, pSatDevData->satPendingNCQIO); 138285242Sachim tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, pSatDevData->satPendingNONNCQIO); 139285242Sachim tdsmInterlockedExchange(smRoot, &satPendingIO, pSatDevData->satPendingIO); 140285242Sachim#endif 141285242Sachim 142285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 143285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 144285242Sachim { 145285242Sachim #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 146285242Sachim if ( satPendingNCQIO >= pSatDevData->satNCQMaxIO || 147285242Sachim satPendingNONNCQIO != 0) 148285242Sachim { 149285242Sachim SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id)); 150285242Sachim SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 151285242Sachim satPendingNONNCQIO, satPendingIO)); 152285242Sachim /* free resource */ 153285242Sachim smsatFreeIntIoResource( smRoot, 154285242Sachim pSatDevData, 155285242Sachim satIntIo); 156285242Sachim return SM_RC_DEVICE_BUSY; 157285242Sachim } 158285242Sachim #else 159285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 160285242Sachim if (pSatDevData->satPendingNCQIO >= pSatDevData->satNCQMaxIO || 161285242Sachim pSatDevData->satPendingNONNCQIO != 0) 162285242Sachim { 163285242Sachim SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id)); 164285242Sachim SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 165285242Sachim pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 166285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 167285242Sachim /* free resource */ 168285242Sachim smsatFreeIntIoResource( smRoot, 169285242Sachim pSatDevData, 170285242Sachim satIntIo); 171285242Sachim return SM_RC_DEVICE_BUSY; 172285242Sachim } 173285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 174285242Sachim #endif 175285242Sachim 176285242Sachim } 177285242Sachim else if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_D2H_PKT) || 178285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_H2D_PKT) || 179285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_PKT) ) 180285242Sachim { 181285242Sachim sm_memcpy(agSATAReq->scsiCDB, smScsiRequest->scsiCmnd.cdb, 16); 182285242Sachim #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 183285242Sachim if ( satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX || 184285242Sachim satPendingNCQIO != 0) 185285242Sachim { 186285242Sachim SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id)); 187285242Sachim SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 188285242Sachim satPendingNONNCQIO, satPendingIO)); 189285242Sachim /* free resource */ 190285242Sachim smsatFreeIntIoResource( smRoot, 191285242Sachim pSatDevData, 192285242Sachim satIntIo); 193285242Sachim return SM_RC_DEVICE_BUSY; 194285242Sachim } 195285242Sachim #else 196285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 197285242Sachim if ( pSatDevData->satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX || 198285242Sachim pSatDevData->satPendingNCQIO != 0) 199285242Sachim { 200285242Sachim SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id)); 201285242Sachim SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 202285242Sachim pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 203285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 204285242Sachim /* free resource */ 205285242Sachim smsatFreeIntIoResource( smRoot, 206285242Sachim pSatDevData, 207285242Sachim satIntIo); 208285242Sachim return SM_RC_DEVICE_BUSY; 209285242Sachim } 210285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 211285242Sachim #endif 212285242Sachim 213285242Sachim } 214285242Sachim else 215285242Sachim { 216285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 217285242Sachim if ( satPendingNONNCQIO >= SAT_NONNCQ_MAX || 218285242Sachim satPendingNCQIO != 0) 219285242Sachim { 220285242Sachim SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id)); 221285242Sachim SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 222285242Sachim satPendingNONNCQIO, satPendingIO)); 223285242Sachim /* free resource */ 224285242Sachim smsatFreeIntIoResource( smRoot, 225285242Sachim pSatDevData, 226285242Sachim satIntIo); 227285242Sachim return SM_RC_DEVICE_BUSY; 228285242Sachim } 229285242Sachim#else 230285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 231285242Sachim if (pSatDevData->satPendingNONNCQIO >= SAT_NONNCQ_MAX || 232285242Sachim pSatDevData->satPendingNCQIO != 0) 233285242Sachim { 234285242Sachim SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id)); 235285242Sachim SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 236285242Sachim pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 237285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 238285242Sachim /* free resource */ 239285242Sachim smsatFreeIntIoResource( smRoot, 240285242Sachim pSatDevData, 241285242Sachim satIntIo); 242285242Sachim return SM_RC_DEVICE_BUSY; 243285242Sachim } 244285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 245285242Sachim#endif 246285242Sachim } 247285242Sachim } /* RLE */ 248285242Sachim /* for internal SATA command only */ 249285242Sachim if (satIOContext->satOrgIOContext != agNULL) 250285242Sachim { 251285242Sachim /* Initialize tiIORequest */ 252285242Sachim smIORequestBody->smIORequest = smIORequest; 253285242Sachim if (smIORequest == agNULL) 254285242Sachim { 255285242Sachim SM_DBG1(("smsataLLIOStart: 1 check!!!\n")); 256285242Sachim } 257285242Sachim } 258285242Sachim /* Initialize tiDevhandle */ 259285242Sachim smIORequestBody->smDevHandle = smDeviceHandle; 260285242Sachim 261285242Sachim /* Initializes Scatter Gather and ESGL */ 262285242Sachim status = smsatIOPrepareSGL( smRoot, 263285242Sachim smIORequestBody, 264285242Sachim &smScsiRequest->smSgl1, 265285242Sachim smScsiRequest->sglVirtualAddr ); 266285242Sachim 267285242Sachim if (status != SM_RC_SUCCESS) 268285242Sachim { 269285242Sachim SM_DBG1(("smsataLLIOStart: can't get SGL!!!\n")); 270285242Sachim /* free resource */ 271285242Sachim smsatFreeIntIoResource( smRoot, 272285242Sachim pSatDevData, 273285242Sachim satIntIo); 274285242Sachim return status; 275285242Sachim } 276285242Sachim 277285242Sachim /* Initialize LL Layer agIORequest */ 278285242Sachim agIORequest->osData = (void *) smIORequestBody; 279285242Sachim agIORequest->sdkData = agNULL; /* SA takes care of this */ 280285242Sachim 281285242Sachim smIORequestBody->ioStarted = agTRUE; 282285242Sachim smIORequestBody->ioCompleted = agFALSE; 283285242Sachim 284285242Sachim /* assign tag value for SATA */ 285285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 286285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 287285242Sachim { 288285242Sachim if (agFALSE == smsatTagAlloc(smRoot, pSatDevData, &satIOContext->sataTag)) 289285242Sachim { 290285242Sachim SM_DBG1(("smsataLLIOStart: No more NCQ tag!!!\n")); 291285242Sachim smIORequestBody->ioStarted = agFALSE; 292285242Sachim smIORequestBody->ioCompleted = agTRUE; 293285242Sachim return SM_RC_DEVICE_BUSY; 294285242Sachim } 295285242Sachim SM_DBG3(("smsataLLIOStart: ncq tag 0x%x\n",satIOContext->sataTag)); 296285242Sachim } 297285242Sachim else 298285242Sachim { 299285242Sachim satIOContext->sataTag = 0xFF; 300285242Sachim } 301285242Sachim } 302285242Sachim else /* AGSA_SATA_PROTOCOL_SRST_ASSERT or AGSA_SATA_PROTOCOL_SRST_DEASSERT 303285242Sachim or SAT_CHECK_POWER_MODE as ABORT */ 304285242Sachim { 305285242Sachim agsaSgl_t *agSgl; 306285242Sachim 307285242Sachim /* for internal SATA command only */ 308285242Sachim if (satIOContext->satOrgIOContext != agNULL) 309285242Sachim { 310285242Sachim /* Initialize tiIORequest */ 311285242Sachim smIORequestBody->smIORequest = smIORequest; 312285242Sachim if (smIORequest == agNULL) 313285242Sachim { 314285242Sachim SM_DBG1(("smsataLLIOStart: 2 check!!!\n")); 315285242Sachim } 316285242Sachim } 317285242Sachim /* Initialize tiDevhandle */ 318285242Sachim smIORequestBody->smDevHandle = smDeviceHandle; 319285242Sachim 320285242Sachim 321285242Sachim smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 322285242Sachim /* SGL for SATA request */ 323285242Sachim agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl); 324285242Sachim agSgl->len = 0; 325285242Sachim 326285242Sachim agSgl->sgUpper = 0; 327285242Sachim agSgl->sgLower = 0; 328285242Sachim agSgl->len = 0; 329285242Sachim SM_CLEAR_ESGL_EXTEND(agSgl->extReserved); 330285242Sachim 331285242Sachim /* Initialize LL Layer agIORequest */ 332285242Sachim agIORequest = &(smIORequestBody->agIORequest); 333285242Sachim agIORequest->osData = (void *) smIORequestBody; 334285242Sachim agIORequest->sdkData = agNULL; /* SA takes care of this */ 335285242Sachim 336285242Sachim smIORequestBody->ioStarted = agTRUE; 337285242Sachim smIORequestBody->ioCompleted = agFALSE; 338285242Sachim 339285242Sachim /* setting the data length */ 340285242Sachim agSATAReq->dataLength = 0; 341285242Sachim 342285242Sachim } 343285242Sachim 344285242Sachim 345285242Sachim smIORequestBody->reTries = 0; 346285242Sachim 347285242Sachim#ifdef TD_INTERNAL_DEBUG 348285242Sachim smhexdump("smsataLLIOStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 349285242Sachim smhexdump("smsataLLIOStart LL", (bit8 *)&agSATAReq->fis.fisRegHostToDev, 350285242Sachim sizeof(agsaFisRegHostToDevice_t)); 351285242Sachim#endif 352285242Sachim 353285242Sachim SM_DBG6(("smsataLLIOStart: agDevHandle %p\n", agDevHandle)); 354285242Sachim 355285242Sachim /* to get better IO performance, rotate the OBQ number on main IO path */ 356285242Sachim if (smScsiRequest == agNULL) 357285242Sachim { 358285242Sachim nQNumber = 0; 359285242Sachim } 360285242Sachim else 361285242Sachim { 362285242Sachim switch (smScsiRequest->scsiCmnd.cdb[0]) 363285242Sachim { 364285242Sachim case SCSIOPC_READ_10: 365285242Sachim case SCSIOPC_WRITE_10: 366285242Sachim case SCSIOPC_READ_6: 367285242Sachim case SCSIOPC_WRITE_6: 368285242Sachim case SCSIOPC_READ_12: 369285242Sachim case SCSIOPC_WRITE_12: 370285242Sachim case SCSIOPC_READ_16: 371285242Sachim case SCSIOPC_WRITE_16: 372285242Sachim nQNumber = tdsmRotateQnumber(smRoot, smDeviceHandle); 373285242Sachim break; 374285242Sachim 375285242Sachim default: 376285242Sachim nQNumber = 0; 377285242Sachim break; 378285242Sachim } 379285242Sachim } 380285242Sachim 381285242Sachim SM_DBG3(("sataLLIOStart: Lock in\n")); 382285242Sachim 383285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 384285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 385285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 386285242Sachim { 387285242Sachim tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNCQIO); 388285242Sachim } 389285242Sachim else 390285242Sachim { 391285242Sachim tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNONNCQIO); 392285242Sachim } 393285242Sachim tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingIO); 394285242Sachim#else 395285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 396285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 397285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 398285242Sachim { 399285242Sachim pSatDevData->satPendingNCQIO++; 400285242Sachim } 401285242Sachim else 402285242Sachim { 403285242Sachim pSatDevData->satPendingNONNCQIO++; 404285242Sachim } 405285242Sachim pSatDevData->satPendingIO++; 406285242Sachim 407285242Sachim SMLIST_INIT_ELEMENT (&satIOContext->satIoContextLink); 408285242Sachim SMLIST_ENQUEUE_AT_TAIL (&satIOContext->satIoContextLink, &pSatDevData->satIoLinkList); 409285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 410285242Sachim#endif 411285242Sachim /* post SATA command to low level MPI */ 412285242Sachim status = saSATAStart( agRoot, 413285242Sachim agIORequest, 414285242Sachim nQNumber, 415285242Sachim agDevHandle, 416285242Sachim satIOContext->reqType, 417285242Sachim agSATAReq, 418285242Sachim satIOContext->sataTag, 419285242Sachim smllSATACompleted 420285242Sachim ); 421285242Sachim 422285242Sachim if (status != AGSA_RC_SUCCESS) 423285242Sachim { 424285242Sachim if (status == AGSA_RC_BUSY) 425285242Sachim { 426285242Sachim SM_DBG1(("smsataLLIOStart: saSATAStart busy!!!\n")); 427285242Sachim status = SM_RC_BUSY; 428285242Sachim } 429285242Sachim else 430285242Sachim { 431285242Sachim SM_DBG1(("smsataLLIOStart: saSATAStart failed!!!\n")); 432285242Sachim status = SM_RC_FAILURE; 433285242Sachim } 434285242Sachim 435285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 436285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 437285242Sachim { 438285242Sachim smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag); 439285242Sachim } 440285242Sachim 441285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 442285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 443285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 444285242Sachim { 445285242Sachim tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO); 446285242Sachim } 447285242Sachim else 448285242Sachim { 449285242Sachim tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO); 450285242Sachim } 451285242Sachim tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO); 452285242Sachim#else 453285242Sachim if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 454285242Sachim (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 455285242Sachim { 456285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 457285242Sachim oneDeviceData->satPendingNCQIO--; 458285242Sachim oneDeviceData->satPendingIO--; 459285242Sachim SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink); 460285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 461285242Sachim } 462285242Sachim else 463285242Sachim { 464285242Sachim tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 465285242Sachim oneDeviceData->satPendingNONNCQIO--; 466285242Sachim oneDeviceData->satPendingIO--; 467285242Sachim SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink); 468285242Sachim tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 469285242Sachim } 470285242Sachim#endif /* CCFLAG_OPTIMIZE_SAT_LOCK */ 471285242Sachim 472285242Sachim /* Free the ESGL pages associated with this I/O */ 473285242Sachim smIORequestBody->ioStarted = agFALSE; 474285242Sachim smIORequestBody->ioCompleted = agTRUE; 475285242Sachim return (status); 476285242Sachim } 477285242Sachim 478285242Sachim return SM_RC_SUCCESS; 479285242Sachim} 480285242Sachim 481285242Sachim 482285242SachimosGLOBAL FORCEINLINE bit32 483285242SachimsmsatIOPrepareSGL( 484285242Sachim smRoot_t *smRoot, 485285242Sachim smIORequestBody_t *smIORequestBody, 486285242Sachim smSgl_t *smSgl1, 487285242Sachim void *sglVirtualAddr 488285242Sachim ) 489285242Sachim{ 490285242Sachim agsaSgl_t *agSgl; 491285242Sachim 492285242Sachim /* Uppper should be zero-out */ 493285242Sachim SM_DBG5(("smsatIOPrepareSGL: start\n")); 494285242Sachim 495285242Sachim SM_DBG5(("smsatIOPrepareSGL: smSgl1->upper %d smSgl1->lower %d smSgl1->len %d\n", 496285242Sachim smSgl1->upper, smSgl1->lower, smSgl1->len)); 497285242Sachim SM_DBG5(("smsatIOPrepareSGL: smSgl1->type %d\n", smSgl1->type)); 498285242Sachim 499285242Sachim /* SGL for SATA request */ 500285242Sachim agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl); 501285242Sachim agSgl->len = 0; 502285242Sachim 503285242Sachim if (smSgl1 == agNULL) 504285242Sachim { 505285242Sachim SM_DBG1(("smsatIOPrepareSGL: Error smSgl1 is NULL!!!\n")); 506285242Sachim return tiError; 507285242Sachim } 508285242Sachim 509285242Sachim if (smIORequestBody->IOType.InitiatorRegIO.expDataLength == 0) 510285242Sachim { 511285242Sachim SM_DBG3(("smsatIOPrepareSGL: expDataLength is 0\n")); 512285242Sachim agSgl->sgUpper = 0; 513285242Sachim agSgl->sgLower = 0; 514285242Sachim agSgl->len = 0; 515285242Sachim SM_CLEAR_ESGL_EXTEND(agSgl->extReserved); 516285242Sachim return SM_RC_SUCCESS; 517285242Sachim } 518285242Sachim 519285242Sachim agSgl->sgUpper = smSgl1->upper; 520285242Sachim agSgl->sgLower = smSgl1->lower; 521285242Sachim agSgl->len = smSgl1->len; 522285242Sachim agSgl->extReserved = smSgl1->type; 523285242Sachim 524285242Sachim return SM_RC_SUCCESS; 525285242Sachim 526285242Sachim} 527285242Sachim 528285242Sachim 529285242Sachim 530285242Sachim 531