1285809Sscottl/******************************************************************************* 2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285809Sscottl* 4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285809Sscottl*that the following conditions are met: 6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285809Sscottl*following disclaimer. 8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285809Sscottl*with the distribution. 11285809Sscottl* 12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285809Sscottl 21285809Sscottl********************************************************************************/ 22285809Sscottl#include <sys/cdefs.h> 23285809Sscottl__FBSDID("$FreeBSD$"); 24285809Sscottl#include <dev/pms/config.h> 25285809Sscottl 26285809Sscottl#include <dev/pms/freebsd/driver/common/osenv.h> 27285809Sscottl#include <dev/pms/freebsd/driver/common/ostypes.h> 28285809Sscottl#include <dev/pms/freebsd/driver/common/osdebug.h> 29285809Sscottl 30285809Sscottl#include <dev/pms/RefTisa/tisa/api/titypes.h> 31285809Sscottl 32285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/sa.h> 33285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 34285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 35285809Sscottl 36285809Sscottl#include <dev/pms/RefTisa/sat/api/sm.h> 37285809Sscottl#include <dev/pms/RefTisa/sat/api/smapi.h> 38285809Sscottl#include <dev/pms/RefTisa/sat/api/tdsmapi.h> 39285809Sscottl 40285809Sscottl#include <dev/pms/RefTisa/sat/src/smdefs.h> 41285809Sscottl#include <dev/pms/RefTisa/sat/src/smproto.h> 42285809Sscottl#include <dev/pms/RefTisa/sat/src/smtypes.h> 43285809Sscottl 44285809Sscottl/* 45285809Sscottl * This table is used to map LL Layer saSATAStart() status to TISA status. 46285809Sscottl */ 47285809Sscottl 48285809Sscottl 49285809SscottlFORCEINLINE bit32 50285809SscottlsmsataLLIOStart( 51285809Sscottl smRoot_t *smRoot, 52285809Sscottl smIORequest_t *smIORequest, 53285809Sscottl smDeviceHandle_t *smDeviceHandle, 54285809Sscottl smScsiInitiatorRequest_t *smScsiRequest, 55285809Sscottl smSatIOContext_t *satIOContext 56285809Sscottl ) 57285809Sscottl{ 58285809Sscottl smDeviceData_t *oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 59285809Sscottl smIntRoot_t *smIntRoot = (smIntRoot_t *) smRoot->smData; 60285809Sscottl smIntContext_t *smAllShared = (smIntContext_t *)&(smIntRoot->smAllShared); 61285809Sscottl smIORequestBody_t *smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 62285809Sscottl smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 63285809Sscottl smSatInternalIo_t *satIntIo = satIOContext->satIntIoContext; 64285809Sscottl agsaRoot_t *agRoot = smAllShared->agRoot; 65285809Sscottl agsaIORequest_t *agIORequest = &(smIORequestBody->agIORequest); 66285809Sscottl agsaDevHandle_t *agDevHandle = oneDeviceData->agDevHandle; 67285809Sscottl agsaSATAInitiatorRequest_t *agSATAReq = &(smIORequestBody->transport.SATA.agSATARequestBody); 68285809Sscottl bit32 RLERecovery = agFALSE; 69285809Sscottl bit32 status = SM_RC_FAILURE; 70285809Sscottl bit32 nQNumber = 0; 71285809Sscottl /* 72285809Sscottl * If this is a super I/O request, check for optional settings. 73285809Sscottl * Be careful. Use the superRequest pointer for all references 74285809Sscottl * in this block of code. 75285809Sscottl */ 76285809Sscottl agSATAReq->option = 0; 77285809Sscottl if (satIOContext->superIOFlag) 78285809Sscottl { 79285809Sscottl smSuperScsiInitiatorRequest_t *superRequest = (smSuperScsiInitiatorRequest_t *) smScsiRequest; 80285809Sscottl 81285809Sscottl if (superRequest->flags & SM_SCSI_INITIATOR_ENCRYPT) 82285809Sscottl { 83285809Sscottl /* Copy all of the relevant encrypt information */ 84285809Sscottl agSATAReq->option |= AGSA_SATA_ENABLE_ENCRYPTION; 85285809Sscottl sm_memcpy(&agSATAReq->encrypt, &superRequest->Encrypt, sizeof(agsaEncrypt_t)); 86285809Sscottl } 87285809Sscottl { 88285809Sscottl /* initialize expDataLength */ 89285809Sscottl if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA || 90285809Sscottl satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT || 91285809Sscottl satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT ) 92285809Sscottl { 93285809Sscottl smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 94285809Sscottl } 95285809Sscottl else 96285809Sscottl { 97285809Sscottl smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength; 98285809Sscottl } 99285809Sscottl 100285809Sscottl agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength; 101285809Sscottl } 102285809Sscottl } 103285809Sscottl else 104285809Sscottl { 105285809Sscottl /* initialize expDataLength */ 106285809Sscottl if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA || 107285809Sscottl satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT || 108285809Sscottl satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT ) 109285809Sscottl { 110285809Sscottl smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 111285809Sscottl } 112285809Sscottl else 113285809Sscottl { 114285809Sscottl smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength; 115285809Sscottl } 116285809Sscottl 117285809Sscottl agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength; 118285809Sscottl } 119285809Sscottl 120285809Sscottl if ( (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) && 121285809Sscottl (satIOContext->pFis->h.command == SAT_READ_LOG_EXT) ) 122285809Sscottl { 123285809Sscottl RLERecovery = agTRUE; 124285809Sscottl } 125285809Sscottl 126285809Sscottl /* check max io, be sure to free */ 127285809Sscottl if ( (pSatDevData->satDriveState != SAT_DEV_STATE_IN_RECOVERY) || 128285809Sscottl (RLERecovery == agTRUE) ) 129285809Sscottl { 130285809Sscottl if (RLERecovery == agFALSE) /* RLE is not checked against pending IO's */ 131285809Sscottl { 132285809Sscottl#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 133285809Sscottl bit32 volatile satPendingNCQIO = 0; 134285809Sscottl bit32 volatile satPendingNONNCQIO = 0; 135285809Sscottl bit32 volatile satPendingIO = 0; 136285809Sscottl 137285809Sscottl tdsmInterlockedExchange(smRoot, &satPendingNCQIO, pSatDevData->satPendingNCQIO); 138285809Sscottl tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, pSatDevData->satPendingNONNCQIO); 139285809Sscottl tdsmInterlockedExchange(smRoot, &satPendingIO, pSatDevData->satPendingIO); 140285809Sscottl#endif 141285809Sscottl 142285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 143285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 144285809Sscottl { 145285809Sscottl #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 146285809Sscottl if ( satPendingNCQIO >= pSatDevData->satNCQMaxIO || 147285809Sscottl satPendingNONNCQIO != 0) 148285809Sscottl { 149285809Sscottl SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id)); 150285809Sscottl SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 151285809Sscottl satPendingNONNCQIO, satPendingIO)); 152285809Sscottl /* free resource */ 153285809Sscottl smsatFreeIntIoResource( smRoot, 154285809Sscottl pSatDevData, 155285809Sscottl satIntIo); 156285809Sscottl return SM_RC_DEVICE_BUSY; 157285809Sscottl } 158285809Sscottl #else 159285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 160285809Sscottl if (pSatDevData->satPendingNCQIO >= pSatDevData->satNCQMaxIO || 161285809Sscottl pSatDevData->satPendingNONNCQIO != 0) 162285809Sscottl { 163285809Sscottl SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id)); 164285809Sscottl SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 165285809Sscottl pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 166285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 167285809Sscottl /* free resource */ 168285809Sscottl smsatFreeIntIoResource( smRoot, 169285809Sscottl pSatDevData, 170285809Sscottl satIntIo); 171285809Sscottl return SM_RC_DEVICE_BUSY; 172285809Sscottl } 173285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 174285809Sscottl #endif 175285809Sscottl 176285809Sscottl } 177285809Sscottl else if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_D2H_PKT) || 178285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_H2D_PKT) || 179285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_PKT) ) 180285809Sscottl { 181285809Sscottl sm_memcpy(agSATAReq->scsiCDB, smScsiRequest->scsiCmnd.cdb, 16); 182285809Sscottl #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 183285809Sscottl if ( satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX || 184285809Sscottl satPendingNCQIO != 0) 185285809Sscottl { 186285809Sscottl SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id)); 187285809Sscottl SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 188285809Sscottl satPendingNONNCQIO, satPendingIO)); 189285809Sscottl /* free resource */ 190285809Sscottl smsatFreeIntIoResource( smRoot, 191285809Sscottl pSatDevData, 192285809Sscottl satIntIo); 193285809Sscottl return SM_RC_DEVICE_BUSY; 194285809Sscottl } 195285809Sscottl #else 196285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 197285809Sscottl if ( pSatDevData->satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX || 198285809Sscottl pSatDevData->satPendingNCQIO != 0) 199285809Sscottl { 200285809Sscottl SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id)); 201285809Sscottl SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 202285809Sscottl pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 203285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 204285809Sscottl /* free resource */ 205285809Sscottl smsatFreeIntIoResource( smRoot, 206285809Sscottl pSatDevData, 207285809Sscottl satIntIo); 208285809Sscottl return SM_RC_DEVICE_BUSY; 209285809Sscottl } 210285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 211285809Sscottl #endif 212285809Sscottl 213285809Sscottl } 214285809Sscottl else 215285809Sscottl { 216285809Sscottl#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 217285809Sscottl if ( satPendingNONNCQIO >= SAT_NONNCQ_MAX || 218285809Sscottl satPendingNCQIO != 0) 219285809Sscottl { 220285809Sscottl SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id)); 221285809Sscottl SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO, 222285809Sscottl satPendingNONNCQIO, satPendingIO)); 223285809Sscottl /* free resource */ 224285809Sscottl smsatFreeIntIoResource( smRoot, 225285809Sscottl pSatDevData, 226285809Sscottl satIntIo); 227285809Sscottl return SM_RC_DEVICE_BUSY; 228285809Sscottl } 229285809Sscottl#else 230285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 231285809Sscottl if (pSatDevData->satPendingNONNCQIO >= SAT_NONNCQ_MAX || 232285809Sscottl pSatDevData->satPendingNCQIO != 0) 233285809Sscottl { 234285809Sscottl SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id)); 235285809Sscottl SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO, 236285809Sscottl pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO)); 237285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 238285809Sscottl /* free resource */ 239285809Sscottl smsatFreeIntIoResource( smRoot, 240285809Sscottl pSatDevData, 241285809Sscottl satIntIo); 242285809Sscottl return SM_RC_DEVICE_BUSY; 243285809Sscottl } 244285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 245285809Sscottl#endif 246285809Sscottl } 247285809Sscottl } /* RLE */ 248285809Sscottl /* for internal SATA command only */ 249285809Sscottl if (satIOContext->satOrgIOContext != agNULL) 250285809Sscottl { 251285809Sscottl /* Initialize tiIORequest */ 252285809Sscottl smIORequestBody->smIORequest = smIORequest; 253285809Sscottl if (smIORequest == agNULL) 254285809Sscottl { 255285809Sscottl SM_DBG1(("smsataLLIOStart: 1 check!!!\n")); 256285809Sscottl } 257285809Sscottl } 258285809Sscottl /* Initialize tiDevhandle */ 259285809Sscottl smIORequestBody->smDevHandle = smDeviceHandle; 260285809Sscottl 261285809Sscottl /* Initializes Scatter Gather and ESGL */ 262285809Sscottl status = smsatIOPrepareSGL( smRoot, 263285809Sscottl smIORequestBody, 264285809Sscottl &smScsiRequest->smSgl1, 265285809Sscottl smScsiRequest->sglVirtualAddr ); 266285809Sscottl 267285809Sscottl if (status != SM_RC_SUCCESS) 268285809Sscottl { 269285809Sscottl SM_DBG1(("smsataLLIOStart: can't get SGL!!!\n")); 270285809Sscottl /* free resource */ 271285809Sscottl smsatFreeIntIoResource( smRoot, 272285809Sscottl pSatDevData, 273285809Sscottl satIntIo); 274285809Sscottl return status; 275285809Sscottl } 276285809Sscottl 277285809Sscottl /* Initialize LL Layer agIORequest */ 278285809Sscottl agIORequest->osData = (void *) smIORequestBody; 279285809Sscottl agIORequest->sdkData = agNULL; /* SA takes care of this */ 280285809Sscottl 281285809Sscottl smIORequestBody->ioStarted = agTRUE; 282285809Sscottl smIORequestBody->ioCompleted = agFALSE; 283285809Sscottl 284285809Sscottl /* assign tag value for SATA */ 285285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 286285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 287285809Sscottl { 288285809Sscottl if (agFALSE == smsatTagAlloc(smRoot, pSatDevData, &satIOContext->sataTag)) 289285809Sscottl { 290285809Sscottl SM_DBG1(("smsataLLIOStart: No more NCQ tag!!!\n")); 291285809Sscottl smIORequestBody->ioStarted = agFALSE; 292285809Sscottl smIORequestBody->ioCompleted = agTRUE; 293285809Sscottl return SM_RC_DEVICE_BUSY; 294285809Sscottl } 295285809Sscottl SM_DBG3(("smsataLLIOStart: ncq tag 0x%x\n",satIOContext->sataTag)); 296285809Sscottl } 297285809Sscottl else 298285809Sscottl { 299285809Sscottl satIOContext->sataTag = 0xFF; 300285809Sscottl } 301285809Sscottl } 302285809Sscottl else /* AGSA_SATA_PROTOCOL_SRST_ASSERT or AGSA_SATA_PROTOCOL_SRST_DEASSERT 303285809Sscottl or SAT_CHECK_POWER_MODE as ABORT */ 304285809Sscottl { 305285809Sscottl agsaSgl_t *agSgl; 306285809Sscottl 307285809Sscottl /* for internal SATA command only */ 308285809Sscottl if (satIOContext->satOrgIOContext != agNULL) 309285809Sscottl { 310285809Sscottl /* Initialize tiIORequest */ 311285809Sscottl smIORequestBody->smIORequest = smIORequest; 312285809Sscottl if (smIORequest == agNULL) 313285809Sscottl { 314285809Sscottl SM_DBG1(("smsataLLIOStart: 2 check!!!\n")); 315285809Sscottl } 316285809Sscottl } 317285809Sscottl /* Initialize tiDevhandle */ 318285809Sscottl smIORequestBody->smDevHandle = smDeviceHandle; 319285809Sscottl 320285809Sscottl 321285809Sscottl smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0; 322285809Sscottl /* SGL for SATA request */ 323285809Sscottl agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl); 324285809Sscottl agSgl->len = 0; 325285809Sscottl 326285809Sscottl agSgl->sgUpper = 0; 327285809Sscottl agSgl->sgLower = 0; 328285809Sscottl agSgl->len = 0; 329285809Sscottl SM_CLEAR_ESGL_EXTEND(agSgl->extReserved); 330285809Sscottl 331285809Sscottl /* Initialize LL Layer agIORequest */ 332285809Sscottl agIORequest = &(smIORequestBody->agIORequest); 333285809Sscottl agIORequest->osData = (void *) smIORequestBody; 334285809Sscottl agIORequest->sdkData = agNULL; /* SA takes care of this */ 335285809Sscottl 336285809Sscottl smIORequestBody->ioStarted = agTRUE; 337285809Sscottl smIORequestBody->ioCompleted = agFALSE; 338285809Sscottl 339285809Sscottl /* setting the data length */ 340285809Sscottl agSATAReq->dataLength = 0; 341285809Sscottl 342285809Sscottl } 343285809Sscottl 344285809Sscottl 345285809Sscottl smIORequestBody->reTries = 0; 346285809Sscottl 347285809Sscottl#ifdef TD_INTERNAL_DEBUG 348285809Sscottl smhexdump("smsataLLIOStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 349285809Sscottl smhexdump("smsataLLIOStart LL", (bit8 *)&agSATAReq->fis.fisRegHostToDev, 350285809Sscottl sizeof(agsaFisRegHostToDevice_t)); 351285809Sscottl#endif 352285809Sscottl 353285809Sscottl SM_DBG6(("smsataLLIOStart: agDevHandle %p\n", agDevHandle)); 354285809Sscottl 355285809Sscottl /* to get better IO performance, rotate the OBQ number on main IO path */ 356285809Sscottl if (smScsiRequest == agNULL) 357285809Sscottl { 358285809Sscottl nQNumber = 0; 359285809Sscottl } 360285809Sscottl else 361285809Sscottl { 362285809Sscottl switch (smScsiRequest->scsiCmnd.cdb[0]) 363285809Sscottl { 364285809Sscottl case SCSIOPC_READ_10: 365285809Sscottl case SCSIOPC_WRITE_10: 366285809Sscottl case SCSIOPC_READ_6: 367285809Sscottl case SCSIOPC_WRITE_6: 368285809Sscottl case SCSIOPC_READ_12: 369285809Sscottl case SCSIOPC_WRITE_12: 370285809Sscottl case SCSIOPC_READ_16: 371285809Sscottl case SCSIOPC_WRITE_16: 372285809Sscottl nQNumber = tdsmRotateQnumber(smRoot, smDeviceHandle); 373285809Sscottl break; 374285809Sscottl 375285809Sscottl default: 376285809Sscottl nQNumber = 0; 377285809Sscottl break; 378285809Sscottl } 379285809Sscottl } 380285809Sscottl 381285809Sscottl SM_DBG3(("sataLLIOStart: Lock in\n")); 382285809Sscottl 383285809Sscottl#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 384285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 385285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 386285809Sscottl { 387285809Sscottl tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNCQIO); 388285809Sscottl } 389285809Sscottl else 390285809Sscottl { 391285809Sscottl tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNONNCQIO); 392285809Sscottl } 393285809Sscottl tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingIO); 394285809Sscottl#else 395285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 396285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 397285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 398285809Sscottl { 399285809Sscottl pSatDevData->satPendingNCQIO++; 400285809Sscottl } 401285809Sscottl else 402285809Sscottl { 403285809Sscottl pSatDevData->satPendingNONNCQIO++; 404285809Sscottl } 405285809Sscottl pSatDevData->satPendingIO++; 406285809Sscottl 407285809Sscottl SMLIST_INIT_ELEMENT (&satIOContext->satIoContextLink); 408285809Sscottl SMLIST_ENQUEUE_AT_TAIL (&satIOContext->satIoContextLink, &pSatDevData->satIoLinkList); 409285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 410285809Sscottl#endif 411285809Sscottl /* post SATA command to low level MPI */ 412285809Sscottl status = saSATAStart( agRoot, 413285809Sscottl agIORequest, 414285809Sscottl nQNumber, 415285809Sscottl agDevHandle, 416285809Sscottl satIOContext->reqType, 417285809Sscottl agSATAReq, 418285809Sscottl satIOContext->sataTag, 419285809Sscottl smllSATACompleted 420285809Sscottl ); 421285809Sscottl 422285809Sscottl if (status != AGSA_RC_SUCCESS) 423285809Sscottl { 424285809Sscottl if (status == AGSA_RC_BUSY) 425285809Sscottl { 426285809Sscottl SM_DBG1(("smsataLLIOStart: saSATAStart busy!!!\n")); 427285809Sscottl status = SM_RC_BUSY; 428285809Sscottl } 429285809Sscottl else 430285809Sscottl { 431285809Sscottl SM_DBG1(("smsataLLIOStart: saSATAStart failed!!!\n")); 432285809Sscottl status = SM_RC_FAILURE; 433285809Sscottl } 434285809Sscottl 435285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 436285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 437285809Sscottl { 438285809Sscottl smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag); 439285809Sscottl } 440285809Sscottl 441285809Sscottl#ifdef CCFLAG_OPTIMIZE_SAT_LOCK 442285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 443285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 444285809Sscottl { 445285809Sscottl tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO); 446285809Sscottl } 447285809Sscottl else 448285809Sscottl { 449285809Sscottl tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO); 450285809Sscottl } 451285809Sscottl tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO); 452285809Sscottl#else 453285809Sscottl if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 454285809Sscottl (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) ) 455285809Sscottl { 456285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 457285809Sscottl oneDeviceData->satPendingNCQIO--; 458285809Sscottl oneDeviceData->satPendingIO--; 459285809Sscottl SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink); 460285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 461285809Sscottl } 462285809Sscottl else 463285809Sscottl { 464285809Sscottl tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 465285809Sscottl oneDeviceData->satPendingNONNCQIO--; 466285809Sscottl oneDeviceData->satPendingIO--; 467285809Sscottl SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink); 468285809Sscottl tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 469285809Sscottl } 470285809Sscottl#endif /* CCFLAG_OPTIMIZE_SAT_LOCK */ 471285809Sscottl 472285809Sscottl /* Free the ESGL pages associated with this I/O */ 473285809Sscottl smIORequestBody->ioStarted = agFALSE; 474285809Sscottl smIORequestBody->ioCompleted = agTRUE; 475285809Sscottl return (status); 476285809Sscottl } 477285809Sscottl 478285809Sscottl return SM_RC_SUCCESS; 479285809Sscottl} 480285809Sscottl 481285809Sscottl 482285809SscottlosGLOBAL FORCEINLINE bit32 483285809SscottlsmsatIOPrepareSGL( 484285809Sscottl smRoot_t *smRoot, 485285809Sscottl smIORequestBody_t *smIORequestBody, 486285809Sscottl smSgl_t *smSgl1, 487285809Sscottl void *sglVirtualAddr 488285809Sscottl ) 489285809Sscottl{ 490285809Sscottl agsaSgl_t *agSgl; 491285809Sscottl 492285809Sscottl /* Uppper should be zero-out */ 493285809Sscottl SM_DBG5(("smsatIOPrepareSGL: start\n")); 494285809Sscottl 495285809Sscottl SM_DBG5(("smsatIOPrepareSGL: smSgl1->upper %d smSgl1->lower %d smSgl1->len %d\n", 496285809Sscottl smSgl1->upper, smSgl1->lower, smSgl1->len)); 497285809Sscottl SM_DBG5(("smsatIOPrepareSGL: smSgl1->type %d\n", smSgl1->type)); 498285809Sscottl 499285809Sscottl /* SGL for SATA request */ 500285809Sscottl agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl); 501285809Sscottl agSgl->len = 0; 502285809Sscottl 503285809Sscottl if (smSgl1 == agNULL) 504285809Sscottl { 505285809Sscottl SM_DBG1(("smsatIOPrepareSGL: Error smSgl1 is NULL!!!\n")); 506285809Sscottl return tiError; 507285809Sscottl } 508285809Sscottl 509285809Sscottl if (smIORequestBody->IOType.InitiatorRegIO.expDataLength == 0) 510285809Sscottl { 511285809Sscottl SM_DBG3(("smsatIOPrepareSGL: expDataLength is 0\n")); 512285809Sscottl agSgl->sgUpper = 0; 513285809Sscottl agSgl->sgLower = 0; 514285809Sscottl agSgl->len = 0; 515285809Sscottl SM_CLEAR_ESGL_EXTEND(agSgl->extReserved); 516285809Sscottl return SM_RC_SUCCESS; 517285809Sscottl } 518285809Sscottl 519285809Sscottl agSgl->sgUpper = smSgl1->upper; 520285809Sscottl agSgl->sgLower = smSgl1->lower; 521285809Sscottl agSgl->len = smSgl1->len; 522285809Sscottl agSgl->extReserved = smSgl1->type; 523285809Sscottl 524285809Sscottl return SM_RC_SUCCESS; 525285809Sscottl 526285809Sscottl} 527285809Sscottl 528285809Sscottl 529285809Sscottl 530285809Sscottl 531