xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c (revision 685dc743)
14e1bc9a0SAchim Leubner /*******************************************************************************
24e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
34e1bc9a0SAchim Leubner *
44e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
54e1bc9a0SAchim Leubner *that the following conditions are met:
64e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
74e1bc9a0SAchim Leubner *following disclaimer.
84e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
94e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
104e1bc9a0SAchim Leubner *with the distribution.
114e1bc9a0SAchim Leubner *
124e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
134e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
144e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
154e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
164e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
174e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
184e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
194e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
204e1bc9a0SAchim Leubner 
214e1bc9a0SAchim Leubner ********************************************************************************/
224e1bc9a0SAchim Leubner /*******************************************************************************/
234e1bc9a0SAchim Leubner /** \file
244e1bc9a0SAchim Leubner  *
254e1bc9a0SAchim Leubner  *
264e1bc9a0SAchim Leubner  * This file contains initiator IO related functions in TD layer
274e1bc9a0SAchim Leubner  *
284e1bc9a0SAchim Leubner  */
294e1bc9a0SAchim Leubner #include <sys/cdefs.h>
304e1bc9a0SAchim Leubner #include <dev/pms/config.h>
314e1bc9a0SAchim Leubner 
324e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/osenv.h>
334e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/ostypes.h>
344e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/osdebug.h>
354e1bc9a0SAchim Leubner 
364e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/sa.h>
374e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
384e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
394e1bc9a0SAchim Leubner 
404e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/api/titypes.h>
414e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
424e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/api/tiapi.h>
434e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
444e1bc9a0SAchim Leubner 
454e1bc9a0SAchim Leubner #ifdef FDS_SM
464e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/sm.h>
474e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/smapi.h>
484e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
494e1bc9a0SAchim Leubner #endif
504e1bc9a0SAchim Leubner 
514e1bc9a0SAchim Leubner #ifdef FDS_DM
524e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/discovery/api/dm.h>
534e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/discovery/api/dmapi.h>
544e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
554e1bc9a0SAchim Leubner #endif
564e1bc9a0SAchim Leubner 
574e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
584e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/osstring.h>
594e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
604e1bc9a0SAchim Leubner 
614e1bc9a0SAchim Leubner #ifdef INITIATOR_DRIVER
624e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
634e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
644e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
654e1bc9a0SAchim Leubner #endif
664e1bc9a0SAchim Leubner 
674e1bc9a0SAchim Leubner #ifdef TARGET_DRIVER
684e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
694e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
704e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
714e1bc9a0SAchim Leubner #endif
724e1bc9a0SAchim Leubner 
734e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
744e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
754e1bc9a0SAchim Leubner 
764e1bc9a0SAchim Leubner /*****************************************************************************
774e1bc9a0SAchim Leubner *! \brief  tiINIIOStart
784e1bc9a0SAchim Leubner *
794e1bc9a0SAchim Leubner *   Purpose:  This routine is called to initiate a new SCSI request.
804e1bc9a0SAchim Leubner *
814e1bc9a0SAchim Leubner *  \param   tiRoot:           Pointer to initiator driver/port instance.
824e1bc9a0SAchim Leubner *  \param   tiIORequest:      Pointer to the I/O request context for this I/O.
834e1bc9a0SAchim Leubner *  \param   tiDeviceHandle:   Pointer to device handle for this I/O.
844e1bc9a0SAchim Leubner *  \param   tiScsiRequest:    Pointer to the SCSI-3 I/O request and SGL list.
854e1bc9a0SAchim Leubner *  \param   tiRequestBody:    Pointer to the OS Specific module allocated storage
864e1bc9a0SAchim Leubner *                             to be used by the TD layer for executing this I/O.
874e1bc9a0SAchim Leubner *  \param   interruptContext: The interrupt context within which this function
884e1bc9a0SAchim Leubner *                       is called.
894e1bc9a0SAchim Leubner *  \return:
904e1bc9a0SAchim Leubner *
914e1bc9a0SAchim Leubner *  tiSuccess:     I/O request successfully initiated.
924e1bc9a0SAchim Leubner *  tiBusy:        No resources available, try again later.
934e1bc9a0SAchim Leubner *  tiIONoDevice:  Invalid device handle.
944e1bc9a0SAchim Leubner *  tiError:       Other errors that prevent the I/O request to be started.
954e1bc9a0SAchim Leubner *
964e1bc9a0SAchim Leubner *
974e1bc9a0SAchim Leubner *****************************************************************************/
984e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext)994e1bc9a0SAchim Leubner tiINIIOStart(
1004e1bc9a0SAchim Leubner              tiRoot_t                  *tiRoot,
1014e1bc9a0SAchim Leubner              tiIORequest_t             *tiIORequest,
1024e1bc9a0SAchim Leubner              tiDeviceHandle_t          *tiDeviceHandle,
1034e1bc9a0SAchim Leubner              tiScsiInitiatorRequest_t  *tiScsiRequest,
1044e1bc9a0SAchim Leubner              void                      *tiRequestBody,
1054e1bc9a0SAchim Leubner              bit32                     interruptContext
1064e1bc9a0SAchim Leubner              )
1074e1bc9a0SAchim Leubner {
1084e1bc9a0SAchim Leubner   tdsaRoot_t                *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
1094e1bc9a0SAchim Leubner   tdsaContext_t             *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1104e1bc9a0SAchim Leubner   itdsaIni_t                *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
1114e1bc9a0SAchim Leubner   tdsaDeviceData_t          *oneDeviceData;
1124e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot = agNULL;
1134e1bc9a0SAchim Leubner   agsaIORequest_t           *agIORequest = agNULL;
1144e1bc9a0SAchim Leubner   agsaDevHandle_t           *agDevHandle = agNULL;
1154e1bc9a0SAchim Leubner   bit32                     agRequestType;
1164e1bc9a0SAchim Leubner   agsaSASRequestBody_t      *agSASRequestBody = agNULL;
1174e1bc9a0SAchim Leubner   bit32                     tiStatus = tiError;
1184e1bc9a0SAchim Leubner   bit32                     saStatus = AGSA_RC_FAILURE;
1194e1bc9a0SAchim Leubner 
1204e1bc9a0SAchim Leubner   tdIORequestBody_t         *tdIORequestBody;
1214e1bc9a0SAchim Leubner   agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
1224e1bc9a0SAchim Leubner #ifdef REMOVED
1234e1bc9a0SAchim Leubner   /* only for debugging */
1244e1bc9a0SAchim Leubner   bit32                      i;
1254e1bc9a0SAchim Leubner #endif
1264e1bc9a0SAchim Leubner 
1274e1bc9a0SAchim Leubner #ifdef  SATA_ENABLE
1284e1bc9a0SAchim Leubner #ifndef FDS_SM
1294e1bc9a0SAchim Leubner   satIOContext_t            *satIOContext;
1304e1bc9a0SAchim Leubner #endif
1314e1bc9a0SAchim Leubner #endif
1324e1bc9a0SAchim Leubner #ifdef FDS_SM
1334e1bc9a0SAchim Leubner   smRoot_t                  *smRoot = &(tdsaAllShared->smRoot);
1344e1bc9a0SAchim Leubner   smIORequest_t             *smIORequest;
1354e1bc9a0SAchim Leubner   smDeviceHandle_t          *smDeviceHandle;
1364e1bc9a0SAchim Leubner   smScsiInitiatorRequest_t  *smSCSIRequest;
1374e1bc9a0SAchim Leubner #endif
1384e1bc9a0SAchim Leubner 
1394e1bc9a0SAchim Leubner   TDSA_INP_ENTER(tiRoot);
1404e1bc9a0SAchim Leubner   TI_DBG6(("tiINIIOStart: start\n"));
1414e1bc9a0SAchim Leubner   TI_DBG6(("tiINIIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
1424e1bc9a0SAchim Leubner 
1434e1bc9a0SAchim Leubner   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1444e1bc9a0SAchim Leubner 
1454e1bc9a0SAchim Leubner   TI_DBG6(("tiINIIOStart: onedevicedata %p\n", oneDeviceData));
1464e1bc9a0SAchim Leubner 
1474e1bc9a0SAchim Leubner   if(oneDeviceData == agNULL)
1484e1bc9a0SAchim Leubner   {
1494e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
1504e1bc9a0SAchim Leubner     tiStatus = tiIONoDevice;
1514e1bc9a0SAchim Leubner     goto ext;
1524e1bc9a0SAchim Leubner   }
1534e1bc9a0SAchim Leubner 
1544e1bc9a0SAchim Leubner   /* for hotplug */
1554e1bc9a0SAchim Leubner   if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
1564e1bc9a0SAchim Leubner       oneDeviceData->tdPortContext == agNULL )
1574e1bc9a0SAchim Leubner   {
1584e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
1594e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
1604e1bc9a0SAchim Leubner     oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
1614e1bc9a0SAchim Leubner     // for debugging
1624e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1634e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
1644e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
1654e1bc9a0SAchim Leubner     tiStatus = tiIONoDevice;
1664e1bc9a0SAchim Leubner     goto ext;
1674e1bc9a0SAchim Leubner   }
1684e1bc9a0SAchim Leubner #if 1
1694e1bc9a0SAchim Leubner   if (tiIORequest->osData == agNULL)
1704e1bc9a0SAchim Leubner   {
1714e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStart: tiIORequest->osData is NULL, wrong\n"));
1724e1bc9a0SAchim Leubner   }
1734e1bc9a0SAchim Leubner #endif
1744e1bc9a0SAchim Leubner 
1754e1bc9a0SAchim Leubner   /* starting IO with SAS device */
1764e1bc9a0SAchim Leubner   if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
1774e1bc9a0SAchim Leubner   {
1784e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: calling saSSPStart\n"));
1794e1bc9a0SAchim Leubner 
1804e1bc9a0SAchim Leubner     agRoot = oneDeviceData->agRoot;
1814e1bc9a0SAchim Leubner     agDevHandle = oneDeviceData->agDevHandle;
1824e1bc9a0SAchim Leubner 
1834e1bc9a0SAchim Leubner     /* OS layer has tdlayer data structure pointer in
1844e1bc9a0SAchim Leubner        tdIORequestBody_t    tdIOReqBody;
1854e1bc9a0SAchim Leubner        in ccb_t in agtiapi.h
1864e1bc9a0SAchim Leubner     */
1874e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
1884e1bc9a0SAchim Leubner 
1894e1bc9a0SAchim Leubner     /* initialize */
1904e1bc9a0SAchim Leubner     osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
1914e1bc9a0SAchim Leubner 
1924e1bc9a0SAchim Leubner     /* let's initialize tdIOrequestBody */
1934e1bc9a0SAchim Leubner     /* initialize callback */
1944e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
1954e1bc9a0SAchim Leubner 
1964e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
1974e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
1984e1bc9a0SAchim Leubner 
1994e1bc9a0SAchim Leubner     /* initialize tiIORequest */
2004e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
2014e1bc9a0SAchim Leubner 
2024e1bc9a0SAchim Leubner     /* save context if we need to abort later */
2034e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
2044e1bc9a0SAchim Leubner 
2054e1bc9a0SAchim Leubner     /* initialize expDataLength */
2064e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.expDataLength
2074e1bc9a0SAchim Leubner       = tiScsiRequest->scsiCmnd.expDataLength;
2084e1bc9a0SAchim Leubner 
2094e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
2104e1bc9a0SAchim Leubner       = tiScsiRequest->sglVirtualAddr;
2114e1bc9a0SAchim Leubner 
2124e1bc9a0SAchim Leubner     /* initializes "agsaSgl_t   agSgl" of "agsaDifSSPInitiatorRequest_t" */
2134e1bc9a0SAchim Leubner     tiStatus = itdssIOPrepareSGL(
2144e1bc9a0SAchim Leubner                                  tiRoot,
2154e1bc9a0SAchim Leubner                                  tdIORequestBody,
2164e1bc9a0SAchim Leubner                                  &tiScsiRequest->agSgl1,
2174e1bc9a0SAchim Leubner                                  tiScsiRequest->sglVirtualAddr
2184e1bc9a0SAchim Leubner                                  );
2194e1bc9a0SAchim Leubner 
2204e1bc9a0SAchim Leubner     if (tiStatus != tiSuccess)
2214e1bc9a0SAchim Leubner     {
2224e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStart: can't get SGL\n"));
2234e1bc9a0SAchim Leubner       goto ext;
2244e1bc9a0SAchim Leubner     }
2254e1bc9a0SAchim Leubner 
2264e1bc9a0SAchim Leubner 
2274e1bc9a0SAchim Leubner     /* initialize agIORequest */
2284e1bc9a0SAchim Leubner     agIORequest = &(tdIORequestBody->agIORequest);
2294e1bc9a0SAchim Leubner     agIORequest->osData = (void *) tdIORequestBody;
2304e1bc9a0SAchim Leubner     agIORequest->sdkData = agNULL; /* LL takes care of this */
2314e1bc9a0SAchim Leubner 
2324e1bc9a0SAchim Leubner 
2334e1bc9a0SAchim Leubner     /*
2344e1bc9a0SAchim Leubner       initialize
2354e1bc9a0SAchim Leubner       tdIORequestBody_t tdIORequestBody -> agSASRequestBody
2364e1bc9a0SAchim Leubner     */
2374e1bc9a0SAchim Leubner     agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
2384e1bc9a0SAchim Leubner     agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
2394e1bc9a0SAchim Leubner 
2404e1bc9a0SAchim Leubner     agSSPInitiatorRequest->flag = 0;
2414e1bc9a0SAchim Leubner 
2424e1bc9a0SAchim Leubner     /* copy cdb bytes */
2434e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
2444e1bc9a0SAchim Leubner 
2454e1bc9a0SAchim Leubner     /* copy lun field */
2464e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
2474e1bc9a0SAchim Leubner                 tiScsiRequest->scsiCmnd.lun.lun, 8);
2484e1bc9a0SAchim Leubner 
2494e1bc9a0SAchim Leubner 
2504e1bc9a0SAchim Leubner     /* setting the data length */
2514e1bc9a0SAchim Leubner     agSSPInitiatorRequest->dataLength  = tiScsiRequest->scsiCmnd.expDataLength;
2524e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
2534e1bc9a0SAchim Leubner 
2544e1bc9a0SAchim Leubner     agSSPInitiatorRequest->firstBurstSize = 0;
2554e1bc9a0SAchim Leubner 
2564e1bc9a0SAchim Leubner     /*
2574e1bc9a0SAchim Leubner       process taskattribute
2584e1bc9a0SAchim Leubner     */
2594e1bc9a0SAchim Leubner     if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
2604e1bc9a0SAchim Leubner     {
2614e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
2624e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
2634e1bc9a0SAchim Leubner     }
2644e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
2654e1bc9a0SAchim Leubner     {
2664e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
2674e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
2684e1bc9a0SAchim Leubner     }
2694e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
2704e1bc9a0SAchim Leubner     {
2714e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
2724e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
2734e1bc9a0SAchim Leubner     }
2744e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
2754e1bc9a0SAchim Leubner     {
2764e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
2774e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
2784e1bc9a0SAchim Leubner     }
2794e1bc9a0SAchim Leubner 
2804e1bc9a0SAchim Leubner     if (tiScsiRequest->dataDirection == tiDirectionIn)
2814e1bc9a0SAchim Leubner     {
2824e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_READ;
2834e1bc9a0SAchim Leubner       TI_DBG6(("tiINIIOStart: READ\n"));
2844e1bc9a0SAchim Leubner     }
2854e1bc9a0SAchim Leubner     else if (tiScsiRequest->dataDirection == tiDirectionOut)
2864e1bc9a0SAchim Leubner     {
2874e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_WRITE;
2884e1bc9a0SAchim Leubner       TI_DBG6(("tiINIIOStart: WRITE\n"));
2894e1bc9a0SAchim Leubner     }
2904e1bc9a0SAchim Leubner     else
2914e1bc9a0SAchim Leubner     {
2924e1bc9a0SAchim Leubner       agRequestType = AGSA_REQ_TYPE_UNKNOWN;
2934e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStart: unknown data direction\n"));
2944e1bc9a0SAchim Leubner     }
2954e1bc9a0SAchim Leubner 
2964e1bc9a0SAchim Leubner     tdIORequestBody->agRequestType = agRequestType;
2974e1bc9a0SAchim Leubner 
2984e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2994e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
3004e1bc9a0SAchim Leubner 
3014e1bc9a0SAchim Leubner     /* for debugging */
3024e1bc9a0SAchim Leubner     if (tdIORequestBody->IOCompletionFunc == agNULL)
3034e1bc9a0SAchim Leubner     {
3044e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStart: Error!!!! IOCompletionFunc is NULL\n"));
3054e1bc9a0SAchim Leubner     }
3064e1bc9a0SAchim Leubner     saStatus = saSSPStart(agRoot,
3074e1bc9a0SAchim Leubner                           agIORequest,
3084e1bc9a0SAchim Leubner                           tdsaRotateQnumber(tiRoot, oneDeviceData),
3094e1bc9a0SAchim Leubner                           agDevHandle,
3104e1bc9a0SAchim Leubner                           agRequestType,
3114e1bc9a0SAchim Leubner                           agSASRequestBody,
3124e1bc9a0SAchim Leubner                           agNULL,
3134e1bc9a0SAchim Leubner                           &ossaSSPCompleted);
3144e1bc9a0SAchim Leubner 
3154e1bc9a0SAchim Leubner     tdIORequestBody->ioStarted = agTRUE;
3164e1bc9a0SAchim Leubner     tdIORequestBody->ioCompleted = agFALSE;
3174e1bc9a0SAchim Leubner     tdIORequestBody->reTries = 0;
3184e1bc9a0SAchim Leubner 
3194e1bc9a0SAchim Leubner     if (saStatus == AGSA_RC_SUCCESS)
3204e1bc9a0SAchim Leubner     {
3214e1bc9a0SAchim Leubner       Initiator->NumIOsActive++;
3224e1bc9a0SAchim Leubner       tiStatus = tiSuccess;
3234e1bc9a0SAchim Leubner     }
3244e1bc9a0SAchim Leubner     else
3254e1bc9a0SAchim Leubner     {
3264e1bc9a0SAchim Leubner       tdIORequestBody->ioStarted = agFALSE;
3274e1bc9a0SAchim Leubner       tdIORequestBody->ioCompleted = agTRUE;
3284e1bc9a0SAchim Leubner       if (saStatus == AGSA_RC_BUSY)
3294e1bc9a0SAchim Leubner       {
3304e1bc9a0SAchim Leubner         TI_DBG4(("tiINIIOStart: saSSPStart busy\n"));
3314e1bc9a0SAchim Leubner         tiStatus = tiBusy;
3324e1bc9a0SAchim Leubner       }
3334e1bc9a0SAchim Leubner       else
3344e1bc9a0SAchim Leubner       {
3354e1bc9a0SAchim Leubner         tiStatus = tiError;
3364e1bc9a0SAchim Leubner       }
3374e1bc9a0SAchim Leubner       goto ext;
3384e1bc9a0SAchim Leubner     }
3394e1bc9a0SAchim Leubner   }
3404e1bc9a0SAchim Leubner #ifdef FDS_SM
3414e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
3424e1bc9a0SAchim Leubner   {
3434e1bc9a0SAchim Leubner     TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
3444e1bc9a0SAchim Leubner     TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
3454e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
3464e1bc9a0SAchim Leubner     /* initialize */
3474e1bc9a0SAchim Leubner     osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
3484e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
3494e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
3504e1bc9a0SAchim Leubner     tdIORequestBody->superIOFlag = agFALSE;
3514e1bc9a0SAchim Leubner 
3524e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
3534e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
3544e1bc9a0SAchim Leubner     smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
3554e1bc9a0SAchim Leubner     smIORequest->tdData = tdIORequestBody;
3564e1bc9a0SAchim Leubner 
3574e1bc9a0SAchim Leubner     smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
3584e1bc9a0SAchim Leubner     smDeviceHandle->tdData = oneDeviceData;
3594e1bc9a0SAchim Leubner 
3604e1bc9a0SAchim Leubner     smSCSIRequest = (smScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSCSIRequest);
3614e1bc9a0SAchim Leubner     osti_memcpy(smSCSIRequest, tiScsiRequest, sizeof(smScsiInitiatorRequest_t));
3624e1bc9a0SAchim Leubner 
3634e1bc9a0SAchim Leubner     tiStatus = smIOStart(smRoot,
3644e1bc9a0SAchim Leubner                          smIORequest,
3654e1bc9a0SAchim Leubner                          smDeviceHandle,
3664e1bc9a0SAchim Leubner                          smSCSIRequest,
3674e1bc9a0SAchim Leubner                          interruptContext);
3684e1bc9a0SAchim Leubner     /*
3694e1bc9a0SAchim Leubner osGLOBAL bit32
3704e1bc9a0SAchim Leubner smIOStart(
3714e1bc9a0SAchim Leubner           smRoot_t          *smRoot,
3724e1bc9a0SAchim Leubner           smIORequest_t         *smIORequest,
3734e1bc9a0SAchim Leubner           smDeviceHandle_t      *smDeviceHandle,
3744e1bc9a0SAchim Leubner           smScsiInitiatorRequest_t  *smSCSIRequest,
3754e1bc9a0SAchim Leubner           bit32             interruptContext
3764e1bc9a0SAchim Leubner          )
3774e1bc9a0SAchim Leubner 
3784e1bc9a0SAchim Leubner 
3794e1bc9a0SAchim Leubner     */
3804e1bc9a0SAchim Leubner   }
3814e1bc9a0SAchim Leubner #else
3824e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
3834e1bc9a0SAchim Leubner   {
3844e1bc9a0SAchim Leubner     TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
3854e1bc9a0SAchim Leubner     TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
3864e1bc9a0SAchim Leubner 
3874e1bc9a0SAchim Leubner #ifdef  SATA_ENABLE
3884e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
3894e1bc9a0SAchim Leubner 
3904e1bc9a0SAchim Leubner     /* initialize */
3914e1bc9a0SAchim Leubner     osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
3924e1bc9a0SAchim Leubner 
3934e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
3944e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
3954e1bc9a0SAchim Leubner 
3964e1bc9a0SAchim Leubner     /* initialize tiIORequest */
3974e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
3984e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
3994e1bc9a0SAchim Leubner 
4004e1bc9a0SAchim Leubner     satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
4014e1bc9a0SAchim Leubner 
4024e1bc9a0SAchim Leubner     /*
4034e1bc9a0SAchim Leubner      * Need to initialize all the fields within satIOContext except
4044e1bc9a0SAchim Leubner      * reqType and satCompleteCB which will be set in sat.c depending on cmd.
4054e1bc9a0SAchim Leubner      */
4064e1bc9a0SAchim Leubner     tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
4074e1bc9a0SAchim Leubner     tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
4084e1bc9a0SAchim Leubner     satIOContext->pSatDevData   = &oneDeviceData->satDevData;
4094e1bc9a0SAchim Leubner     satIOContext->pFis          =
4104e1bc9a0SAchim Leubner       &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
4114e1bc9a0SAchim Leubner     satIOContext->pScsiCmnd     = &tiScsiRequest->scsiCmnd;
4124e1bc9a0SAchim Leubner     satIOContext->pSense        = &tdIORequestBody->transport.SATA.sensePayload;
4134e1bc9a0SAchim Leubner     satIOContext->pTiSenseData  = &tdIORequestBody->transport.SATA.tiSenseData;
4144e1bc9a0SAchim Leubner     satIOContext->pTiSenseData->senseData = satIOContext->pSense;
4154e1bc9a0SAchim Leubner     /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */
4164e1bc9a0SAchim Leubner     satIOContext->tiRequestBody = tiRequestBody;
4174e1bc9a0SAchim Leubner     satIOContext->interruptContext = interruptContext;
4184e1bc9a0SAchim Leubner     satIOContext->ptiDeviceHandle = tiDeviceHandle;
4194e1bc9a0SAchim Leubner     satIOContext->tiScsiXchg = tiScsiRequest;
4204e1bc9a0SAchim Leubner     satIOContext->satIntIoContext  = agNULL;
4214e1bc9a0SAchim Leubner     satIOContext->satOrgIOContext  = agNULL;
4224e1bc9a0SAchim Leubner     /*    satIOContext->tiIORequest      = tiIORequest; */
4234e1bc9a0SAchim Leubner 
4244e1bc9a0SAchim Leubner     /* save context if we need to abort later */
4254e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
4264e1bc9a0SAchim Leubner 
4274e1bc9a0SAchim Leubner     /* followings are used only for internal IO */
4284e1bc9a0SAchim Leubner     satIOContext->currentLBA = 0;
4294e1bc9a0SAchim Leubner     satIOContext->OrgTL = 0;
4304e1bc9a0SAchim Leubner 
4314e1bc9a0SAchim Leubner     TI_DBG5(("tiINIIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
4324e1bc9a0SAchim Leubner 
4334e1bc9a0SAchim Leubner     tiStatus = satIOStart( tiRoot,
4344e1bc9a0SAchim Leubner                            tiIORequest,
4354e1bc9a0SAchim Leubner                            tiDeviceHandle,
4364e1bc9a0SAchim Leubner                            tiScsiRequest,
4374e1bc9a0SAchim Leubner                            satIOContext);
4384e1bc9a0SAchim Leubner     goto ext;
4394e1bc9a0SAchim Leubner #endif
4404e1bc9a0SAchim Leubner   }
4414e1bc9a0SAchim Leubner #endif /* else of FDS_SM */
4424e1bc9a0SAchim Leubner   else
4434e1bc9a0SAchim Leubner   {
4444e1bc9a0SAchim Leubner 
4454e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
4464e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
4474e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
4484e1bc9a0SAchim Leubner     /*
4494e1bc9a0SAchim Leubner       error. unsupported IO
4504e1bc9a0SAchim Leubner      */
4514e1bc9a0SAchim Leubner   }
4524e1bc9a0SAchim Leubner ext:
4534e1bc9a0SAchim Leubner   TDSA_INP_LEAVE(tiRoot);
4544e1bc9a0SAchim Leubner   return tiStatus;
4554e1bc9a0SAchim Leubner }
4564e1bc9a0SAchim Leubner 
4574e1bc9a0SAchim Leubner #ifdef FAST_IO_TEST
4584e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIFastIOSend(void * ioh)4594e1bc9a0SAchim Leubner tiINIFastIOSend(void *ioh)
4604e1bc9a0SAchim Leubner {
4614e1bc9a0SAchim Leubner   bit32 saStatus, tiStatus;
4624e1bc9a0SAchim Leubner 
4634e1bc9a0SAchim Leubner   saStatus = saFastSSPSend(ioh);
4644e1bc9a0SAchim Leubner   if (saStatus == AGSA_RC_SUCCESS)
4654e1bc9a0SAchim Leubner     tiStatus = tiSuccess;
4664e1bc9a0SAchim Leubner   else
4674e1bc9a0SAchim Leubner     tiStatus = tiError;
4684e1bc9a0SAchim Leubner   return tiStatus;
4694e1bc9a0SAchim Leubner }
4704e1bc9a0SAchim Leubner 
4714e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIFastIOCancel(void * ioh)4724e1bc9a0SAchim Leubner tiINIFastIOCancel(void *ioh)
4734e1bc9a0SAchim Leubner {
4744e1bc9a0SAchim Leubner   bit32 saStatus, tiStatus;
4754e1bc9a0SAchim Leubner 
4764e1bc9a0SAchim Leubner   saStatus = saFastSSPCancel(ioh);
4774e1bc9a0SAchim Leubner   if (saStatus == AGSA_RC_SUCCESS)
4784e1bc9a0SAchim Leubner     tiStatus = tiSuccess;
4794e1bc9a0SAchim Leubner   else
4804e1bc9a0SAchim Leubner     tiStatus = tiError;
4814e1bc9a0SAchim Leubner   return tiStatus;
4824e1bc9a0SAchim Leubner }
4834e1bc9a0SAchim Leubner 
4844e1bc9a0SAchim Leubner osGLOBAL void*
tiINIFastIOPrepare(tiRoot_t * tiRoot,void * ioHandle,agsaFastCommand_t * fc)4854e1bc9a0SAchim Leubner tiINIFastIOPrepare(
4864e1bc9a0SAchim Leubner             tiRoot_t          *tiRoot,
4874e1bc9a0SAchim Leubner             void              *ioHandle,
4884e1bc9a0SAchim Leubner             agsaFastCommand_t *fc)
4894e1bc9a0SAchim Leubner {
4904e1bc9a0SAchim Leubner   tdsaDeviceData_t *oneDeviceData;
4914e1bc9a0SAchim Leubner   tiDeviceHandle_t *tiDeviceHandle = fc->devHandle;
4924e1bc9a0SAchim Leubner   bit32            taskAttribute = fc->taskAttribute;
4934e1bc9a0SAchim Leubner   void             *ioh = ioHandle;
4944e1bc9a0SAchim Leubner 
4954e1bc9a0SAchim Leubner   TDSA_INP_ENTER(tiRoot);
4964e1bc9a0SAchim Leubner   TI_DBG6(("tiINIFastIOPrepare: enter\n"));
4974e1bc9a0SAchim Leubner 
4984e1bc9a0SAchim Leubner   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
4994e1bc9a0SAchim Leubner   if(oneDeviceData == agNULL)
5004e1bc9a0SAchim Leubner   {
5014e1bc9a0SAchim Leubner     TI_DBG1(("tiINIFastIOPrepare: tiDeviceHandle=%p DeviceData is NULL\n",
5024e1bc9a0SAchim Leubner              tiDeviceHandle));
5034e1bc9a0SAchim Leubner     ioHandle = 0;
5044e1bc9a0SAchim Leubner     TD_ASSERT((0), "");
5054e1bc9a0SAchim Leubner     goto ext;
5064e1bc9a0SAchim Leubner   }
5074e1bc9a0SAchim Leubner   TI_DBG6(("tiINIFastIOPrepare: onedevicedata %p\n", oneDeviceData));
5084e1bc9a0SAchim Leubner 
5094e1bc9a0SAchim Leubner   /* starting IO with SAS device */
5104e1bc9a0SAchim Leubner   if (oneDeviceData->DeviceType != TD_SAS_DEVICE)
5114e1bc9a0SAchim Leubner   {
5124e1bc9a0SAchim Leubner     TI_DBG1(("tiINISuperIOSend: wrong Device %d\n", oneDeviceData->DeviceType));
5134e1bc9a0SAchim Leubner     /* error: unsupported IO */
5144e1bc9a0SAchim Leubner     ioHandle = 0;
5154e1bc9a0SAchim Leubner     TD_ASSERT((0), "");
5164e1bc9a0SAchim Leubner     goto ext;
5174e1bc9a0SAchim Leubner   }
5184e1bc9a0SAchim Leubner 
5194e1bc9a0SAchim Leubner   fc->agRoot = oneDeviceData->agRoot;
5204e1bc9a0SAchim Leubner   TD_ASSERT((NULL != fc->agRoot), "");
5214e1bc9a0SAchim Leubner 
5224e1bc9a0SAchim Leubner   fc->devHandle = oneDeviceData->agDevHandle;
5234e1bc9a0SAchim Leubner   TD_ASSERT((NULL != fc->devHandle), "");
5244e1bc9a0SAchim Leubner   fc->safb->oneDeviceData = oneDeviceData;
5254e1bc9a0SAchim Leubner 
5264e1bc9a0SAchim Leubner   /*
5274e1bc9a0SAchim Leubner     process taskattribute
5284e1bc9a0SAchim Leubner   */
5294e1bc9a0SAchim Leubner   switch (taskAttribute)
5304e1bc9a0SAchim Leubner   {
5314e1bc9a0SAchim Leubner     case TASK_SIMPLE:
5324e1bc9a0SAchim Leubner       fc->taskAttribute = TD_TASK_SIMPLE;
5334e1bc9a0SAchim Leubner       break;
5344e1bc9a0SAchim Leubner     case TASK_ORDERED:
5354e1bc9a0SAchim Leubner       fc->taskAttribute = TD_TASK_ORDERED;
5364e1bc9a0SAchim Leubner       break;
5374e1bc9a0SAchim Leubner     case TASK_HEAD_OF_QUEUE:
5384e1bc9a0SAchim Leubner       fc->taskAttribute = TD_TASK_HEAD_OF_QUEUE;
5394e1bc9a0SAchim Leubner       break;
5404e1bc9a0SAchim Leubner     case TASK_ACA:
5414e1bc9a0SAchim Leubner       fc->taskAttribute = TD_TASK_ACA;
5424e1bc9a0SAchim Leubner       break;
5434e1bc9a0SAchim Leubner       /* compile out for "iniload" */
5444e1bc9a0SAchim Leubner   }
5454e1bc9a0SAchim Leubner 
5464e1bc9a0SAchim Leubner 
5474e1bc9a0SAchim Leubner   TI_DBG3(("tiINIFastIOPrepare: data direction: %x\n", fc->agRequestType));
5484e1bc9a0SAchim Leubner   TI_DBG6(("tiINIFastIOPrepare: device AddrHi/Lo 0x%08x / 0x%08x\n",
5494e1bc9a0SAchim Leubner            oneDeviceData->SASAddressID.sasAddressHi,
5504e1bc9a0SAchim Leubner            oneDeviceData->SASAddressID.sasAddressLo));
5514e1bc9a0SAchim Leubner 
5524e1bc9a0SAchim Leubner   fc->queueNum = tdsaRotateQnumber(tiRoot, oneDeviceData);
5534e1bc9a0SAchim Leubner 
5544e1bc9a0SAchim Leubner   ioHandle = saFastSSPPrepare(ioHandle, fc, ossaFastSSPCompleted, fc->safb);
5554e1bc9a0SAchim Leubner   if (!ioHandle)
5564e1bc9a0SAchim Leubner   {
5574e1bc9a0SAchim Leubner     TI_DBG1(("tiINIFastIOPrepare: saSuperSSPSend error\n"));
5584e1bc9a0SAchim Leubner     TD_ASSERT((0), "");
5594e1bc9a0SAchim Leubner     //goto ext;
5604e1bc9a0SAchim Leubner   }
5614e1bc9a0SAchim Leubner 
5624e1bc9a0SAchim Leubner ext:
5634e1bc9a0SAchim Leubner   if (ioh && !ioHandle)
5644e1bc9a0SAchim Leubner   {
5654e1bc9a0SAchim Leubner     saFastSSPCancel(ioh);
5664e1bc9a0SAchim Leubner   }
5674e1bc9a0SAchim Leubner 
5684e1bc9a0SAchim Leubner   TI_DBG6(("tiINIFastIOPrepare: leave\n"));
5694e1bc9a0SAchim Leubner 
5704e1bc9a0SAchim Leubner   TDSA_INP_LEAVE(tiRoot);
5714e1bc9a0SAchim Leubner   return ioHandle;
5724e1bc9a0SAchim Leubner } /* tiINIFastIOPrepare */
5734e1bc9a0SAchim Leubner #endif
5744e1bc9a0SAchim Leubner 
5754e1bc9a0SAchim Leubner /*****************************************************************************
5764e1bc9a0SAchim Leubner *
5774e1bc9a0SAchim Leubner *   tiINIIOStartDif
5784e1bc9a0SAchim Leubner *
5794e1bc9a0SAchim Leubner *   Purpose:  This routine is called to initiate a new SCSI request with
5804e1bc9a0SAchim Leubner *             DIF enable.
5814e1bc9a0SAchim Leubner *
5824e1bc9a0SAchim Leubner *   Parameters:
5834e1bc9a0SAchim Leubner *     tiRoot:           Pointer to initiator driver/port instance.
5844e1bc9a0SAchim Leubner *     tiIORequest:      Pointer to the I/O request context for this I/O.
5854e1bc9a0SAchim Leubner *     tiDeviceHandle:   Pointer to device handle for this I/O.
5864e1bc9a0SAchim Leubner *     tiScsiRequest:    Pointer to the SCSI-3 I/O request and SGL list.
5874e1bc9a0SAchim Leubner *     tiRequestBody:    Pointer to the OS Specific module allocated storage
5884e1bc9a0SAchim Leubner *                       to be used by the TD layer for executing this I/O.
5894e1bc9a0SAchim Leubner *     interruptContext: The interrupt context within which this function
5904e1bc9a0SAchim Leubner *                       is called.
5914e1bc9a0SAchim Leubner *     difOption:        DIF option.
5924e1bc9a0SAchim Leubner *
5934e1bc9a0SAchim Leubner *  Return:
5944e1bc9a0SAchim Leubner *
5954e1bc9a0SAchim Leubner *  tiSuccess:     I/O request successfully initiated.
5964e1bc9a0SAchim Leubner *  tiBusy:        No resources available, try again later.
5974e1bc9a0SAchim Leubner *  tiIONoDevice:  Invalid device handle.
5984e1bc9a0SAchim Leubner *  tiError:       Other errors that prevent the I/O request to be started.
5994e1bc9a0SAchim Leubner *
6004e1bc9a0SAchim Leubner *
6014e1bc9a0SAchim Leubner *****************************************************************************/
tiINIIOStartDif(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiDif_t * difOption)6024e1bc9a0SAchim Leubner osGLOBAL bit32 tiINIIOStartDif(
6034e1bc9a0SAchim Leubner                         tiRoot_t                    *tiRoot,
6044e1bc9a0SAchim Leubner                         tiIORequest_t               *tiIORequest,
6054e1bc9a0SAchim Leubner                         tiDeviceHandle_t            *tiDeviceHandle,
6064e1bc9a0SAchim Leubner                         tiScsiInitiatorRequest_t   *tiScsiRequest,
6074e1bc9a0SAchim Leubner                         void                      *tiRequestBody,
6084e1bc9a0SAchim Leubner                         bit32                       interruptContext,
6094e1bc9a0SAchim Leubner                         tiDif_t                     *difOption
6104e1bc9a0SAchim Leubner                         )
6114e1bc9a0SAchim Leubner {
6124e1bc9a0SAchim Leubner 
6134e1bc9a0SAchim Leubner   /* This function was never used by SAS/SATA. Use tiINISuperIOStart() instead. */
6144e1bc9a0SAchim Leubner   return tiBusy;
6154e1bc9a0SAchim Leubner }
6164e1bc9a0SAchim Leubner 
6174e1bc9a0SAchim Leubner 
6184e1bc9a0SAchim Leubner /*****************************************************************************
6194e1bc9a0SAchim Leubner *
6204e1bc9a0SAchim Leubner *   tiINISuperIOStart
6214e1bc9a0SAchim Leubner *
6224e1bc9a0SAchim Leubner *   Purpose:  This routine is called to initiate a new SCSI request.
6234e1bc9a0SAchim Leubner *
6244e1bc9a0SAchim Leubner *   Parameters:
6254e1bc9a0SAchim Leubner *     tiRoot:           Pointer to initiator driver/port instance.
6264e1bc9a0SAchim Leubner *     tiIORequest:      Pointer to the I/O request context for this I/O.
6274e1bc9a0SAchim Leubner *     tiDeviceHandle:   Pointer to device handle for this I/O.
6284e1bc9a0SAchim Leubner *     tiScsiRequest:    Pointer to the SCSI-3 I/O request and SGL list.
6294e1bc9a0SAchim Leubner *     tiRequestBody:    Pointer to the OS Specific module allocated storage
6304e1bc9a0SAchim Leubner *                       to be used by the TD layer for executing this I/O.
6314e1bc9a0SAchim Leubner *     interruptContext: The interrupt context within which this function
6324e1bc9a0SAchim Leubner *                       is called.
6334e1bc9a0SAchim Leubner *  Return:
6344e1bc9a0SAchim Leubner *
6354e1bc9a0SAchim Leubner *  tiSuccess:     I/O request successfully initiated.
6364e1bc9a0SAchim Leubner *  tiBusy:        No resources available, try again later.
6374e1bc9a0SAchim Leubner *  tiIONoDevice:  Invalid device handle.
6384e1bc9a0SAchim Leubner *  tiError:       Other errors that prevent the I/O request to be started.
6394e1bc9a0SAchim Leubner *
6404e1bc9a0SAchim Leubner *
6414e1bc9a0SAchim Leubner *****************************************************************************/
6424e1bc9a0SAchim Leubner osGLOBAL bit32
tiINISuperIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiSuperScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext)6434e1bc9a0SAchim Leubner tiINISuperIOStart(
6444e1bc9a0SAchim Leubner              tiRoot_t                       *tiRoot,
6454e1bc9a0SAchim Leubner              tiIORequest_t                  *tiIORequest,
6464e1bc9a0SAchim Leubner              tiDeviceHandle_t               *tiDeviceHandle,
6474e1bc9a0SAchim Leubner              tiSuperScsiInitiatorRequest_t  *tiScsiRequest,
6484e1bc9a0SAchim Leubner              void                           *tiRequestBody,
6494e1bc9a0SAchim Leubner              bit32                          interruptContext
6504e1bc9a0SAchim Leubner              )
6514e1bc9a0SAchim Leubner {
6524e1bc9a0SAchim Leubner   tdsaRoot_t                *tdsaRoot = agNULL;
6534e1bc9a0SAchim Leubner   tdsaContext_t             *tdsaAllShared = agNULL;
6544e1bc9a0SAchim Leubner   itdsaIni_t                *Initiator = agNULL;
6554e1bc9a0SAchim Leubner   tdsaDeviceData_t          *oneDeviceData = agNULL;
6564e1bc9a0SAchim Leubner   tdIORequestBody_t         *tdIORequestBody = agNULL;
6574e1bc9a0SAchim Leubner   agsaSSPInitiatorRequest_t *agSSPInitiatorRequest = agNULL;
6584e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot = agNULL;
6594e1bc9a0SAchim Leubner   agsaIORequest_t           *agIORequest = agNULL;
6604e1bc9a0SAchim Leubner   agsaDevHandle_t           *agDevHandle = agNULL;
6614e1bc9a0SAchim Leubner   agsaSASRequestBody_t      *agSASRequestBody = agNULL;
6624e1bc9a0SAchim Leubner   bit32                     tiStatus = tiError;
6634e1bc9a0SAchim Leubner   bit32                     saStatus = AGSA_RC_FAILURE;
6644e1bc9a0SAchim Leubner   bit32                     adjusted_length = 0;
6654e1bc9a0SAchim Leubner   bit32                     agRequestType   = 0;
6664e1bc9a0SAchim Leubner   agBOOLEAN                 needPlusDataLenAdjustment = agFALSE;
6674e1bc9a0SAchim Leubner   agBOOLEAN                 needMinusDataLenAdjustment = agFALSE;
6684e1bc9a0SAchim Leubner 
6694e1bc9a0SAchim Leubner #ifdef  SATA_ENABLE
6704e1bc9a0SAchim Leubner #ifndef FDS_SM
6714e1bc9a0SAchim Leubner   satIOContext_t            *satIOContext;
6724e1bc9a0SAchim Leubner #endif
6734e1bc9a0SAchim Leubner #endif
6744e1bc9a0SAchim Leubner #ifdef FDS_SM
6754e1bc9a0SAchim Leubner   smRoot_t                  *smRoot;
6764e1bc9a0SAchim Leubner   smIORequest_t             *smIORequest;
6774e1bc9a0SAchim Leubner   smDeviceHandle_t          *smDeviceHandle;
6784e1bc9a0SAchim Leubner   smSuperScsiInitiatorRequest_t  *smSuperSCSIRequest;
6794e1bc9a0SAchim Leubner #endif
6804e1bc9a0SAchim Leubner #ifdef CCBUILD_INDIRECT_CDB
6814e1bc9a0SAchim Leubner   agsaSSPInitiatorRequestIndirect_t *agSSPInitiatorIndRequest = agNULL;
6824e1bc9a0SAchim Leubner #endif
6834e1bc9a0SAchim Leubner   TD_ASSERT(tiRoot , "tiRoot");
6844e1bc9a0SAchim Leubner   TD_ASSERT(tiIORequest, "tiIORequest");
6854e1bc9a0SAchim Leubner   TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
6864e1bc9a0SAchim Leubner   TD_ASSERT(tiRequestBody, "tiRequestBody");
6874e1bc9a0SAchim Leubner   TD_ASSERT(tiRoot->tdData, "tiRoot->tdData");
6884e1bc9a0SAchim Leubner   TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
6894e1bc9a0SAchim Leubner 
6904e1bc9a0SAchim Leubner   tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
6914e1bc9a0SAchim Leubner   TD_ASSERT(tdsaRoot, "tdsaRoot");
6924e1bc9a0SAchim Leubner 
6934e1bc9a0SAchim Leubner   tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
6944e1bc9a0SAchim Leubner   TD_ASSERT(tdsaAllShared, "tdsaAllShared");
6954e1bc9a0SAchim Leubner 
6964e1bc9a0SAchim Leubner   Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
6974e1bc9a0SAchim Leubner   TD_ASSERT(Initiator, "Initiator");
6984e1bc9a0SAchim Leubner 
6994e1bc9a0SAchim Leubner   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
7004e1bc9a0SAchim Leubner   TD_ASSERT(oneDeviceData, "oneDeviceData");
7014e1bc9a0SAchim Leubner 
7024e1bc9a0SAchim Leubner 
7034e1bc9a0SAchim Leubner #ifdef FDS_SM
7044e1bc9a0SAchim Leubner   smRoot = &(tdsaAllShared->smRoot);
7054e1bc9a0SAchim Leubner   TD_ASSERT(smRoot , "smRoot");
7064e1bc9a0SAchim Leubner #endif
7074e1bc9a0SAchim Leubner 
7084e1bc9a0SAchim Leubner 
7094e1bc9a0SAchim Leubner   TI_DBG6(("tiINISuperIOStart: start\n"));
7104e1bc9a0SAchim Leubner   TI_DBG6(("tiINISuperIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
7114e1bc9a0SAchim Leubner 
7124e1bc9a0SAchim Leubner   TI_DBG6(("tiINISuperIOStart: onedevicedata %p\n", oneDeviceData));
7134e1bc9a0SAchim Leubner 
7144e1bc9a0SAchim Leubner   if (oneDeviceData == agNULL)
7154e1bc9a0SAchim Leubner   {
7164e1bc9a0SAchim Leubner     TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
7174e1bc9a0SAchim Leubner     return tiIONoDevice;
7184e1bc9a0SAchim Leubner   }
7194e1bc9a0SAchim Leubner 
7204e1bc9a0SAchim Leubner   /* for hotplug */
7214e1bc9a0SAchim Leubner   if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
7224e1bc9a0SAchim Leubner       oneDeviceData->tdPortContext == agNULL )
7234e1bc9a0SAchim Leubner   {
7244e1bc9a0SAchim Leubner     TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
7254e1bc9a0SAchim Leubner     TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
7264e1bc9a0SAchim Leubner     oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
7274e1bc9a0SAchim Leubner     // for debugging
7284e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
7294e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
7304e1bc9a0SAchim Leubner     TI_DBG6(("tiINISuperIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
7314e1bc9a0SAchim Leubner     return tiIONoDevice;
7324e1bc9a0SAchim Leubner   }
7334e1bc9a0SAchim Leubner 
7344e1bc9a0SAchim Leubner #ifdef DBG
7354e1bc9a0SAchim Leubner   if (tiIORequest->osData == agNULL)
7364e1bc9a0SAchim Leubner   {
7374e1bc9a0SAchim Leubner     TI_DBG1(("tiINISuperIOStart: tiIORequest->osData is NULL, wrong\n"));
7384e1bc9a0SAchim Leubner     return tiError;
7394e1bc9a0SAchim Leubner   }
7404e1bc9a0SAchim Leubner #endif
7414e1bc9a0SAchim Leubner   /* starting IO with SAS device */
7424e1bc9a0SAchim Leubner   if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
7434e1bc9a0SAchim Leubner   {
7444e1bc9a0SAchim Leubner     TI_DBG3(("tiINISuperIOStart: calling saSSPStart\n"));
7454e1bc9a0SAchim Leubner 
7464e1bc9a0SAchim Leubner     agRoot = oneDeviceData->agRoot;
7474e1bc9a0SAchim Leubner     agDevHandle = oneDeviceData->agDevHandle;
7484e1bc9a0SAchim Leubner 
7494e1bc9a0SAchim Leubner     /* OS layer has tdlayer data structure pointer in tdIORequestBody_t  tdIOReqBody; in ccb_t in agtiapi.h */
7504e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
7514e1bc9a0SAchim Leubner 
7524e1bc9a0SAchim Leubner     /* initialize */
7534e1bc9a0SAchim Leubner     /*the tdIORequestBody has been initialized in HwBuildIo routine */
7544e1bc9a0SAchim Leubner     /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/
7554e1bc9a0SAchim Leubner 
7564e1bc9a0SAchim Leubner     /* let's initialize tdIOrequestBody */
7574e1bc9a0SAchim Leubner     /* initialize callback */
7584e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
7594e1bc9a0SAchim Leubner 
7604e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
7614e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
7624e1bc9a0SAchim Leubner 
7634e1bc9a0SAchim Leubner     /* initialize tiIORequest */
7644e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
7654e1bc9a0SAchim Leubner 
7664e1bc9a0SAchim Leubner     /* save context if we need to abort later */
7674e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
7684e1bc9a0SAchim Leubner 
7694e1bc9a0SAchim Leubner     /* initialize expDataLength */
7704e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.expDataLength
7714e1bc9a0SAchim Leubner       = tiScsiRequest->scsiCmnd.expDataLength;
7724e1bc9a0SAchim Leubner 
7734e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
7744e1bc9a0SAchim Leubner       = tiScsiRequest->sglVirtualAddr;
7754e1bc9a0SAchim Leubner 
7764e1bc9a0SAchim Leubner     /* initialize agIORequest */
7774e1bc9a0SAchim Leubner     agIORequest = &(tdIORequestBody->agIORequest);
7784e1bc9a0SAchim Leubner     agIORequest->osData = (void *) tdIORequestBody;
7794e1bc9a0SAchim Leubner 
7804e1bc9a0SAchim Leubner     /* initialize tdIORequestBody_t tdIORequestBody -> agSASRequestBody */
7814e1bc9a0SAchim Leubner     agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
7824e1bc9a0SAchim Leubner     agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
7834e1bc9a0SAchim Leubner 
7844e1bc9a0SAchim Leubner     agSSPInitiatorRequest->flag = 0;
7854e1bc9a0SAchim Leubner     if (tiScsiRequest->flags & TI_SCSI_INITIATOR_ENCRYPT)
7864e1bc9a0SAchim Leubner     {
7874e1bc9a0SAchim Leubner       TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_ENCRYPT\n"));
7884e1bc9a0SAchim Leubner 
7894e1bc9a0SAchim Leubner       /*  Copy all of the relevant encrypt information */
7904e1bc9a0SAchim Leubner       agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_ENCRYPTION;
7914e1bc9a0SAchim Leubner       TD_ASSERT( sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t) , "sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t)");
7924e1bc9a0SAchim Leubner       osti_memcpy(&agSSPInitiatorRequest->encrypt, &tiScsiRequest->Encrypt, sizeof(agsaEncrypt_t));
7934e1bc9a0SAchim Leubner     }
7944e1bc9a0SAchim Leubner 
7954e1bc9a0SAchim Leubner     if ((tiScsiRequest->flags & TI_SCSI_INITIATOR_DIF) &&
7964e1bc9a0SAchim Leubner          (tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_10 ||
7974e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_10 ||
7984e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_6 ||
7994e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_6 ||
8004e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_12 ||
8014e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_12 ||
8024e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_16 ||
8034e1bc9a0SAchim Leubner           tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_16 ))
8044e1bc9a0SAchim Leubner     {
8054e1bc9a0SAchim Leubner       TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_DIF\n"));
8064e1bc9a0SAchim Leubner       /* Copy all of the relevant DIF information */
8074e1bc9a0SAchim Leubner       agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_DIF;
8084e1bc9a0SAchim Leubner       osti_memcpy(&agSSPInitiatorRequest->dif, &tiScsiRequest->Dif, sizeof(agsaDif_t));
8094e1bc9a0SAchim Leubner 
8104e1bc9a0SAchim Leubner       /* Check if need to adjust dataLength. */
8114e1bc9a0SAchim Leubner       switch (tiScsiRequest->dataDirection)
8124e1bc9a0SAchim Leubner       {
8134e1bc9a0SAchim Leubner       case tiDirectionOut: /* Write/Outbound */
8144e1bc9a0SAchim Leubner           break;
8154e1bc9a0SAchim Leubner 
8164e1bc9a0SAchim Leubner       case tiDirectionIn:  /* Read/Inbound */
8174e1bc9a0SAchim Leubner           if ((agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK) == DIF_INSERT)
8184e1bc9a0SAchim Leubner           {
8194e1bc9a0SAchim Leubner               needPlusDataLenAdjustment = agTRUE;
8204e1bc9a0SAchim Leubner           }
8214e1bc9a0SAchim Leubner           break;
8224e1bc9a0SAchim Leubner       }
8234e1bc9a0SAchim Leubner 
8244e1bc9a0SAchim Leubner       /* Set SGL data len XXX This code needs to support more sector sizes */
8254e1bc9a0SAchim Leubner       /* Length adjustment for PCIe DMA only not SAS */
8264e1bc9a0SAchim Leubner       if (needPlusDataLenAdjustment == agTRUE)
8274e1bc9a0SAchim Leubner       {
8284e1bc9a0SAchim Leubner         adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
8294e1bc9a0SAchim Leubner         adjusted_length += (adjusted_length/512) * 8;
8304e1bc9a0SAchim Leubner         agSSPInitiatorRequest->dataLength = adjusted_length;
8314e1bc9a0SAchim Leubner       }
8324e1bc9a0SAchim Leubner       else if (needMinusDataLenAdjustment == agTRUE)
8334e1bc9a0SAchim Leubner       {
8344e1bc9a0SAchim Leubner         adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
8354e1bc9a0SAchim Leubner         adjusted_length -= (adjusted_length/520) * 8;
8364e1bc9a0SAchim Leubner         agSSPInitiatorRequest->dataLength = adjusted_length;
8374e1bc9a0SAchim Leubner       }
8384e1bc9a0SAchim Leubner       else
8394e1bc9a0SAchim Leubner       {
8404e1bc9a0SAchim Leubner         /* setting the data length */
8414e1bc9a0SAchim Leubner         agSSPInitiatorRequest->dataLength  = tiScsiRequest->scsiCmnd.expDataLength;
8424e1bc9a0SAchim Leubner       }
8434e1bc9a0SAchim Leubner 
8444e1bc9a0SAchim Leubner       /* initializes "agsaSgl_t   agSgl" of "agsaDifSSPInitiatorRequest_t" */
8454e1bc9a0SAchim Leubner       tiStatus = itdssIOPrepareSGL(
8464e1bc9a0SAchim Leubner                                    tiRoot,
8474e1bc9a0SAchim Leubner                                    tdIORequestBody,
8484e1bc9a0SAchim Leubner                                    &tiScsiRequest->agSgl1,
8494e1bc9a0SAchim Leubner                                    tiScsiRequest->sglVirtualAddr
8504e1bc9a0SAchim Leubner                                    );
8514e1bc9a0SAchim Leubner       TI_DBG2(("tiINISuperIOStart:TI_SCSI_INITIATOR_DIF needMinusDataLenAdjustment %d needPlusDataLenAdjustment %d difAction %X\n",
8524e1bc9a0SAchim Leubner                    needMinusDataLenAdjustment,
8534e1bc9a0SAchim Leubner                    needPlusDataLenAdjustment,
8544e1bc9a0SAchim Leubner                    agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK));
8554e1bc9a0SAchim Leubner 
8564e1bc9a0SAchim Leubner     }
8574e1bc9a0SAchim Leubner     else
8584e1bc9a0SAchim Leubner     {
8594e1bc9a0SAchim Leubner       /* setting the data length */
8604e1bc9a0SAchim Leubner       agSSPInitiatorRequest->dataLength  = tiScsiRequest->scsiCmnd.expDataLength;
8614e1bc9a0SAchim Leubner 
8624e1bc9a0SAchim Leubner       /* initializes "agsaSgl_t   agSgl" of "agsaSSPInitiatorRequest_t" */
8634e1bc9a0SAchim Leubner       tiStatus = itdssIOPrepareSGL(
8644e1bc9a0SAchim Leubner                                    tiRoot,
8654e1bc9a0SAchim Leubner                                    tdIORequestBody,
8664e1bc9a0SAchim Leubner                                    &tiScsiRequest->agSgl1,
8674e1bc9a0SAchim Leubner                                    tiScsiRequest->sglVirtualAddr
8684e1bc9a0SAchim Leubner                                    );
8694e1bc9a0SAchim Leubner     }
8704e1bc9a0SAchim Leubner 
8714e1bc9a0SAchim Leubner     if (tiStatus != tiSuccess)
8724e1bc9a0SAchim Leubner     {
8734e1bc9a0SAchim Leubner       TI_DBG1(("tiINISuperIOStart: can't get SGL\n"));
8744e1bc9a0SAchim Leubner       return tiStatus;
8754e1bc9a0SAchim Leubner     }
8764e1bc9a0SAchim Leubner 
8774e1bc9a0SAchim Leubner     TI_DBG6(("tiINISuperIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
8784e1bc9a0SAchim Leubner 
8794e1bc9a0SAchim Leubner     /* process taskattribute */
8804e1bc9a0SAchim Leubner     if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
8814e1bc9a0SAchim Leubner     {
8824e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
8834e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
8844e1bc9a0SAchim Leubner     }
8854e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
8864e1bc9a0SAchim Leubner     {
8874e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
8884e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
8894e1bc9a0SAchim Leubner     }
8904e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
8914e1bc9a0SAchim Leubner     {
8924e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
8934e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
8944e1bc9a0SAchim Leubner     }
8954e1bc9a0SAchim Leubner     else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
8964e1bc9a0SAchim Leubner     {
8974e1bc9a0SAchim Leubner       agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
8984e1bc9a0SAchim Leubner        agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
8994e1bc9a0SAchim Leubner     }
9004e1bc9a0SAchim Leubner 
9014e1bc9a0SAchim Leubner     /* copy cdb bytes */
9024e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
9034e1bc9a0SAchim Leubner     /* copy lun field */
9044e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, tiScsiRequest->scsiCmnd.lun.lun, 8);
9054e1bc9a0SAchim Leubner #ifdef CCBUILD_INDIRECT_CDB
9064e1bc9a0SAchim Leubner     /* check the Indirect CDB flag */
9074e1bc9a0SAchim Leubner     if (tiScsiRequest->flags & TI_SCSI_INITIATOR_INDIRECT_CDB)
9084e1bc9a0SAchim Leubner     {
9094e1bc9a0SAchim Leubner       /* Indirect CDB */
9104e1bc9a0SAchim Leubner       if (tiScsiRequest->dataDirection == tiDirectionIn)
9114e1bc9a0SAchim Leubner       {
9124e1bc9a0SAchim Leubner         agRequestType = AGSA_SSP_INIT_READ_INDIRECT;
9134e1bc9a0SAchim Leubner         TI_DBG6(("tiINISuperIOStart: Indirect READ\n"));
9144e1bc9a0SAchim Leubner       }
9154e1bc9a0SAchim Leubner       else if (tiScsiRequest->dataDirection == tiDirectionOut)
9164e1bc9a0SAchim Leubner       {
9174e1bc9a0SAchim Leubner         agRequestType = AGSA_SSP_INIT_WRITE_INDIRECT;
9184e1bc9a0SAchim Leubner         TI_DBG6(("tiINISuperIOStart: Indirect WRITE\n"));
9194e1bc9a0SAchim Leubner       }
9204e1bc9a0SAchim Leubner       else
9214e1bc9a0SAchim Leubner       {
9224e1bc9a0SAchim Leubner         agRequestType = AGSA_REQ_TYPE_UNKNOWN;
9234e1bc9a0SAchim Leubner         TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
9244e1bc9a0SAchim Leubner       }
9254e1bc9a0SAchim Leubner       agSSPInitiatorIndRequest = &(agSASRequestBody->sspInitiatorReqIndirect);
9264e1bc9a0SAchim Leubner       /* copy the constructed SSPIU info to indirect SSPIU buffer */
9274e1bc9a0SAchim Leubner       osti_memcpy(tiScsiRequest->IndCDBBuffer, &agSSPInitiatorRequest->sspCmdIU, sizeof(agsaSSPCmdInfoUnit_t));
9284e1bc9a0SAchim Leubner       /* initialize the indirect CDB buffer address and length */
9294e1bc9a0SAchim Leubner       agSSPInitiatorIndRequest->sspInitiatorReqAddrLower32 = tiScsiRequest->IndCDBLowAddr;
9304e1bc9a0SAchim Leubner       agSSPInitiatorIndRequest->sspInitiatorReqAddrUpper32 = tiScsiRequest->IndCDBHighAddr;
9314e1bc9a0SAchim Leubner       agSSPInitiatorIndRequest->sspInitiatorReqLen         = sizeof(agsaSSPCmdInfoUnit_t);
9324e1bc9a0SAchim Leubner     }
9334e1bc9a0SAchim Leubner     else
9344e1bc9a0SAchim Leubner #endif //CCBUILD_INDIRECT_CDB
9354e1bc9a0SAchim Leubner     {
9364e1bc9a0SAchim Leubner       /* Direct CDB */
9374e1bc9a0SAchim Leubner       if (tiScsiRequest->dataDirection == tiDirectionIn)
9384e1bc9a0SAchim Leubner       {
9394e1bc9a0SAchim Leubner         agRequestType = AGSA_SSP_INIT_READ;
9404e1bc9a0SAchim Leubner         TI_DBG6(("tiINISuperIOStart: READ\n"));
9414e1bc9a0SAchim Leubner       }
9424e1bc9a0SAchim Leubner       else if (tiScsiRequest->dataDirection == tiDirectionOut)
9434e1bc9a0SAchim Leubner       {
9444e1bc9a0SAchim Leubner         agRequestType = AGSA_SSP_INIT_WRITE;
9454e1bc9a0SAchim Leubner         TI_DBG6(("tiINISuperIOStart: WRITE\n"));
9464e1bc9a0SAchim Leubner       }
9474e1bc9a0SAchim Leubner       else
9484e1bc9a0SAchim Leubner       {
9494e1bc9a0SAchim Leubner         agRequestType = AGSA_REQ_TYPE_UNKNOWN;
9504e1bc9a0SAchim Leubner         TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
9514e1bc9a0SAchim Leubner       }
9524e1bc9a0SAchim Leubner     }
9534e1bc9a0SAchim Leubner 
9544e1bc9a0SAchim Leubner     tdIORequestBody->agRequestType = agRequestType;
9554e1bc9a0SAchim Leubner 
9564e1bc9a0SAchim Leubner     TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
9574e1bc9a0SAchim Leubner     TI_DBG6(("tiINISuperIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
9584e1bc9a0SAchim Leubner 
9594e1bc9a0SAchim Leubner #ifdef DBG
9604e1bc9a0SAchim Leubner     /* for debugging */
9614e1bc9a0SAchim Leubner     if (tdIORequestBody->IOCompletionFunc == agNULL)
9624e1bc9a0SAchim Leubner     {
9634e1bc9a0SAchim Leubner       TI_DBG1(("tiINISuperIOStart: Error!!!! IOCompletionFunc is NULL\n"));
9644e1bc9a0SAchim Leubner       return tiError;
9654e1bc9a0SAchim Leubner     }
9664e1bc9a0SAchim Leubner #endif
9674e1bc9a0SAchim Leubner     saStatus = saSSPStart(agRoot,
9684e1bc9a0SAchim Leubner                           agIORequest,
9694e1bc9a0SAchim Leubner                           tdsaRotateQnumber(tiRoot, oneDeviceData),
9704e1bc9a0SAchim Leubner                           agDevHandle,
9714e1bc9a0SAchim Leubner                           agRequestType,
9724e1bc9a0SAchim Leubner                           agSASRequestBody,
9734e1bc9a0SAchim Leubner                           agNULL,
9744e1bc9a0SAchim Leubner                           &ossaSSPCompleted);
9754e1bc9a0SAchim Leubner 
9764e1bc9a0SAchim Leubner     if (saStatus == AGSA_RC_SUCCESS)
9774e1bc9a0SAchim Leubner     {
9784e1bc9a0SAchim Leubner       Initiator->NumIOsActive++;
9794e1bc9a0SAchim Leubner       tdIORequestBody->ioStarted = agTRUE;
9804e1bc9a0SAchim Leubner       tdIORequestBody->ioCompleted = agFALSE;
9814e1bc9a0SAchim Leubner       tiStatus = tiSuccess;
9824e1bc9a0SAchim Leubner     }
9834e1bc9a0SAchim Leubner     else
9844e1bc9a0SAchim Leubner     {
9854e1bc9a0SAchim Leubner       tdIORequestBody->ioStarted = agFALSE;
9864e1bc9a0SAchim Leubner       tdIORequestBody->ioCompleted = agTRUE;
9874e1bc9a0SAchim Leubner       if (saStatus == AGSA_RC_BUSY)
9884e1bc9a0SAchim Leubner       {
9894e1bc9a0SAchim Leubner         TI_DBG4(("tiINISuperIOStart: saSSPStart busy\n"));
9904e1bc9a0SAchim Leubner         tiStatus = tiBusy;
9914e1bc9a0SAchim Leubner       }
9924e1bc9a0SAchim Leubner       else
9934e1bc9a0SAchim Leubner       {
9944e1bc9a0SAchim Leubner         tiStatus = tiError;
9954e1bc9a0SAchim Leubner       }
9964e1bc9a0SAchim Leubner       return tiStatus;
9974e1bc9a0SAchim Leubner     }
9984e1bc9a0SAchim Leubner   }
9994e1bc9a0SAchim Leubner #ifdef FDS_SM
10004e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
10014e1bc9a0SAchim Leubner   {
10024e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
10034e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
10044e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: SATA sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
10054e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: SATA sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
10064e1bc9a0SAchim Leubner 
10074e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
10084e1bc9a0SAchim Leubner     /* initialize */
10094e1bc9a0SAchim Leubner     /* the tdIORequestBody has been initialized by Storport in SRB Extension */
10104e1bc9a0SAchim Leubner     /*osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));*/
10114e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
10124e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
10134e1bc9a0SAchim Leubner     tdIORequestBody->superIOFlag = agTRUE;
10144e1bc9a0SAchim Leubner 
10154e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
10164e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
10174e1bc9a0SAchim Leubner     smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
10184e1bc9a0SAchim Leubner     smIORequest->tdData = tdIORequestBody;
10194e1bc9a0SAchim Leubner     smIORequest->smData = &tdIORequestBody->smIORequestBody;
10204e1bc9a0SAchim Leubner 
10214e1bc9a0SAchim Leubner     smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
10224e1bc9a0SAchim Leubner     smDeviceHandle->tdData = oneDeviceData;
10234e1bc9a0SAchim Leubner 
10244e1bc9a0SAchim Leubner     smSuperSCSIRequest = (smSuperScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSuperSCSIRequest);
10254e1bc9a0SAchim Leubner     osti_memcpy(smSuperSCSIRequest, tiScsiRequest, sizeof(smSuperScsiInitiatorRequest_t));
10264e1bc9a0SAchim Leubner 
10274e1bc9a0SAchim Leubner     tiStatus = smSuperIOStart(smRoot,
10284e1bc9a0SAchim Leubner                               smIORequest,
10294e1bc9a0SAchim Leubner                               smDeviceHandle,
10304e1bc9a0SAchim Leubner                               smSuperSCSIRequest,
10314e1bc9a0SAchim Leubner                               oneDeviceData->SASAddressID.sasAddressHi,
10324e1bc9a0SAchim Leubner                               oneDeviceData->SASAddressID.sasAddressLo,
10334e1bc9a0SAchim Leubner                               interruptContext);
10344e1bc9a0SAchim Leubner 
10354e1bc9a0SAchim Leubner   }
10364e1bc9a0SAchim Leubner #else
10374e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
10384e1bc9a0SAchim Leubner   {
10394e1bc9a0SAchim Leubner 
10404e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
10414e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
10424e1bc9a0SAchim Leubner 
10434e1bc9a0SAchim Leubner #ifdef  SATA_ENABLE
10444e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
10454e1bc9a0SAchim Leubner 
10464e1bc9a0SAchim Leubner     /* initialize */
10474e1bc9a0SAchim Leubner     osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
10484e1bc9a0SAchim Leubner 
10494e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
10504e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
10514e1bc9a0SAchim Leubner 
10524e1bc9a0SAchim Leubner     /* initialize tiIORequest */
10534e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
10544e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
10554e1bc9a0SAchim Leubner 
10564e1bc9a0SAchim Leubner     satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
10574e1bc9a0SAchim Leubner 
10584e1bc9a0SAchim Leubner     /*
10594e1bc9a0SAchim Leubner      * Need to initialize all the fields within satIOContext except
10604e1bc9a0SAchim Leubner      * reqType and satCompleteCB which will be set in sat.c depending on cmd.
10614e1bc9a0SAchim Leubner      */
10624e1bc9a0SAchim Leubner     tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
10634e1bc9a0SAchim Leubner     tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
10644e1bc9a0SAchim Leubner     satIOContext->pSatDevData   = &oneDeviceData->satDevData;
10654e1bc9a0SAchim Leubner     satIOContext->pFis          =
10664e1bc9a0SAchim Leubner       &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
10674e1bc9a0SAchim Leubner     satIOContext->pScsiCmnd     = &tiScsiRequest->scsiCmnd;
10684e1bc9a0SAchim Leubner     satIOContext->pSense        = &tdIORequestBody->transport.SATA.sensePayload;
10694e1bc9a0SAchim Leubner     satIOContext->pTiSenseData  = &tdIORequestBody->transport.SATA.tiSenseData;
10704e1bc9a0SAchim Leubner     satIOContext->pTiSenseData->senseData = satIOContext->pSense;
10714e1bc9a0SAchim Leubner     /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pTiSenseData->senseData; */
10724e1bc9a0SAchim Leubner     satIOContext->tiRequestBody = tiRequestBody;
10734e1bc9a0SAchim Leubner     satIOContext->interruptContext = interruptContext;
10744e1bc9a0SAchim Leubner     satIOContext->ptiDeviceHandle = tiDeviceHandle;
10754e1bc9a0SAchim Leubner     /*
10764e1bc9a0SAchim Leubner      This code uses a kludge for the tiScsiXchg. Many subroutines in the SATA code
10774e1bc9a0SAchim Leubner      require a tiScsiInitiatorRequest. Since it would be a lot of work to replicate
10784e1bc9a0SAchim Leubner      those functions for a tiSuperScsiInitiatorRequest, we will use a short cut.
10794e1bc9a0SAchim Leubner      The standard pointer will be passed, but the superIOFlag marks the real type of the structure.
10804e1bc9a0SAchim Leubner     */
10814e1bc9a0SAchim Leubner     satIOContext->tiScsiXchg = tiScsiRequest;
10824e1bc9a0SAchim Leubner     satIOContext->superIOFlag = agTRUE;
10834e1bc9a0SAchim Leubner 
10844e1bc9a0SAchim Leubner     satIOContext->satIntIoContext  = agNULL;
10854e1bc9a0SAchim Leubner     satIOContext->satOrgIOContext  = agNULL;
10864e1bc9a0SAchim Leubner     /*    satIOContext->tiIORequest      = tiIORequest; */
10874e1bc9a0SAchim Leubner 
10884e1bc9a0SAchim Leubner     /* save context if we need to abort later */
10894e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
10904e1bc9a0SAchim Leubner 
10914e1bc9a0SAchim Leubner     /* followings are used only for internal IO */
10924e1bc9a0SAchim Leubner     satIOContext->currentLBA = 0;
10934e1bc9a0SAchim Leubner     satIOContext->OrgTL = 0;
10944e1bc9a0SAchim Leubner 
10954e1bc9a0SAchim Leubner     TI_DBG5(("tiINISuperIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
10964e1bc9a0SAchim Leubner 
10974e1bc9a0SAchim Leubner     tiStatus = satIOStart( tiRoot,
10984e1bc9a0SAchim Leubner                            tiIORequest,
10994e1bc9a0SAchim Leubner                            tiDeviceHandle,
11004e1bc9a0SAchim Leubner                            satIOContext->tiScsiXchg,
11014e1bc9a0SAchim Leubner                            satIOContext);
11024e1bc9a0SAchim Leubner 
11034e1bc9a0SAchim Leubner     return tiStatus;
11044e1bc9a0SAchim Leubner #endif
11054e1bc9a0SAchim Leubner   }
11064e1bc9a0SAchim Leubner #endif /* else of FDS_SM */
11074e1bc9a0SAchim Leubner 
11084e1bc9a0SAchim Leubner   else
11094e1bc9a0SAchim Leubner   {
11104e1bc9a0SAchim Leubner 
11114e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
11124e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
11134e1bc9a0SAchim Leubner     TI_DBG1(("tiINISuperIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
11144e1bc9a0SAchim Leubner     /*
11154e1bc9a0SAchim Leubner       error. unsupported IO
11164e1bc9a0SAchim Leubner      */
11174e1bc9a0SAchim Leubner   }
11184e1bc9a0SAchim Leubner   return tiStatus;
11194e1bc9a0SAchim Leubner }
11204e1bc9a0SAchim Leubner 
11214e1bc9a0SAchim Leubner osGLOBAL bit32
tiINISMPStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiSMPFrame_t * tiSMPFrame,void * tiSMPBody,bit32 interruptContext)11224e1bc9a0SAchim Leubner tiINISMPStart(
11234e1bc9a0SAchim Leubner        tiRoot_t                  *tiRoot,
11244e1bc9a0SAchim Leubner        tiIORequest_t             *tiIORequest,
11254e1bc9a0SAchim Leubner        tiDeviceHandle_t          *tiDeviceHandle,
11264e1bc9a0SAchim Leubner        tiSMPFrame_t              *tiSMPFrame,
11274e1bc9a0SAchim Leubner        void                      *tiSMPBody,
11284e1bc9a0SAchim Leubner        bit32                     interruptContext
11294e1bc9a0SAchim Leubner        )
11304e1bc9a0SAchim Leubner {
11314e1bc9a0SAchim Leubner   tdsaDeviceData_t          *oneDeviceData;
11324e1bc9a0SAchim Leubner   agsaIORequest_t           *agIORequest = agNULL;
11334e1bc9a0SAchim Leubner   tdIORequestBody_t         *tdSMPRequestBody = agNULL;
11344e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot = agNULL;
11354e1bc9a0SAchim Leubner   agsaDevHandle_t           *agDevHandle = agNULL;
11364e1bc9a0SAchim Leubner   agsaSASRequestBody_t      *agRequestBody = agNULL;
11374e1bc9a0SAchim Leubner   agsaSMPFrame_t            *agSMPFrame = agNULL;
11384e1bc9a0SAchim Leubner   bit32                     agRequestType;
11394e1bc9a0SAchim Leubner   bit32                     tiStatus = tiError;
11404e1bc9a0SAchim Leubner   bit32                     saStatus = AGSA_RC_FAILURE;
11414e1bc9a0SAchim Leubner   bit32                     queueNum;
11424e1bc9a0SAchim Leubner   TDSA_INP_ENTER(tiRoot);
11434e1bc9a0SAchim Leubner     TI_DBG6(("tiINISMPStart: start\n"));
11444e1bc9a0SAchim Leubner     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
11454e1bc9a0SAchim Leubner   TI_DBG6(("tiINISMPStart: onedevicedata %p\n", oneDeviceData));
11464e1bc9a0SAchim Leubner     TI_DBG6(("tiINISMPStart: tiDeviceHandle %p\n", tiDeviceHandle));
11474e1bc9a0SAchim Leubner   if (oneDeviceData == agNULL)
11484e1bc9a0SAchim Leubner   {
11494e1bc9a0SAchim Leubner     TI_DBG1(("tiINISMPStart: tiDeviceHandle=%p Expander DeviceData is NULL\n", tiDeviceHandle ));
11504e1bc9a0SAchim Leubner     return tiError;
11514e1bc9a0SAchim Leubner   }
11524e1bc9a0SAchim Leubner   if (tiIORequest->osData == agNULL)
11534e1bc9a0SAchim Leubner   {
11544e1bc9a0SAchim Leubner     TI_DBG1(("tiINISMPStart: tiIORequest->osData is NULL, wrong\n"));
11554e1bc9a0SAchim Leubner     return tiError;
11564e1bc9a0SAchim Leubner   }
11574e1bc9a0SAchim Leubner   agRoot = oneDeviceData->agRoot;
11584e1bc9a0SAchim Leubner   agDevHandle = oneDeviceData->agDevHandle;
11594e1bc9a0SAchim Leubner   tdSMPRequestBody = (tdIORequestBody_t *)tiSMPBody;
11604e1bc9a0SAchim Leubner   tdSMPRequestBody->tiIORequest = tiIORequest;
11614e1bc9a0SAchim Leubner   tiIORequest->tdData = tdSMPRequestBody;
11624e1bc9a0SAchim Leubner   agIORequest = &(tdSMPRequestBody->agIORequest);
11634e1bc9a0SAchim Leubner   agIORequest->osData = (void *) tdSMPRequestBody;
11644e1bc9a0SAchim Leubner   agRequestBody = &(tdSMPRequestBody->transport.SAS.agSASRequestBody);
11654e1bc9a0SAchim Leubner   agSMPFrame = &(agRequestBody->smpFrame);
11664e1bc9a0SAchim Leubner   if (!DEVICE_IS_SMP_TARGET(oneDeviceData))
11674e1bc9a0SAchim Leubner   {
11684e1bc9a0SAchim Leubner     TI_DBG1(("tiINISMPStart: Target Device is not SMP device\n"));
11694e1bc9a0SAchim Leubner     return tiError;
11704e1bc9a0SAchim Leubner   }
11714e1bc9a0SAchim Leubner   if (tiSMPFrame->flag == 0) // define DIRECT SMP at td layer?
11724e1bc9a0SAchim Leubner   {
11734e1bc9a0SAchim Leubner     TI_DBG6(("tiINISMPStart: Direct SMP\n"));
11744e1bc9a0SAchim Leubner     agSMPFrame->outFrameBuf = tiSMPFrame->outFrameBuf;
11754e1bc9a0SAchim Leubner     agSMPFrame->outFrameLen = tiSMPFrame->outFrameLen;
11764e1bc9a0SAchim Leubner     tdhexdump("tiINISMPStart agSMPFrame", (bit8 *)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
11774e1bc9a0SAchim Leubner     agSMPFrame->expectedRespLen = tiSMPFrame->expectedRespLen;
11784e1bc9a0SAchim Leubner     agSMPFrame->inFrameLen = 0;
11794e1bc9a0SAchim Leubner     agSMPFrame->flag = tiSMPFrame->flag;
11804e1bc9a0SAchim Leubner     agRequestType = AGSA_SMP_INIT_REQ;
11814e1bc9a0SAchim Leubner     queueNum = 0;
11824e1bc9a0SAchim Leubner     saStatus = saSMPStart(agRoot,
11834e1bc9a0SAchim Leubner                 agIORequest,
11844e1bc9a0SAchim Leubner                 queueNum,
11854e1bc9a0SAchim Leubner                 agDevHandle,
11864e1bc9a0SAchim Leubner                 agRequestType,
11874e1bc9a0SAchim Leubner                 agRequestBody,
11884e1bc9a0SAchim Leubner                 &ossaSMPCAMCompleted
11894e1bc9a0SAchim Leubner                );
11904e1bc9a0SAchim Leubner     if (saStatus == AGSA_RC_SUCCESS)
11914e1bc9a0SAchim Leubner     {
11924e1bc9a0SAchim Leubner       tiStatus = tiSuccess;
11934e1bc9a0SAchim Leubner     }
11944e1bc9a0SAchim Leubner     else
11954e1bc9a0SAchim Leubner     {
11964e1bc9a0SAchim Leubner       if (saStatus == AGSA_RC_BUSY)
11974e1bc9a0SAchim Leubner       {
11984e1bc9a0SAchim Leubner         TI_DBG1(("tiINISMPStart: saSSPStart busy\n"));
11994e1bc9a0SAchim Leubner         tiStatus = tiBusy;
12004e1bc9a0SAchim Leubner       }
12014e1bc9a0SAchim Leubner       else
12024e1bc9a0SAchim Leubner       {
12034e1bc9a0SAchim Leubner         TI_DBG1(("tiINISMPStart: saSSPStart error\n"));
12044e1bc9a0SAchim Leubner         tiStatus = tiError;
12054e1bc9a0SAchim Leubner       }
12064e1bc9a0SAchim Leubner       return tiStatus;
12074e1bc9a0SAchim Leubner     }
12084e1bc9a0SAchim Leubner   }
12094e1bc9a0SAchim Leubner   else
12104e1bc9a0SAchim Leubner   {
12114e1bc9a0SAchim Leubner     TI_DBG1(("tiINISMPStart: Indirect SMP! Not supported yet\n"));
12124e1bc9a0SAchim Leubner     tiStatus = tiError;
12134e1bc9a0SAchim Leubner   }
12144e1bc9a0SAchim Leubner   return tiStatus;
12154e1bc9a0SAchim Leubner }
12164e1bc9a0SAchim Leubner #ifdef TD_INT_COALESCE
12174e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIIOStartIntCoalesce(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiIntCoalesceContext_t * tiIntCoalesceCxt)12184e1bc9a0SAchim Leubner tiINIIOStartIntCoalesce(
12194e1bc9a0SAchim Leubner              tiRoot_t                  *tiRoot,
12204e1bc9a0SAchim Leubner              tiIORequest_t             *tiIORequest,
12214e1bc9a0SAchim Leubner              tiDeviceHandle_t          *tiDeviceHandle,
12224e1bc9a0SAchim Leubner              tiScsiInitiatorRequest_t *tiScsiRequest,
12234e1bc9a0SAchim Leubner              void                      *tiRequestBody,
12244e1bc9a0SAchim Leubner              bit32                     interruptContext,
12254e1bc9a0SAchim Leubner              tiIntCoalesceContext_t    *tiIntCoalesceCxt
12264e1bc9a0SAchim Leubner              )
12274e1bc9a0SAchim Leubner {
12284e1bc9a0SAchim Leubner   tdsaRoot_t                *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
12294e1bc9a0SAchim Leubner   tdsaContext_t             *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
12304e1bc9a0SAchim Leubner   itdsaIni_t                *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
12314e1bc9a0SAchim Leubner   tdsaDeviceData_t          *oneDeviceData;
12324e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot = agNULL;
12334e1bc9a0SAchim Leubner   agsaIORequest_t           *agIORequest = agNULL;
12344e1bc9a0SAchim Leubner   agsaDevHandle_t           *agDevHandle = agNULL;
12354e1bc9a0SAchim Leubner   bit32                     agRequestType;
12364e1bc9a0SAchim Leubner   agsaSASRequestBody_t      *agSASRequestBody = agNULL;
12374e1bc9a0SAchim Leubner   bit32                     tiStatus = tiError;
12384e1bc9a0SAchim Leubner   bit32                     saStatus = AGSA_RC_FAILURE;
12394e1bc9a0SAchim Leubner 
12404e1bc9a0SAchim Leubner   tdIORequestBody_t         *tdIORequestBody;
12414e1bc9a0SAchim Leubner   agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
12424e1bc9a0SAchim Leubner   tdsaIntCoalesceContext_t  *tdsaIntCoalCxt;
12434e1bc9a0SAchim Leubner   agsaIntCoalesceContext_t  *agIntCoalCxt;
12444e1bc9a0SAchim Leubner 
12454e1bc9a0SAchim Leubner   TI_DBG1(("tiINIIOStartIntCoalesce: start\n"));
12464e1bc9a0SAchim Leubner   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
12474e1bc9a0SAchim Leubner 
12484e1bc9a0SAchim Leubner   TI_DBG6(("tiINIIOStartIntCoalesce: onedevicedata %p\n", oneDeviceData));
12494e1bc9a0SAchim Leubner 
12504e1bc9a0SAchim Leubner   if(oneDeviceData == agNULL)
12514e1bc9a0SAchim Leubner   {
12524e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesce: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
12534e1bc9a0SAchim Leubner     return tiIONoDevice;
12544e1bc9a0SAchim Leubner   }
12554e1bc9a0SAchim Leubner 
12564e1bc9a0SAchim Leubner   /* starting IO with SAS device */
12574e1bc9a0SAchim Leubner   if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
12584e1bc9a0SAchim Leubner   {
12594e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStartIntCoalesce: calling saSSPStart\n"));
12604e1bc9a0SAchim Leubner 
12614e1bc9a0SAchim Leubner     agRoot = oneDeviceData->agRoot;
12624e1bc9a0SAchim Leubner     agDevHandle = oneDeviceData->agDevHandle;
12634e1bc9a0SAchim Leubner 
12644e1bc9a0SAchim Leubner     /* OS layer has tdlayer data structure pointer in
12654e1bc9a0SAchim Leubner        tdIORequestBody_t    tdIOReqBody;
12664e1bc9a0SAchim Leubner        in ccb_t in agtiapi.h
12674e1bc9a0SAchim Leubner     */
12684e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
12694e1bc9a0SAchim Leubner 
12704e1bc9a0SAchim Leubner     /* let's initialize tdIOrequestBody */
12714e1bc9a0SAchim Leubner     /* initialize callback */
12724e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
12734e1bc9a0SAchim Leubner 
12744e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
12754e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
12764e1bc9a0SAchim Leubner 
12774e1bc9a0SAchim Leubner     /* initialize tiIORequest */
12784e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
12794e1bc9a0SAchim Leubner 
12804e1bc9a0SAchim Leubner     /* save context if we need to abort later */
12814e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
12824e1bc9a0SAchim Leubner 
12834e1bc9a0SAchim Leubner     /* initialize expDataLength */
12844e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.expDataLength
12854e1bc9a0SAchim Leubner       = tiScsiRequest->scsiCmnd.expDataLength;
12864e1bc9a0SAchim Leubner 
12874e1bc9a0SAchim Leubner     /* initializes "agsaSgl_t   agSgl" of "agsaDifSSPInitiatorRequest_t" */
12884e1bc9a0SAchim Leubner     tiStatus = itdssIOPrepareSGL(
12894e1bc9a0SAchim Leubner                                  tiRoot,
12904e1bc9a0SAchim Leubner                                  tdIORequestBody,
12914e1bc9a0SAchim Leubner                                  &tiScsiRequest->agSgl1,
12924e1bc9a0SAchim Leubner                                  tiScsiRequest->sglVirtualAddr
12934e1bc9a0SAchim Leubner                                  );
12944e1bc9a0SAchim Leubner 
12954e1bc9a0SAchim Leubner     if (tiStatus != tiSuccess)
12964e1bc9a0SAchim Leubner     {
12974e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesce: can't get SGL\n"));
12984e1bc9a0SAchim Leubner       return tiStatus;
12994e1bc9a0SAchim Leubner     }
13004e1bc9a0SAchim Leubner 
13014e1bc9a0SAchim Leubner 
13024e1bc9a0SAchim Leubner     /* initialize agIORequest */
13034e1bc9a0SAchim Leubner     agIORequest = &(tdIORequestBody->agIORequest);
13044e1bc9a0SAchim Leubner     agIORequest->osData = (void *) tdIORequestBody;
13054e1bc9a0SAchim Leubner     agIORequest->sdkData = agNULL; /* LL takes care of this */
13064e1bc9a0SAchim Leubner 
13074e1bc9a0SAchim Leubner 
13084e1bc9a0SAchim Leubner     /*
13094e1bc9a0SAchim Leubner       initialize
13104e1bc9a0SAchim Leubner       tdIORequestBody_t tdIORequestBody -> agSASRequestBody
13114e1bc9a0SAchim Leubner     */
13124e1bc9a0SAchim Leubner     agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
13134e1bc9a0SAchim Leubner     agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
13144e1bc9a0SAchim Leubner 
13154e1bc9a0SAchim Leubner 
13164e1bc9a0SAchim Leubner     /* copy cdb bytes */
13174e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
13184e1bc9a0SAchim Leubner 
13194e1bc9a0SAchim Leubner     /* copy lun field */
13204e1bc9a0SAchim Leubner     osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
13214e1bc9a0SAchim Leubner                 tiScsiRequest->scsiCmnd.lun.lun, 8);
13224e1bc9a0SAchim Leubner 
13234e1bc9a0SAchim Leubner     /* setting the data length */
13244e1bc9a0SAchim Leubner     agSSPInitiatorRequest->dataLength  = tiScsiRequest->scsiCmnd.expDataLength;
13254e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStartIntCoalesce: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
13264e1bc9a0SAchim Leubner 
13274e1bc9a0SAchim Leubner     agSSPInitiatorRequest->firstBurstSize = 0;
13284e1bc9a0SAchim Leubner 
13294e1bc9a0SAchim Leubner     if (tiScsiRequest->dataDirection == tiDirectionIn)
13304e1bc9a0SAchim Leubner     {
13314e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_READ;
13324e1bc9a0SAchim Leubner       TI_DBG6(("tiINIIOStartIntCoalesce: READ\n"));
13334e1bc9a0SAchim Leubner     }
13344e1bc9a0SAchim Leubner     else if (tiScsiRequest->dataDirection == tiDirectionOut)
13354e1bc9a0SAchim Leubner     {
13364e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_WRITE;
13374e1bc9a0SAchim Leubner       TI_DBG6(("tiINIIOStartIntCoalesce: WRITE\n"));
13384e1bc9a0SAchim Leubner     }
13394e1bc9a0SAchim Leubner     else
13404e1bc9a0SAchim Leubner     {
13414e1bc9a0SAchim Leubner       agRequestType = AGSA_REQ_TYPE_UNKNOWN;
13424e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesce: unknown data direction\n"));
13434e1bc9a0SAchim Leubner     }
13444e1bc9a0SAchim Leubner 
13454e1bc9a0SAchim Leubner     tdIORequestBody->agRequestType = agRequestType;
13464e1bc9a0SAchim Leubner 
13474e1bc9a0SAchim Leubner     tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
13484e1bc9a0SAchim Leubner     agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
13494e1bc9a0SAchim Leubner 
13504e1bc9a0SAchim Leubner 
13514e1bc9a0SAchim Leubner 
13524e1bc9a0SAchim Leubner #ifdef LL_INT_COALESCE
13534e1bc9a0SAchim Leubner     saStatus = saSSPStartIntCoalesce(agRoot,
13544e1bc9a0SAchim Leubner                                      agIORequest,
13554e1bc9a0SAchim Leubner                                      agIntCoalCxt,
13564e1bc9a0SAchim Leubner                                      agDevHandle,
13574e1bc9a0SAchim Leubner                                      agRequestType,
13584e1bc9a0SAchim Leubner                                      agSASRequestBody,
13594e1bc9a0SAchim Leubner                                      &ossaSSPCompleted);
13604e1bc9a0SAchim Leubner #endif
13614e1bc9a0SAchim Leubner 
13624e1bc9a0SAchim Leubner     tdIORequestBody->ioStarted = agTRUE;
13634e1bc9a0SAchim Leubner     tdIORequestBody->ioCompleted = agFALSE;
13644e1bc9a0SAchim Leubner 
13654e1bc9a0SAchim Leubner     if (saStatus == AGSA_RC_SUCCESS)
13664e1bc9a0SAchim Leubner     {
13674e1bc9a0SAchim Leubner       Initiator->NumIOsActive++;
13684e1bc9a0SAchim Leubner       tiStatus = tiSuccess;
13694e1bc9a0SAchim Leubner     }
13704e1bc9a0SAchim Leubner     else
13714e1bc9a0SAchim Leubner     {
13724e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesce: saSSPStart failed\n"));
13734e1bc9a0SAchim Leubner       tdIORequestBody->ioStarted = agFALSE;
13744e1bc9a0SAchim Leubner       tdIORequestBody->ioCompleted = agTRUE;
13754e1bc9a0SAchim Leubner       if (saStatus == AGSA_RC_BUSY)
13764e1bc9a0SAchim Leubner       {
13774e1bc9a0SAchim Leubner         tiStatus = tiBusy;
13784e1bc9a0SAchim Leubner       }
13794e1bc9a0SAchim Leubner       else
13804e1bc9a0SAchim Leubner       {
13814e1bc9a0SAchim Leubner         tiStatus = tiError;
13824e1bc9a0SAchim Leubner       }
13834e1bc9a0SAchim Leubner       return tiStatus;
13844e1bc9a0SAchim Leubner     }
13854e1bc9a0SAchim Leubner   }
13864e1bc9a0SAchim Leubner 
13874e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
13884e1bc9a0SAchim Leubner   {
13894e1bc9a0SAchim Leubner     /*
13904e1bc9a0SAchim Leubner       satIOStart() -> saSATAStartIntCoalesce()
13914e1bc9a0SAchim Leubner     */
13924e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesce: SATA not supported yet\n"));
13934e1bc9a0SAchim Leubner     return tiStatus;
13944e1bc9a0SAchim Leubner   }
13954e1bc9a0SAchim Leubner   else
13964e1bc9a0SAchim Leubner   {
13974e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesce: wrong unspported Device %d\n", oneDeviceData->DeviceType));
13984e1bc9a0SAchim Leubner     /*
13994e1bc9a0SAchim Leubner       error. unsupported IO
14004e1bc9a0SAchim Leubner      */
14014e1bc9a0SAchim Leubner   }
14024e1bc9a0SAchim Leubner   return tiStatus;
14034e1bc9a0SAchim Leubner 
14044e1bc9a0SAchim Leubner 
14054e1bc9a0SAchim Leubner }
14064e1bc9a0SAchim Leubner 
14074e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIIOStartIntCoalesceDif(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,void * tiRequestBody,bit32 interruptContext,tiIntCoalesceContext_t * tiIntCoalesceCxt,tiDif_t * difOption)14084e1bc9a0SAchim Leubner tiINIIOStartIntCoalesceDif(
14094e1bc9a0SAchim Leubner                            tiRoot_t                  *tiRoot,
14104e1bc9a0SAchim Leubner                            tiIORequest_t             *tiIORequest,
14114e1bc9a0SAchim Leubner                            tiDeviceHandle_t          *tiDeviceHandle,
14124e1bc9a0SAchim Leubner                            tiScsiInitiatorRequest_t *tiScsiRequest,
14134e1bc9a0SAchim Leubner                            void                      *tiRequestBody,
14144e1bc9a0SAchim Leubner                            bit32                     interruptContext,
14154e1bc9a0SAchim Leubner                            tiIntCoalesceContext_t    *tiIntCoalesceCxt,
14164e1bc9a0SAchim Leubner                            tiDif_t                   *difOption
14174e1bc9a0SAchim Leubner                            )
14184e1bc9a0SAchim Leubner {
14194e1bc9a0SAchim Leubner   tdsaRoot_t                   *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
14204e1bc9a0SAchim Leubner   tdsaContext_t                *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
14214e1bc9a0SAchim Leubner   itdsaIni_t                   *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
14224e1bc9a0SAchim Leubner   tdsaDeviceData_t             *oneDeviceData;
14234e1bc9a0SAchim Leubner   agsaRoot_t                   *agRoot = agNULL;
14244e1bc9a0SAchim Leubner   agsaIORequest_t              *agIORequest = agNULL;
14254e1bc9a0SAchim Leubner   agsaDevHandle_t              *agDevHandle = agNULL;
14264e1bc9a0SAchim Leubner   bit32                        agRequestType;
14274e1bc9a0SAchim Leubner   agsaDifSSPRequestBody_t      *agEdcSSPRequestBody = agNULL;
14284e1bc9a0SAchim Leubner   bit32                        tiStatus = tiError;
14294e1bc9a0SAchim Leubner   bit32                        saStatus = AGSA_RC_FAILURE;
14304e1bc9a0SAchim Leubner 
14314e1bc9a0SAchim Leubner   tdIORequestBody_t            *tdIORequestBody;
14324e1bc9a0SAchim Leubner   agsaDifSSPInitiatorRequest_t *agEdcSSPInitiatorRequest;
14334e1bc9a0SAchim Leubner   agsaDif_t                    *agEdc;
14344e1bc9a0SAchim Leubner   bit32                        agUpdateMask = 0;
14354e1bc9a0SAchim Leubner   bit32                        agVerifyMask = 0;
14364e1bc9a0SAchim Leubner   tdsaIntCoalesceContext_t     *tdsaIntCoalCxt;
14374e1bc9a0SAchim Leubner   agsaIntCoalesceContext_t     *agIntCoalCxt;
14384e1bc9a0SAchim Leubner 
14394e1bc9a0SAchim Leubner   TI_DBG1(("tiINIIOStartIntCoalesceDif: start\n"));
14404e1bc9a0SAchim Leubner   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
14414e1bc9a0SAchim Leubner 
14424e1bc9a0SAchim Leubner   TI_DBG6(("tiINIIOStartIntCoalesceDif: onedevicedata %p\n", oneDeviceData));
14434e1bc9a0SAchim Leubner 
14444e1bc9a0SAchim Leubner   if(oneDeviceData == agNULL)
14454e1bc9a0SAchim Leubner   {
14464e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesceDif: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
14474e1bc9a0SAchim Leubner     return tiIONoDevice;
14484e1bc9a0SAchim Leubner   }
14494e1bc9a0SAchim Leubner 
14504e1bc9a0SAchim Leubner   /* starting IO with SAS device */
14514e1bc9a0SAchim Leubner   if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
14524e1bc9a0SAchim Leubner   {
14534e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStartIntCoalesceDif: calling saSSPStart\n"));
14544e1bc9a0SAchim Leubner 
14554e1bc9a0SAchim Leubner     agRoot = oneDeviceData->agRoot;
14564e1bc9a0SAchim Leubner     agDevHandle = oneDeviceData->agDevHandle;
14574e1bc9a0SAchim Leubner 
14584e1bc9a0SAchim Leubner     /* OS layer has tdlayer data structure pointer in
14594e1bc9a0SAchim Leubner        tdIORequestBody_t    tdIOReqBody;
14604e1bc9a0SAchim Leubner        in ccb_t in agtiapi.h
14614e1bc9a0SAchim Leubner     */
14624e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
14634e1bc9a0SAchim Leubner 
14644e1bc9a0SAchim Leubner     /* let's initialize tdIOrequestBody */
14654e1bc9a0SAchim Leubner     /* initialize callback */
14664e1bc9a0SAchim Leubner     tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
14674e1bc9a0SAchim Leubner 
14684e1bc9a0SAchim Leubner     /* initialize tiDevhandle */
14694e1bc9a0SAchim Leubner     tdIORequestBody->tiDevHandle = tiDeviceHandle;
14704e1bc9a0SAchim Leubner 
14714e1bc9a0SAchim Leubner     /* initialize tiIORequest */
14724e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
14734e1bc9a0SAchim Leubner 
14744e1bc9a0SAchim Leubner     /* save context if we need to abort later */
14754e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
14764e1bc9a0SAchim Leubner 
14774e1bc9a0SAchim Leubner     /* initialize expDataLength */
14784e1bc9a0SAchim Leubner     tdIORequestBody->IOType.InitiatorRegIO.expDataLength
14794e1bc9a0SAchim Leubner       = tiScsiRequest->scsiCmnd.expDataLength;
14804e1bc9a0SAchim Leubner 
14814e1bc9a0SAchim Leubner     /* initializes "agsaSgl_t   agSgl" of "agsaDifSSPInitiatorRequest_t" */
14824e1bc9a0SAchim Leubner     tiStatus = itdssIOPrepareSGL(
14834e1bc9a0SAchim Leubner                                  tiRoot,
14844e1bc9a0SAchim Leubner                                  tdIORequestBody,
14854e1bc9a0SAchim Leubner                                  &tiScsiRequest->agSgl1,
14864e1bc9a0SAchim Leubner                                  tiScsiRequest->sglVirtualAddr
14874e1bc9a0SAchim Leubner                                  );
14884e1bc9a0SAchim Leubner 
14894e1bc9a0SAchim Leubner     if (tiStatus != tiSuccess)
14904e1bc9a0SAchim Leubner     {
14914e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesceDif: can't get SGL\n"));
14924e1bc9a0SAchim Leubner       return tiStatus;
14934e1bc9a0SAchim Leubner     }
14944e1bc9a0SAchim Leubner 
14954e1bc9a0SAchim Leubner 
14964e1bc9a0SAchim Leubner     /* initialize agIORequest */
14974e1bc9a0SAchim Leubner     agIORequest = &(tdIORequestBody->agIORequest);
14984e1bc9a0SAchim Leubner     agIORequest->osData = (void *) tdIORequestBody;
14994e1bc9a0SAchim Leubner     agIORequest->sdkData = agNULL; /* LL takes care of this */
15004e1bc9a0SAchim Leubner 
15014e1bc9a0SAchim Leubner 
15024e1bc9a0SAchim Leubner     /*
15034e1bc9a0SAchim Leubner       initialize
15044e1bc9a0SAchim Leubner       tdIORequestBody_t tdIORequestBody -> agSASRequestBody
15054e1bc9a0SAchim Leubner     */
15064e1bc9a0SAchim Leubner     agEdcSSPRequestBody = &(tdIORequestBody->transport.SAS.agEdcSSPRequestBody);
15074e1bc9a0SAchim Leubner     agEdcSSPInitiatorRequest = &(agEdcSSPRequestBody->edcSSPInitiatorReq);
15084e1bc9a0SAchim Leubner 
15094e1bc9a0SAchim Leubner 
15104e1bc9a0SAchim Leubner     /* copy cdb bytes */
15114e1bc9a0SAchim Leubner     osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
15124e1bc9a0SAchim Leubner 
15134e1bc9a0SAchim Leubner     /* copy lun field */
15144e1bc9a0SAchim Leubner     osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.lun,
15154e1bc9a0SAchim Leubner                 tiScsiRequest->scsiCmnd.lun.lun, 8);
15164e1bc9a0SAchim Leubner 
15174e1bc9a0SAchim Leubner 
15184e1bc9a0SAchim Leubner     /* setting the data length */
15194e1bc9a0SAchim Leubner     agEdcSSPInitiatorRequest->dataLength  = tiScsiRequest->scsiCmnd.expDataLength;
15204e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIOStartIntCoalesceDif: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
15214e1bc9a0SAchim Leubner 
15224e1bc9a0SAchim Leubner     agEdcSSPInitiatorRequest->firstBurstSize = 0;
15234e1bc9a0SAchim Leubner 
15244e1bc9a0SAchim Leubner 
15254e1bc9a0SAchim Leubner     if (tiScsiRequest->dataDirection == tiDirectionIn)
15264e1bc9a0SAchim Leubner     {
15274e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_READ;
15284e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesceDif: READ difAction %X\n",difOption->difAction));
15294e1bc9a0SAchim Leubner     }
15304e1bc9a0SAchim Leubner     else if (tiScsiRequest->dataDirection == tiDirectionOut)
15314e1bc9a0SAchim Leubner     {
15324e1bc9a0SAchim Leubner       agRequestType = AGSA_SSP_INIT_WRITE;
15334e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesceDif: WRITE difAction %X\n",difOption->difAction));
15344e1bc9a0SAchim Leubner     }
15354e1bc9a0SAchim Leubner     else
15364e1bc9a0SAchim Leubner     {
15374e1bc9a0SAchim Leubner       agRequestType = AGSA_REQ_TYPE_UNKNOWN;
15384e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesceDif: unknown data direction\n"));
15394e1bc9a0SAchim Leubner     }
15404e1bc9a0SAchim Leubner 
15414e1bc9a0SAchim Leubner     tdIORequestBody->agRequestType = agRequestType;
15424e1bc9a0SAchim Leubner 
15434e1bc9a0SAchim Leubner     /* process interrupt coalesce context */
15444e1bc9a0SAchim Leubner     tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
15454e1bc9a0SAchim Leubner     agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
15464e1bc9a0SAchim Leubner 
15474e1bc9a0SAchim Leubner     /* process DIF */
15484e1bc9a0SAchim Leubner 
15494e1bc9a0SAchim Leubner     agEdc = &(agEdcSSPInitiatorRequest->edc);
15504e1bc9a0SAchim Leubner 
15514e1bc9a0SAchim Leubner     osti_memset(agEdc, 0, sizeof(agsaDif_t));
15524e1bc9a0SAchim Leubner 
15534e1bc9a0SAchim Leubner     /* setting edcFlag */
15544e1bc9a0SAchim Leubner     if (difOption->enableBlockCount)
15554e1bc9a0SAchim Leubner     {
15564e1bc9a0SAchim Leubner       /* enables block count; bit5 */
15574e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag | 0x20; /* 0010 0000 */
15584e1bc9a0SAchim Leubner     }
15594e1bc9a0SAchim Leubner 
15604e1bc9a0SAchim Leubner     if (difOption->enableCrc)
15614e1bc9a0SAchim Leubner     {
15624e1bc9a0SAchim Leubner       /* enables CRC verification; bit6 */
15634e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag | 0x40; /* 0100 0000 */
15644e1bc9a0SAchim Leubner     }
15654e1bc9a0SAchim Leubner 
15664e1bc9a0SAchim Leubner     if (difOption->enableIOSeed)
15674e1bc9a0SAchim Leubner     {
15684e1bc9a0SAchim Leubner 
15694e1bc9a0SAchim Leubner     }
15704e1bc9a0SAchim Leubner     if (difOption->difAction == DIF_INSERT)
15714e1bc9a0SAchim Leubner     {
15724e1bc9a0SAchim Leubner       /* bit 0 - 2; 000 */
15734e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag & 0xFFFFFFF8;
15744e1bc9a0SAchim Leubner     }
15754e1bc9a0SAchim Leubner     else if (difOption->difAction == DIF_VERIFY_FORWARD)
15764e1bc9a0SAchim Leubner     {
15774e1bc9a0SAchim Leubner       /* bit 0 - 2; 001 */
15784e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag | 0x01;
15794e1bc9a0SAchim Leubner     }
15804e1bc9a0SAchim Leubner     else if (difOption->difAction == DIF_VERIFY_DELETE)
15814e1bc9a0SAchim Leubner     {
15824e1bc9a0SAchim Leubner       /* bit 0 - 2; 010 */
15834e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag | 0x02;
15844e1bc9a0SAchim Leubner     }
15854e1bc9a0SAchim Leubner     else
15864e1bc9a0SAchim Leubner     {
15874e1bc9a0SAchim Leubner       /* DIF_VERIFY_REPLACE */
15884e1bc9a0SAchim Leubner       /* bit 0 - 2; 011 */
15894e1bc9a0SAchim Leubner       agEdc->edcFlag = agEdc->edcFlag | 0x04;
15904e1bc9a0SAchim Leubner     }
15914e1bc9a0SAchim Leubner 
15924e1bc9a0SAchim Leubner     /* set Update Mask; bit 16-21 */
15934e1bc9a0SAchim Leubner     agUpdateMask = (difOption->tagUpdateMask) & 0x3F; /* 0011 1111 */
15944e1bc9a0SAchim Leubner     agUpdateMask = agUpdateMask << 16;
15954e1bc9a0SAchim Leubner     agEdc->edcFlag = agEdc->edcFlag | agUpdateMask;
15964e1bc9a0SAchim Leubner 
15974e1bc9a0SAchim Leubner     /* set Verify Mask bit 24-29 */
15984e1bc9a0SAchim Leubner     agVerifyMask = (difOption->tagVerifyMask) & 0x3F; /* 0011 1111 */
15994e1bc9a0SAchim Leubner     agVerifyMask = agVerifyMask << 24;
16004e1bc9a0SAchim Leubner     agEdc->edcFlag = agEdc->edcFlag | agVerifyMask;
16014e1bc9a0SAchim Leubner 
16024e1bc9a0SAchim Leubner     agEdc->appTag = difOption->udtArray[0];
16034e1bc9a0SAchim Leubner     agEdc->appTag = (agEdc->appTag << 8) | difOption->udtArray[1];
16044e1bc9a0SAchim Leubner 
16054e1bc9a0SAchim Leubner     agEdc->lbaReferenceTag =  difOption->udtArray[2];
16064e1bc9a0SAchim Leubner     agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[3];
16074e1bc9a0SAchim Leubner     agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[4];
16084e1bc9a0SAchim Leubner     agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[5];
16094e1bc9a0SAchim Leubner 
16104e1bc9a0SAchim Leubner     /* currently TISA supports only 512 logical block size */
16114e1bc9a0SAchim Leubner     agEdc->lbSize = 512;
16124e1bc9a0SAchim Leubner 
16134e1bc9a0SAchim Leubner 
16144e1bc9a0SAchim Leubner #ifdef LL_INT_COALESCE
16154e1bc9a0SAchim Leubner     saStatus = saSSPStartIntCoalesceEdc(agRoot,
16164e1bc9a0SAchim Leubner                                         agIORequest,
16174e1bc9a0SAchim Leubner                                         agIntCoalCxt,
16184e1bc9a0SAchim Leubner                                         agDevHandle,
16194e1bc9a0SAchim Leubner                                         agRequestType,
16204e1bc9a0SAchim Leubner                                         agEdcSSPRequestBody,
16214e1bc9a0SAchim Leubner                                         &ossaSSPCompleted);
16224e1bc9a0SAchim Leubner #endif
16234e1bc9a0SAchim Leubner 
16244e1bc9a0SAchim Leubner     tdIORequestBody->ioStarted = agTRUE;
16254e1bc9a0SAchim Leubner     tdIORequestBody->ioCompleted = agFALSE;
16264e1bc9a0SAchim Leubner 
16274e1bc9a0SAchim Leubner     if (saStatus == AGSA_RC_SUCCESS)
16284e1bc9a0SAchim Leubner     {
16294e1bc9a0SAchim Leubner       Initiator->NumIOsActive++;
16304e1bc9a0SAchim Leubner       tiStatus = tiSuccess;
16314e1bc9a0SAchim Leubner     }
16324e1bc9a0SAchim Leubner     else
16334e1bc9a0SAchim Leubner     {
16344e1bc9a0SAchim Leubner       TI_DBG1(("tiINIIOStartIntCoalesceDif: saSSPStart failed\n"));
16354e1bc9a0SAchim Leubner       tdIORequestBody->ioStarted = agFALSE;
16364e1bc9a0SAchim Leubner       tdIORequestBody->ioCompleted = agTRUE;
16374e1bc9a0SAchim Leubner       if (saStatus == AGSA_RC_BUSY)
16384e1bc9a0SAchim Leubner       {
16394e1bc9a0SAchim Leubner         tiStatus = tiBusy;
16404e1bc9a0SAchim Leubner       }
16414e1bc9a0SAchim Leubner       else
16424e1bc9a0SAchim Leubner       {
16434e1bc9a0SAchim Leubner         tiStatus = tiError;
16444e1bc9a0SAchim Leubner       }
16454e1bc9a0SAchim Leubner       return tiStatus;
16464e1bc9a0SAchim Leubner     }
16474e1bc9a0SAchim Leubner   }
16484e1bc9a0SAchim Leubner   else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
16494e1bc9a0SAchim Leubner   {
16504e1bc9a0SAchim Leubner     /*
16514e1bc9a0SAchim Leubner       satIOStart() -> saSATAStartIntCoalesceEdc()
16524e1bc9a0SAchim Leubner     */
16534e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesceDif: SATA not supported yet\n"));
16544e1bc9a0SAchim Leubner     return tiStatus;
16554e1bc9a0SAchim Leubner   }
16564e1bc9a0SAchim Leubner   else
16574e1bc9a0SAchim Leubner   {
16584e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIOStartIntCoalesceDif: wrong unspported Device %d\n", oneDeviceData->DeviceType));
16594e1bc9a0SAchim Leubner     /*
16604e1bc9a0SAchim Leubner       error. unsupported IO
16614e1bc9a0SAchim Leubner      */
16624e1bc9a0SAchim Leubner   }
16634e1bc9a0SAchim Leubner   return tiStatus;
16644e1bc9a0SAchim Leubner }
16654e1bc9a0SAchim Leubner 
16664e1bc9a0SAchim Leubner 
16674e1bc9a0SAchim Leubner osGLOBAL bit32
tiINIIntCoalesceInit(tiRoot_t * tiRoot,tiIntCoalesceContext_t * tiIntCoalesceCxt,bit32 count)16684e1bc9a0SAchim Leubner tiINIIntCoalesceInit(
16694e1bc9a0SAchim Leubner                      tiRoot_t                  *tiRoot,
16704e1bc9a0SAchim Leubner                      tiIntCoalesceContext_t    *tiIntCoalesceCxt,
16714e1bc9a0SAchim Leubner                      bit32                     count
16724e1bc9a0SAchim Leubner                      )
16734e1bc9a0SAchim Leubner {
16744e1bc9a0SAchim Leubner 
16754e1bc9a0SAchim Leubner   tdsaRoot_t                *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
16764e1bc9a0SAchim Leubner   tdsaContext_t             *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
16774e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot = agNULL;
16784e1bc9a0SAchim Leubner   tdsaIntCoalesceContext_t  *tdsaIntCoalCxtHead
16794e1bc9a0SAchim Leubner     = (tdsaIntCoalesceContext_t *)tdsaAllShared->IntCoalesce;
16804e1bc9a0SAchim Leubner   tdsaIntCoalesceContext_t  *tdsaIntCoalCxt;
16814e1bc9a0SAchim Leubner   agsaIntCoalesceContext_t  *agIntCoalCxt;
16824e1bc9a0SAchim Leubner   tdList_t                  *tdsaIntCoalCxtList = agNULL;
16834e1bc9a0SAchim Leubner 
16844e1bc9a0SAchim Leubner   bit32                     tiStatus = tiError;
16854e1bc9a0SAchim Leubner 
16864e1bc9a0SAchim Leubner   TI_DBG1(("tiINIIntCoalesceInit: start\n"));
16874e1bc9a0SAchim Leubner 
16884e1bc9a0SAchim Leubner   tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
16894e1bc9a0SAchim Leubner   if (TDLIST_NOT_EMPTY(&(tdsaIntCoalCxtHead->FreeLink)))
16904e1bc9a0SAchim Leubner   {
16914e1bc9a0SAchim Leubner     TDLIST_DEQUEUE_FROM_HEAD(&tdsaIntCoalCxtList, &(tdsaIntCoalCxtHead->FreeLink));
16924e1bc9a0SAchim Leubner     tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
16934e1bc9a0SAchim Leubner     tdsaIntCoalCxt
16944e1bc9a0SAchim Leubner       = TDLIST_OBJECT_BASE(tdsaIntCoalesceContext_t, FreeLink, tdsaIntCoalCxtList);
16954e1bc9a0SAchim Leubner 
16964e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIntCoalesceInit: id %d\n", tdsaIntCoalCxt->id));
16974e1bc9a0SAchim Leubner 
16984e1bc9a0SAchim Leubner     agRoot = &(tdsaAllShared->agRootNonInt);
16994e1bc9a0SAchim Leubner 
17004e1bc9a0SAchim Leubner     agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
17014e1bc9a0SAchim Leubner     tdsaIntCoalCxt->tiIntCoalesceCxt = tiIntCoalesceCxt;
17024e1bc9a0SAchim Leubner     tiIntCoalesceCxt->tdData = tdsaIntCoalCxt;
17034e1bc9a0SAchim Leubner     agIntCoalCxt->osData = tdsaIntCoalCxt;
17044e1bc9a0SAchim Leubner 
17054e1bc9a0SAchim Leubner     tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
17064e1bc9a0SAchim Leubner     TDLIST_ENQUEUE_AT_TAIL(&(tdsaIntCoalCxt->MainLink), &(tdsaIntCoalCxtHead->MainLink));
17074e1bc9a0SAchim Leubner     tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
17084e1bc9a0SAchim Leubner 
17094e1bc9a0SAchim Leubner     /*
17104e1bc9a0SAchim Leubner       note: currently asynchronously call is assumed. In other words,
17114e1bc9a0SAchim Leubner       "ossaIntCoalesceInitCB()" -> "ostiInitiatorCoalesceInitCB()" are used
17124e1bc9a0SAchim Leubner     */
17134e1bc9a0SAchim Leubner #ifdef LL_INT_COALESCE
17144e1bc9a0SAchim Leubner     tiStatus = saIntCoalesceInit(agRoot, agIntCoalCxt, count);
17154e1bc9a0SAchim Leubner #endif
17164e1bc9a0SAchim Leubner 
17174e1bc9a0SAchim Leubner     TI_DBG6(("tiINIIntCoalesceInit: status %d\n", tiStatus));
17184e1bc9a0SAchim Leubner     return tiStatus;
17194e1bc9a0SAchim Leubner   }
17204e1bc9a0SAchim Leubner   else
17214e1bc9a0SAchim Leubner   {
17224e1bc9a0SAchim Leubner     tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
17234e1bc9a0SAchim Leubner     TI_DBG1(("tiINIIntCoalesceInit: no more interrupt coalesce context; return fail\n"));
17244e1bc9a0SAchim Leubner     return tiStatus;
17254e1bc9a0SAchim Leubner   }
17264e1bc9a0SAchim Leubner }
17274e1bc9a0SAchim Leubner #endif /* TD_INT_COALESCE */
17284e1bc9a0SAchim Leubner 
17294e1bc9a0SAchim Leubner /*****************************************************************************
17304e1bc9a0SAchim Leubner *! \brief itdssIOPrepareSGL
17314e1bc9a0SAchim Leubner *
17324e1bc9a0SAchim Leubner *  Purpose:  This function is called to translate TISA SGL information to the
17334e1bc9a0SAchim Leubner *            LL layer SGL.
17344e1bc9a0SAchim Leubner *
17354e1bc9a0SAchim Leubner *  \param    tiRoot:         Pointer to initiator driver/port instance.
17364e1bc9a0SAchim Leubner *  \param    IORequestBody:  TD layer request body for the I/O.
17374e1bc9a0SAchim Leubner *  \param    tiSgl1:         First TISA SGL info.
17384e1bc9a0SAchim Leubner *  \param    sglVirtualAddr: The virtual address of the first element in
17394e1bc9a0SAchim Leubner *                            tiSgl1 when tiSgl1 is used with the type tiSglList.
17404e1bc9a0SAchim Leubner *
17414e1bc9a0SAchim Leubner *  \return:
17424e1bc9a0SAchim Leubner *
17434e1bc9a0SAchim Leubner *  tiSuccess:     SGL initialized successfully.
17444e1bc9a0SAchim Leubner *  tiError:       Failed to initialize SGL.
17454e1bc9a0SAchim Leubner *
17464e1bc9a0SAchim Leubner *
17474e1bc9a0SAchim Leubner *****************************************************************************/
17484e1bc9a0SAchim Leubner osGLOBAL FORCEINLINE bit32
itdssIOPrepareSGL(tiRoot_t * tiRoot,tdIORequestBody_t * tdIORequestBody,tiSgl_t * tiSgl1,void * sglVirtualAddr)17494e1bc9a0SAchim Leubner itdssIOPrepareSGL(
17504e1bc9a0SAchim Leubner                   tiRoot_t                 *tiRoot,
17514e1bc9a0SAchim Leubner                   tdIORequestBody_t        *tdIORequestBody,
17524e1bc9a0SAchim Leubner                   tiSgl_t                  *tiSgl1,
17534e1bc9a0SAchim Leubner                   void                     *sglVirtualAddr
17544e1bc9a0SAchim Leubner                   )
17554e1bc9a0SAchim Leubner {
17564e1bc9a0SAchim Leubner   agsaSgl_t                 *agSgl;
17574e1bc9a0SAchim Leubner 
17584e1bc9a0SAchim Leubner   TI_DBG6(("itdssIOPrepareSGL: start\n"));
17594e1bc9a0SAchim Leubner 
17604e1bc9a0SAchim Leubner   agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspInitiatorReq.agSgl);
17614e1bc9a0SAchim Leubner 
17624e1bc9a0SAchim Leubner   agSgl->len = 0;
17634e1bc9a0SAchim Leubner 
17644e1bc9a0SAchim Leubner   if (tiSgl1 == agNULL)
17654e1bc9a0SAchim Leubner   {
17664e1bc9a0SAchim Leubner     TI_DBG1(("itdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
17674e1bc9a0SAchim Leubner     return tiError;
17684e1bc9a0SAchim Leubner   }
17694e1bc9a0SAchim Leubner 
17704e1bc9a0SAchim Leubner   if (tdIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
17714e1bc9a0SAchim Leubner   {
17724e1bc9a0SAchim Leubner     TI_DBG6(("itdssIOPrepareSGL: expDataLength is 0\n"));
17734e1bc9a0SAchim Leubner     agSgl->sgUpper = 0;
17744e1bc9a0SAchim Leubner     agSgl->sgLower = 0;
17754e1bc9a0SAchim Leubner     agSgl->len = 0;
17764e1bc9a0SAchim Leubner     CLEAR_ESGL_EXTEND(agSgl->extReserved);
17774e1bc9a0SAchim Leubner     return tiSuccess;
17784e1bc9a0SAchim Leubner   }
17794e1bc9a0SAchim Leubner 
17804e1bc9a0SAchim Leubner   agSgl->sgUpper = tiSgl1->upper;
17814e1bc9a0SAchim Leubner   agSgl->sgLower = tiSgl1->lower;
17824e1bc9a0SAchim Leubner   agSgl->len = tiSgl1->len;
17834e1bc9a0SAchim Leubner   agSgl->extReserved = tiSgl1->type;
17844e1bc9a0SAchim Leubner 
17854e1bc9a0SAchim Leubner   return tiSuccess;
17864e1bc9a0SAchim Leubner }
17874e1bc9a0SAchim Leubner 
17884e1bc9a0SAchim Leubner osGLOBAL bit32
tiNumOfLunIOCTLreq(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,void * tiRequestBody,tiIOCTLPayload_t * agIOCTLPayload,void * agParam1,void * agParam2)17894e1bc9a0SAchim Leubner tiNumOfLunIOCTLreq(
17904e1bc9a0SAchim Leubner              tiRoot_t                       *tiRoot,
17914e1bc9a0SAchim Leubner              tiIORequest_t                  *tiIORequest,
17924e1bc9a0SAchim Leubner              tiDeviceHandle_t               *tiDeviceHandle,
17934e1bc9a0SAchim Leubner              void                           *tiRequestBody,
17944e1bc9a0SAchim Leubner              tiIOCTLPayload_t               *agIOCTLPayload,
17954e1bc9a0SAchim Leubner              void                           *agParam1,
17964e1bc9a0SAchim Leubner              void                           *agParam2
17974e1bc9a0SAchim Leubner              )
17984e1bc9a0SAchim Leubner {
17994e1bc9a0SAchim Leubner   tdsaRoot_t			    *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
18004e1bc9a0SAchim Leubner   tdsaContext_t			    *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
18014e1bc9a0SAchim Leubner   agsaRoot_t			    *agRoot = &(tdsaAllShared->agRootInt);
18024e1bc9a0SAchim Leubner   void					    *respBuffer = agNULL;
18034e1bc9a0SAchim Leubner   void					    *osMemHandle = agNULL;
18044e1bc9a0SAchim Leubner   bit32					    ostiMemoryStatus = 0;
18054e1bc9a0SAchim Leubner   tdsaDeviceData_t		    *oneDeviceData = agNULL;
18064e1bc9a0SAchim Leubner   agsaSSPInitiatorRequest_t *agSSPFrame = agNULL;
18074e1bc9a0SAchim Leubner   bit32					    status = IOCTL_CALL_SUCCESS;
18084e1bc9a0SAchim Leubner   bit32					    agRequestType = 0;
18094e1bc9a0SAchim Leubner   agsaDevHandle_t 		    *agDevHandle = agNULL;
18104e1bc9a0SAchim Leubner   agsaIORequest_t 		    *agIORequest = agNULL;
18114e1bc9a0SAchim Leubner   tdIORequestBody_t		    *tdIORequestBody = agNULL;
18124e1bc9a0SAchim Leubner   agsaSASRequestBody_t	    *agSASRequestBody = agNULL;
18134e1bc9a0SAchim Leubner 
18144e1bc9a0SAchim Leubner   do
18154e1bc9a0SAchim Leubner   {
18164e1bc9a0SAchim Leubner     if((tiIORequest == agNULL) || (tiRequestBody == agNULL))
18174e1bc9a0SAchim Leubner     {
18184e1bc9a0SAchim Leubner       status = IOCTL_CALL_FAIL;
18194e1bc9a0SAchim Leubner       break;
18204e1bc9a0SAchim Leubner     }
18214e1bc9a0SAchim Leubner     tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
18224e1bc9a0SAchim Leubner     tdIORequestBody->tiIORequest = tiIORequest;
18234e1bc9a0SAchim Leubner 
18244e1bc9a0SAchim Leubner     /* save context if we need to abort later */
18254e1bc9a0SAchim Leubner     tiIORequest->tdData = tdIORequestBody;
18264e1bc9a0SAchim Leubner 
18274e1bc9a0SAchim Leubner     agIORequest = &(tdIORequestBody->agIORequest);
18284e1bc9a0SAchim Leubner     agIORequest->osData = (void *) tdIORequestBody;
18294e1bc9a0SAchim Leubner     agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
18304e1bc9a0SAchim Leubner     agSSPFrame = &(agSASRequestBody->sspInitiatorReq);
18314e1bc9a0SAchim Leubner 
18324e1bc9a0SAchim Leubner     ostiMemoryStatus = ostiAllocMemory( tiRoot,
18334e1bc9a0SAchim Leubner     									  &osMemHandle,
18344e1bc9a0SAchim Leubner     									  (void **)&respBuffer,
18354e1bc9a0SAchim Leubner     									  &(agSSPFrame->agSgl.sgUpper),
18364e1bc9a0SAchim Leubner     									  &(agSSPFrame->agSgl.sgLower),
18374e1bc9a0SAchim Leubner     									  8,
18384e1bc9a0SAchim Leubner     									  REPORT_LUN_LEN,
18394e1bc9a0SAchim Leubner     									  agFALSE);
18404e1bc9a0SAchim Leubner     if((ostiMemoryStatus != tiSuccess) && (respBuffer == agNULL  ))
18414e1bc9a0SAchim Leubner     {
18424e1bc9a0SAchim Leubner       status = IOCTL_CALL_FAIL;
18434e1bc9a0SAchim Leubner       break;
18444e1bc9a0SAchim Leubner     }
18454e1bc9a0SAchim Leubner 
18464e1bc9a0SAchim Leubner     osti_memset((void *)respBuffer, 0, REPORT_LUN_LEN);
18474e1bc9a0SAchim Leubner 
18484e1bc9a0SAchim Leubner     	// use FW control place in shared structure to keep the neccesary information
18494e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.virtAddr = respBuffer;
18504e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.len = REPORT_LUN_LEN;
18514e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.param1 = agParam1;
18524e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.param2 = agParam2;
18534e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.payload = agIOCTLPayload;
18544e1bc9a0SAchim Leubner     tdsaAllShared->tdFWControlEx.inProgress = 1;
18554e1bc9a0SAchim Leubner     agRequestType = AGSA_SSP_INIT_READ;
18564e1bc9a0SAchim Leubner 
18574e1bc9a0SAchim Leubner     status = IOCTL_CALL_PENDING;
18584e1bc9a0SAchim Leubner     oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData);
18594e1bc9a0SAchim Leubner     agDevHandle = oneDeviceData->agDevHandle;
18604e1bc9a0SAchim Leubner 
18614e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[0] = REPORT_LUN_OPCODE;
18624e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[1] = 0x0;
18634e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[2] = 0x0;
18644e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[3] = 0x0;
18654e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[4] = 0x0;
18664e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[5] = 0x0;
18674e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[6] = 0x0;
18684e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[7] = 0x0;
18694e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[8] = 0x0;
18704e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[9] = REPORT_LUN_LEN;
18714e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[10] = 0x0;
18724e1bc9a0SAchim Leubner     agSSPFrame->sspCmdIU.cdb[11] = 0x0;
18734e1bc9a0SAchim Leubner 
18744e1bc9a0SAchim Leubner     agSSPFrame->dataLength = REPORT_LUN_LEN;
18754e1bc9a0SAchim Leubner     agSSPFrame->agSgl.len =	sizeof(agsaSSPCmdInfoUnit_t);
18762fb6802fSDavid Bright     agSSPFrame->agSgl.extReserved = 0;
18772fb6802fSDavid Bright     CLEAR_ESGL_EXTEND(agSSPFrame->agSgl.extReserved);
18784e1bc9a0SAchim Leubner 
18794e1bc9a0SAchim Leubner     status = saSSPStart(agRoot, agIORequest, 0, agDevHandle, agRequestType,agSASRequestBody,agNULL,
18804e1bc9a0SAchim Leubner     										   &ossaSSPIoctlCompleted);
18814e1bc9a0SAchim Leubner     if(status != AGSA_RC_SUCCESS)
18824e1bc9a0SAchim Leubner 	{
18834e1bc9a0SAchim Leubner       ostiFreeMemory(tiRoot,
18844e1bc9a0SAchim Leubner     				 tdsaAllShared->tdFWControlEx.virtAddr,
18854e1bc9a0SAchim Leubner     				 tdsaAllShared->tdFWControlEx.len);
18864e1bc9a0SAchim Leubner       tdsaAllShared->tdFWControlEx.payload = NULL;
18874e1bc9a0SAchim Leubner       tdsaAllShared->tdFWControlEx.inProgress = 0;
18884e1bc9a0SAchim Leubner       status = IOCTL_CALL_FAIL;
18894e1bc9a0SAchim Leubner     }
18904e1bc9a0SAchim Leubner   }while(0);
18914e1bc9a0SAchim Leubner   return status;
18924e1bc9a0SAchim Leubner }
18934e1bc9a0SAchim Leubner 
18944e1bc9a0SAchim Leubner 
1895