The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 

Cache object: 7052376f5c9c8336fccae369bd534a70


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.