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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/freebsd/driver/ini/src/agtiapi.c

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

    1 /*******************************************************************************
    2 **
    3 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
    4  *
    5 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 
    6 *that the following conditions are met: 
    7 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
    8 *2. Redistributions in binary form must reproduce the above copyright notice, 
    9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
   10 *
   11 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   12 *
   13 *INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
   14 *ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
   15 *SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
   16 *OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   17 *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
   18 *THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
   19 **
   20 *******************************************************************************/
   21 
   22 #include <sys/cdefs.h>
   23 __FBSDID("$FreeBSD$");
   24 #include <dev/pms/config.h>
   25 
   26 #define MAJOR_REVISION      1
   27 #define MINOR_REVISION      3
   28 #define BUILD_REVISION      10800
   29 
   30 #include <sys/param.h>      // defines used in kernel.h
   31 #include <sys/ioccom.h>
   32 #include <sys/module.h>
   33 #include <sys/systm.h>
   34 #include <sys/errno.h>
   35 #include <sys/kernel.h>     // types used in module initialization
   36 #include <sys/conf.h>       // cdevsw struct
   37 #include <sys/uio.h>        // uio struct
   38 #include <sys/types.h>
   39 #include <sys/malloc.h>
   40 #include <sys/bus.h>        // structs, prototypes for pci bus stuff
   41 #include <machine/bus.h>
   42 #include <sys/rman.h>
   43 #include <machine/resource.h>
   44 #include <vm/vm.h>          // 1. for vtophys
   45 #include <vm/pmap.h>        // 2. for vtophys
   46 #include <dev/pci/pcivar.h> // For pci_get macros
   47 #include <dev/pci/pcireg.h>
   48 #include <sys/endian.h>
   49 #include <sys/lock.h>
   50 #include <sys/mutex.h>
   51 #include <sys/sema.h>
   52 #include <sys/queue.h>
   53 #include <sys/taskqueue.h>
   54 #include <machine/atomic.h>
   55 #include <sys/libkern.h>
   56 #include <cam/cam.h>
   57 #include <cam/cam_ccb.h>
   58 #include <cam/cam_debug.h>
   59 #include <cam/cam_periph.h> //
   60 #include <cam/cam_sim.h>
   61 #include <cam/cam_xpt_sim.h>
   62 #include <cam/scsi/scsi_all.h>
   63 #include <cam/scsi/scsi_message.h>
   64 #include <sys/systm.h>
   65 #include <sys/types.h>
   66 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
   67 #include <dev/pms/freebsd/driver/ini/src/agtiapi.h>
   68 #include <dev/pms/freebsd/driver/ini/src/agtiproto.h>
   69 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
   70 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
   71 #include <dev/pms/freebsd/driver/common/lxencrypt.h> 
   72 
   73 MALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" );
   74 
   75 MALLOC_DEFINE( M_PMC_MSTL, "STLock malloc",
   76                "allocated in agtiapi_attach as memory for lock use" );
   77 MALLOC_DEFINE( M_PMC_MDVT, "ag_device_t malloc",
   78                "allocated in agtiapi_attach as mem for ag_device_t pDevList" );
   79 MALLOC_DEFINE( M_PMC_MPRT, "ag_portal_data_t malloc",
   80                "allocated in agtiapi_attach as mem for *pPortalData" );
   81 MALLOC_DEFINE( M_PMC_MDEV, "tiDeviceHandle_t * malloc",
   82                "allocated in agtiapi_GetDevHandle as local mem for **agDev" );
   83 MALLOC_DEFINE( M_PMC_MFLG, "lDevFlags * malloc",
   84                "allocated in agtiapi_GetDevHandle as local mem for * flags" );
   85 #ifdef LINUX_PERBI_SUPPORT
   86 MALLOC_DEFINE( M_PMC_MSLR, "ag_slr_map_t malloc",
   87                "mem allocated in agtiapi_attach for pSLRList" );
   88 MALLOC_DEFINE( M_PMC_MTGT, "ag_tgt_map_t malloc",
   89                "mem allocated in agtiapi_attach for pWWNList" );
   90 #endif
   91 MALLOC_DEFINE(TEMP,"tempbuff","buffer for payload");
   92 MALLOC_DEFINE(TEMP2, "tempbuff", "buffer for agtiapi_getdevlist");
   93 STATIC U32  agtiapi_intx_mode    = 0;
   94 STATIC U08  ag_Perbi             = 0;
   95 STATIC U32  agtiapi_polling_mode = 0;
   96 STATIC U32  ag_card_good         = 0;   // * total card initialized
   97 STATIC U32  ag_option_flag       = 0;   // * adjustable parameter flag
   98 STATIC U32  agtiapi_1st_time     = 1;
   99 STATIC U32  ag_timeout_secs      = 10;  //Made timeout equivalent to linux
  100 
  101 U32         gTiDebugLevel        = 1;
  102 S32             ag_encryption_enable = 0;
  103 atomic_t    outstanding_encrypted_io_count;
  104 
  105 #define cache_line_size() CACHE_LINE_SIZE
  106 
  107 #define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  108 
  109 #define CPU_TO_LE32(dst, src)                  \
  110     dst.lower = htole32(LOW_32_BITS(src)); \
  111     dst.upper = htole32(HIGH_32_BITS(src))
  112 
  113 #define CMND_TO_CHANNEL( ccb )     ( ccb->ccb_h.path_id )
  114 #define CMND_TO_TARGET(  ccb )     ( ccb->ccb_h.target_id )
  115 #define CMND_TO_LUN(     ccb )     ( ccb->ccb_h.target_lun )
  116 
  117 STATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] = 
  118       { AGTIAPI_PERIPHERAL };
  119 
  120 #ifdef LINUX_PERBI_SUPPORT
  121 // Holding area for target-WWN mapping assignments on the boot line
  122 static ag_mapping_t *agMappingList = NULL;  // modified by agtiapi_Setup()
  123 #endif
  124 
  125 // * For Debugging Purpose 
  126 #ifdef AGTIAPI_DEBUG
  127 #define AGTIAPI_WWN(name, len)   wwnprintk(name, len)
  128 #else
  129 #define AGTIAPI_WWN(name, len)
  130 #endif
  131 
  132 
  133 #define AGTIAPI_WWNPRINTK(name, len, format, a...)     \
  134           AGTIAPI_PRINTK(format "name ", a);           \
  135           AGTIAPI_WWN((unsigned char*)name, len);
  136 
  137 #define AGTIAPI_ERR_WWNPRINTK(name, len, format, a...) \
  138           printk(KERN_DEBUG format "name ", ## a);     \
  139           wwnprintk((unsigned char*)name, len);
  140 #define AGTIAPI_CPY_DEV_INFO(root, dev, pDev)            \
  141           tiINIGetDeviceInfo(root, dev, &pDev->devInfo); \
  142           wwncpy(pDev);
  143 
  144 #ifdef AGTIAPI_LOCAL_LOCK
  145 
  146 #define AG_CARD_LOCAL_LOCK(lock)     ,(lock)
  147 #define AG_SPIN_LOCK_IRQ(lock, flags)
  148 #define AG_SPIN_UNLOCK_IRQ(lock, flags)
  149 #define AG_SPIN_LOCK(lock)
  150 #define AG_SPIN_UNLOCK(lock)
  151 #define AG_GLOBAL_ARG(arg)
  152 #define AG_PERF_SPINLOCK(lock)
  153 #define AG_PERF_SPINLOCK_IRQ(lock, flags)
  154 
  155 
  156 #define AG_LOCAL_LOCK(lock)     if (lock) \
  157                                          mtx_lock(lock)
  158 #define AG_LOCAL_UNLOCK(lock)   if (lock) \
  159                                          mtx_unlock(lock)
  160 #define AG_LOCAL_FLAGS(_flags)         unsigned long _flags = 0
  161 #endif
  162 
  163 
  164 #define AG_GET_DONE_PCCB(pccb, pmcsc)            \
  165   {                                              \
  166     AG_LOCAL_LOCK(&pmcsc->doneLock);             \
  167     pccb = pmcsc->ccbDoneHead;                   \
  168     if (pccb != NULL)                            \
  169     {                                            \
  170       pmcsc->ccbDoneHead = NULL;                 \
  171       pmcsc->ccbDoneTail = NULL;                 \
  172       AG_LOCAL_UNLOCK(&pmcsc->doneLock);         \
  173       agtiapi_Done(pmcsc, pccb);                 \
  174     }                                            \
  175     else                                         \
  176       AG_LOCAL_UNLOCK(&pmcsc->doneLock);         \
  177   }
  178 
  179 #define AG_GET_DONE_SMP_PCCB(pccb, pmcsc)       \
  180   {                                              \
  181     AG_LOCAL_LOCK(&pmcsc->doneSMPLock);          \
  182     pccb = pmcsc->smpDoneHead;                   \
  183     if (pccb != NULL)                            \
  184     {                                            \
  185       pmcsc->smpDoneHead = NULL;                 \
  186       pmcsc->smpDoneTail = NULL;                 \
  187       AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock);      \
  188       agtiapi_SMPDone(pmcsc, pccb);              \
  189     }                                            \
  190     else                                         \
  191       AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock);      \
  192   }
  193 
  194 #ifdef AGTIAPI_DUMP_IO_DEBUG
  195 #define AG_IO_DUMPCCB(pccb)    agtiapi_DumpCCB(pccb)
  196 #else
  197 #define AG_IO_DUMPCCB(pccb)
  198 #endif
  199 
  200 #define SCHED_DELAY_JIFFIES 4 /* in seconds */
  201 
  202 #ifdef HOTPLUG_SUPPORT
  203 #define AG_HOTPLUG_LOCK_INIT(lock)   mxt_init(lock)
  204 #define AG_LIST_LOCK(lock)           mtx_lock(lock)
  205 #define AG_LIST_UNLOCK(lock)         mtx_unlock(lock)
  206 #else
  207 #define AG_HOTPLUG_LOCK_INIT(lock)
  208 #define AG_LIST_LOCK(lock)
  209 #define AG_LIST_UNLOCK(lock)
  210 #endif
  211 
  212 STATIC void agtiapi_CheckIOTimeout(void *data);
  213 
  214 
  215 
  216 static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list
  217 static void agtiapi_cam_action( struct cam_sim *, union ccb * );
  218 static void agtiapi_cam_poll( struct cam_sim * );
  219 
  220 // Function prototypes
  221 static d_open_t  agtiapi_open;
  222 static d_close_t agtiapi_close;
  223 static d_read_t  agtiapi_read;
  224 static d_write_t agtiapi_write;
  225 static d_ioctl_t agtiapi_CharIoctl;
  226 static void agtiapi_async(void *callback_arg, u_int32_t code,
  227               struct cam_path *path, void *arg);
  228 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth);
  229 
  230 // Character device entry points
  231 static struct cdevsw agtiapi_cdevsw = {
  232   .d_version = D_VERSION,
  233   .d_open    = agtiapi_open,
  234   .d_close   = agtiapi_close,
  235   .d_read    = agtiapi_read,
  236   .d_write   = agtiapi_write,
  237   .d_ioctl   = agtiapi_CharIoctl,
  238   .d_name    = "pmspcv",
  239 };
  240 
  241 U32 maxTargets = 0;
  242 U32 ag_portal_count = 0;
  243 
  244 // In the cdevsw routines, we find our softc by using the si_drv1 member
  245 // of struct cdev. We set this variable to point to our softc in our
  246 // attach routine when we create the /dev entry.
  247 
  248 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
  249 {
  250   struct agtiapi_softc *sc;
  251   /* Look up our softc. */
  252   sc = dev->si_drv1;
  253   AGTIAPI_PRINTK("agtiapi_open\n");
  254   AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
  255   return( 0 );
  256 }
  257 
  258 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
  259 {
  260   struct agtiapi_softc *sc;
  261   // Look up our softc
  262   sc = dev->si_drv1;
  263   AGTIAPI_PRINTK("agtiapi_close\n");
  264   AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
  265   return( 0 );
  266 }
  267 
  268 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
  269 {
  270   struct agtiapi_softc *sc;
  271   // Look up our softc
  272   sc = dev->si_drv1;
  273   AGTIAPI_PRINTK( "agtiapi_read\n" );
  274   AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n",
  275                   uio->uio_resid, sc->my_dev );
  276   return( 0 );
  277 }
  278 
  279 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
  280 {
  281   struct agtiapi_softc *sc;
  282   // Look up our softc
  283   sc = dev->si_drv1;
  284   AGTIAPI_PRINTK( "agtiapi_write\n" );
  285   AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n",
  286                   uio->uio_resid, sc->my_dev );
  287   return( 0 );
  288 }
  289 
  290 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
  291                         tiIOCTLPayload_t *agIOCTLPayload )
  292 {
  293   tdDeviceListPayload_t *pIoctlPayload =
  294     (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea;
  295   tdDeviceInfoIOCTL_t *pDeviceInfo = NULL;
  296   bit8             *pDeviceInfoOrg;
  297   tdsaDeviceData_t *pDeviceData = NULL;
  298   tiDeviceHandle_t **devList = NULL;
  299   tiDeviceHandle_t **devHandleArray = NULL;
  300   tiDeviceHandle_t *pDeviceHandle = NULL;
  301   bit32 x, memNeeded1;
  302   bit32 count, total;
  303   bit32 MaxDeviceCount;
  304   bit32 ret_val=IOCTL_CALL_INVALID_CODE;
  305   ag_portal_data_t *pPortalData;
  306   bit8 *pDeviceHandleList = NULL;
  307   AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" );
  308   
  309   pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
  310   MaxDeviceCount = pCard->devDiscover;
  311   if (MaxDeviceCount > pIoctlPayload->deviceLength )
  312   {   
  313     AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
  314     MaxDeviceCount = pIoctlPayload->deviceLength;
  315     ret_val = IOCTL_CALL_FAIL;
  316   }
  317   AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
  318   memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
  319                              sizeof(void *) );
  320   AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
  321   devList = malloc(memNeeded1, TEMP2, M_WAITOK); 
  322   if (devList == NULL)
  323   {
  324     AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
  325     ret_val = IOCTL_CALL_FAIL;
  326     agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
  327     return ret_val;
  328   }
  329   osti_memset(devList, 0,  memNeeded1);
  330   pPortalData = &pCard->pPortalData[0];
  331   pDeviceHandleList = (bit8*)devList;
  332   for (total = x = 0; x < pCard->portCount; x++, pPortalData++)
  333   {
  334     count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
  335                     &pPortalData->portalInfo.tiPortalContext,
  336                     ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
  337     if (count == DISCOVERY_IN_PROGRESS)
  338     {
  339       AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
  340                       "portal %d\n", x );
  341       free(devList, TEMP2);
  342       ret_val = IOCTL_CALL_FAIL;
  343       agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
  344       return ret_val;
  345     }
  346     total += count;
  347     pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
  348     MaxDeviceCount-= count;
  349   }
  350   if (total > pIoctlPayload->deviceLength)
  351   {
  352     total = pIoctlPayload->deviceLength;
  353   }
  354   // dump device information from device handle list
  355   count = 0;
  356   
  357   devHandleArray = devList;
  358   for (x = 0; x < pCard->devDiscover; x++)
  359   {
  360      pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
  361     if (devList[x] != agNULL)
  362     {
  363       pDeviceData = devList [x]->tdData;
  364     
  365         pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
  366       if (pDeviceData != agNULL && pDeviceInfo != agNULL)
  367       {
  368         osti_memcpy( &pDeviceInfo->sasAddressHi,
  369                      pDeviceData->agDeviceInfo.sasAddressHi,
  370                      sizeof(bit32) );
  371         osti_memcpy( &pDeviceInfo->sasAddressLo,
  372                      pDeviceData->agDeviceInfo.sasAddressLo,
  373                      sizeof(bit32) );
  374 #if 0
  375         pDeviceInfo->sasAddressHi =
  376           DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
  377         pDeviceInfo->sasAddressLo =
  378           DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
  379 #endif
  380 
  381         pDeviceInfo->deviceType =
  382           ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4;
  383         pDeviceInfo->linkRate   =
  384           pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F;
  385         pDeviceInfo->phyId      =  pDeviceData->phyID;
  386         pDeviceInfo->ishost     =  pDeviceData->target_ssp_stp_smp;
  387         pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle;
  388         if(pDeviceInfo->deviceType == 0x02)
  389         {
  390            bit8 *sasAddressHi;
  391            bit8 *sasAddressLo;
  392            tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo);
  393            pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi);
  394            pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16;
  395         }
  396         else
  397         {
  398         pDeviceInfo->sasAddressHi =
  399           DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
  400         pDeviceInfo->sasAddressLo =
  401           DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
  402         }
  403 
  404         AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n",
  405                         pDeviceInfo->deviceType );
  406         AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n",
  407                         pDeviceInfo->linkRate );
  408         AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n",
  409                         pDeviceInfo->phyId );
  410         AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n",
  411                         pDeviceInfo->sasAddressHi );
  412         AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n",
  413                         pDeviceInfo->sasAddressHi );
  414       }
  415       else
  416       {
  417         AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
  418                         "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
  419       }
  420       count++;
  421     }
  422   }
  423   pIoctlPayload->realDeviceCount = count;
  424   AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
  425   if (devList)
  426   {
  427     free(devList, TEMP2);
  428   }
  429   if(ret_val != IOCTL_CALL_FAIL)
  430   {
  431     ret_val = IOCTL_CALL_SUCCESS;
  432   }
  433   agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
  434   return  ret_val;
  435 }
  436 
  437 /******************************************************************************
  438 agtiapi_getCardInfo()
  439 
  440 Purpose:
  441   This function retrives the Card information
  442 Parameters: 
  443   
  444 Return:
  445   A number - error  
  446   0        - HBA has been detected
  447 Note:    
  448 ******************************************************************************/
  449 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
  450                           U32_64                size,
  451                           void                 *buffer )
  452 {
  453   CardInfo_t       *pCardInfo;
  454 
  455   pCardInfo = (CardInfo_t *)buffer;
  456 
  457   pCardInfo->deviceId = pci_get_device(pCard->my_dev);
  458   pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ;
  459   memcpy( pCardInfo->pciMemBaseSpc,
  460           pCard->pCardInfo->pciMemBaseSpc,
  461           ((sizeof(U32_64))*PCI_NUMBER_BARS) );
  462   pCardInfo->deviceNum = pci_get_slot(pCard->my_dev);
  463   pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase;
  464   pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow;
  465   pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp;
  466   pCardInfo->busNum =pci_get_bus(pCard->my_dev);
  467   return 0;
  468 }
  469 
  470 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
  471 {
  472   struct ccb_relsim crs;
  473   memset(&crs, 0, sizeof(crs));
  474   xpt_setup_ccb(&crs.ccb_h, path, 5);
  475   crs.ccb_h.func_code = XPT_REL_SIMQ;
  476   crs.ccb_h.flags = CAM_DEV_QFREEZE;
  477   crs.release_flags = RELSIM_ADJUST_OPENINGS;
  478   crs.openings = QueueDepth;
  479   xpt_action((union ccb *)&crs);
  480   if(crs.ccb_h.status != CAM_REQ_CMP) {
  481                  printf("XPT_REL_SIMQ failed\n");
  482   }
  483 }
  484 static void
  485 agtiapi_async(void *callback_arg, u_int32_t code,
  486                struct cam_path *path, void *arg)
  487 {
  488         struct agtiapi_softc *pmsc;
  489         U32        TID;
  490         ag_device_t *targ;      
  491         pmsc = (struct agtiapi_softc*)callback_arg;
  492         switch (code) {
  493         case AC_FOUND_DEVICE:
  494         {
  495             struct ccb_getdev *cgd;
  496             cgd = (struct ccb_getdev *)arg;
  497             if (cgd == NULL) {
  498                 break;
  499             }
  500             TID = cgd->ccb_h.target_id;
  501             if (TID >= 0 && TID < maxTargets){
  502                 if (pmsc != NULL){
  503                     TID = INDEX(pmsc, TID);
  504                     targ   = &pmsc->pDevList[TID];
  505                     agtiapi_adjust_queue_depth(path, targ->qdepth);
  506                 }
  507             }
  508             break;
  509         }
  510         default:
  511                 break;
  512         }
  513 }
  514 /******************************************************************************
  515 agtiapi_CharIoctl()
  516 
  517 Purpose:
  518   This function handles the ioctl from application layer
  519 Parameters: 
  520  
  521 Return:
  522   A number - error  
  523   0        - HBA has been detected
  524 Note:    
  525 ******************************************************************************/
  526 static int agtiapi_CharIoctl( struct cdev   *dev,
  527                               u_long         cmd,
  528                               caddr_t        data,
  529                               int            fflag,
  530                               struct thread *td )
  531 {
  532   struct sema           mx;
  533   datatosend           *load; // structure defined in lxcommon.h
  534   tiIOCTLPayload_t     *pIoctlPayload;
  535   struct agtiapi_softc *pCard;
  536   pCard=dev->si_drv1;
  537   U32   status = 0;
  538   U32   retValue;
  539   int   err    = 0;
  540   int   error  = 0;
  541   tdDeviceListPayload_t *pDeviceList = NULL;
  542   unsigned long flags;
  543 
  544   switch (cmd)
  545   {
  546   case AGTIAPI_IOCTL:
  547     load=(datatosend*)data;
  548     pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK);
  549     AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize );
  550     //Copy payload to kernel buffer, on success it returns 0
  551     err = copyin(load->data,pIoctlPayload,load->datasize);
  552     if (err)
  553     {
  554       status = IOCTL_CALL_FAIL;
  555       return status;
  556     }
  557     sema_init(&mx,0,"sem");
  558     pCard->pIoctlSem  =&mx; 
  559     pCard->up_count = pCard->down_count = 0;
  560     if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST )
  561     {
  562       retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
  563       if (retValue == 0)
  564       {
  565         pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
  566         status = IOCTL_CALL_SUCCESS;
  567       }
  568       else
  569       {
  570         pIoctlPayload->Status = IOCTL_CALL_FAIL;
  571         status = IOCTL_CALL_FAIL;
  572       }
  573       //update new device length
  574       pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea;
  575       load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount);
  576       AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize );
  577 
  578     }
  579     else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
  580     {
  581       retValue = agtiapi_getCardInfo( pCard,
  582                                       pIoctlPayload->Length,
  583                                       (pIoctlPayload->FunctionSpecificArea) );
  584       if (retValue == 0)
  585       {
  586         pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
  587         status = IOCTL_CALL_SUCCESS;
  588       }
  589       else
  590       {
  591         pIoctlPayload->Status = IOCTL_CALL_FAIL;
  592         status = IOCTL_CALL_FAIL;
  593       }
  594     }
  595     else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
  596     {
  597       if ( pCard->flags & AGTIAPI_PORT_PANIC )
  598       {
  599         strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
  600       }
  601       else
  602       {
  603         strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
  604       }
  605       pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
  606       status = IOCTL_CALL_SUCCESS;
  607     }
  608     else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
  609     {
  610       AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo);
  611       //read port status to see if there is a fatal event
  612       if(pCard->flags & AGTIAPI_PORT_PANIC)
  613       {
  614         printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo);
  615         pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE;
  616       }
  617       else
  618       {
  619         AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo);
  620         pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE;
  621       }
  622       status = IOCTL_CALL_SUCCESS;
  623     }
  624     else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
  625     {
  626       AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo);
  627       //set flags bit status to be a soft reset
  628       pCard->flags |= AGTIAPI_SOFT_RESET;
  629       //trigger soft reset for the card
  630       retValue = agtiapi_ResetCard (pCard, &flags);
  631     
  632       if(retValue == AGTIAPI_SUCCESS)
  633       {
  634         //clear port panic status
  635         pCard->flags &= ~AGTIAPI_PORT_PANIC;
  636         pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG;
  637         status = IOCTL_CALL_SUCCESS;
  638       }
  639       else
  640       {
  641         pIoctlPayload->Status = IOCTL_CALL_FAIL;
  642         status = IOCTL_CALL_FAIL;
  643       }
  644     }
  645     else
  646     {
  647       status = tiCOMMgntIOCTL( &pCard->tiRoot,
  648                                pIoctlPayload,
  649                                pCard,
  650                                NULL,
  651                                NULL );
  652       if (status == IOCTL_CALL_PENDING)
  653       {
  654         ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
  655         status = IOCTL_CALL_SUCCESS;  
  656       }
  657     }
  658     pCard->pIoctlSem = NULL;
  659     err = 0;
  660 
  661     //copy kernel buffer to userland buffer
  662     err=copyout(pIoctlPayload,load->data,load->datasize);
  663     if (err)
  664     {
  665       status = IOCTL_CALL_FAIL;
  666       return status;
  667     }
  668     free(pIoctlPayload,TEMP);
  669     pIoctlPayload=NULL;
  670     break;
  671   default:
  672     error = ENOTTY;
  673     break;
  674   }
  675   return(status);
  676 }
  677 
  678 /******************************************************************************
  679 agtiapi_probe()
  680 
  681 Purpose:
  682   This function initialize and registere all detected HBAs.
  683   The first function being called in driver after agtiapi_probe()
  684 Parameters: 
  685   device_t dev (IN)  - device pointer
  686 Return:
  687   A number - error  
  688   0        - HBA has been detected
  689 Note:    
  690 ******************************************************************************/
  691 static int agtiapi_probe( device_t dev )
  692 {
  693   int retVal;
  694   int thisCard;
  695   ag_card_info_t *thisCardInst;
  696 
  697   thisCard = device_get_unit( dev );
  698   if ( thisCard >= AGTIAPI_MAX_CARDS ) 
  699   {
  700     device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
  701     return (ENXIO); // maybe change to different return value?
  702   }
  703   thisCardInst = &agCardInfoList[ thisCard ];
  704   retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
  705   if ( retVal )
  706     return (ENXIO); // maybe change to different return value?
  707   return( BUS_PROBE_DEFAULT );  // successful probe
  708 }
  709 
  710 
  711 /******************************************************************************
  712 agtiapi_attach()
  713 
  714 Purpose:
  715   This function initialize and registere all detected HBAs.
  716   The first function being called in driver after agtiapi_probe()
  717 Parameters: 
  718   device_t dev (IN)  - device pointer
  719 Return:
  720   A number - error  
  721   0        - HBA has been detected
  722 Note:    
  723 ******************************************************************************/
  724 static int agtiapi_attach( device_t devx )
  725 {
  726   // keeping get_unit call to once
  727   int                   thisCard = device_get_unit( devx );
  728   struct agtiapi_softc *pmsc;
  729   ag_card_info_t       *thisCardInst = &agCardInfoList[ thisCard ];
  730   ag_resource_info_t   *pRscInfo;
  731   int                   idx;
  732   int                           lenRecv;
  733   char                          buffer [256], *pLastUsedChar;
  734   union ccb *ccb;
  735   int bus, tid, lun;
  736   struct ccb_setasync csa;
  737 
  738   AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard);
  739   // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values  A %p / %p\n",
  740   //        thisCardInst->pPCIDev, thisCardInst );
  741   AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) );
  742 
  743   TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS",  &ag_timeout_secs );
  744   TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel   );
  745   // printf( "agtiapi_attach: debugLevel %d, timeout %d\n",
  746   //         gTiDebugLevel, ag_timeout_secs );
  747   if ( ag_timeout_secs < 1 )
  748   {
  749     ag_timeout_secs = 1; // set minimum timeout value of 1 second
  750   }
  751   ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
  752 
  753   // Look up our softc and initialize its fields.
  754   pmsc = device_get_softc( devx );
  755   pmsc->my_dev = devx;
  756 
  757   /* Get NumberOfPortals */ 
  758   if ((ostiGetTransportParam(
  759                              &pmsc->tiRoot, 
  760                              "Global",
  761                              "CardDefault",
  762                              agNULL,
  763                              agNULL,
  764                              agNULL, 
  765                              agNULL, 
  766                              "NumberOfPortals",
  767                              buffer, 
  768                              255, 
  769                              &lenRecv
  770                              ) == tiSuccess) && (lenRecv != 0))
  771   {
  772     if (osti_strncmp(buffer, "0x", 2) == 0)
  773     { 
  774       ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
  775     }
  776     else
  777     {
  778       ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
  779     }
  780     if (ag_portal_count > AGTIAPI_MAX_PORTALS)
  781       ag_portal_count = AGTIAPI_MAX_PORTALS;
  782   }
  783   else
  784   {
  785     ag_portal_count = AGTIAPI_MAX_PORTALS;
  786   }
  787   AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count );
  788   // initialize hostdata structure
  789   pmsc->flags    |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED |
  790       AGTIAPI_INITIATOR;
  791   pmsc->cardNo    = thisCard;  
  792   pmsc->ccbTotal  = 0;
  793   pmsc->portCount = ag_portal_count;
  794   pmsc->pCardInfo = thisCardInst;
  795   pmsc->tiRoot.osData = pmsc;
  796   pmsc->pCardInfo->pCard  = (void *)pmsc;
  797   pmsc->VidDid    = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx );
  798   pmsc->SimQFrozen = agFALSE;
  799   pmsc->devq_flag  = agFALSE;
  800   pRscInfo = &thisCardInst->tiRscInfo;
  801 
  802   osti_memset(buffer, 0, 256); 
  803   lenRecv = 0;
  804 
  805   /* Get MaxTargets */ 
  806   if ((ostiGetTransportParam(
  807                              &pmsc->tiRoot, 
  808                              "Global",
  809                              "InitiatorParms",
  810                              agNULL,
  811                              agNULL,
  812                              agNULL, 
  813                              agNULL, 
  814                              "MaxTargets",
  815                              buffer, 
  816                              sizeof(buffer), 
  817                              &lenRecv
  818                              ) == tiSuccess) && (lenRecv != 0))
  819   {
  820     if (osti_strncmp(buffer, "0x", 2) == 0)
  821     { 
  822       maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
  823       AGTIAPI_PRINTK( "agtiapi_attach:  maxTargets = osti_strtoul  0 \n" );
  824     }
  825     else
  826     {
  827       maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
  828       AGTIAPI_PRINTK( "agtiapi_attach:  maxTargets = osti_strtoul 10\n"   );
  829     }
  830   }
  831   else
  832 
  833   {
  834     if(Is_ADP8H(pmsc))
  835        maxTargets = AGTIAPI_MAX_DEVICE_8H;
  836     else if(Is_ADP7H(pmsc))
  837        maxTargets = AGTIAPI_MAX_DEVICE_7H;
  838     else
  839        maxTargets = AGTIAPI_MAX_DEVICE;
  840   }
  841 
  842   if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
  843   {
  844     AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n",  maxTargets, AGTIAPI_HW_LIMIT_DEVICE );
  845     AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" );
  846     maxTargets = AGTIAPI_HW_LIMIT_DEVICE;
  847   }
  848   pmsc->devDiscover    = maxTargets ; 
  849 
  850  #ifdef HIALEAH_ENCRYPTION
  851    ag_encryption_enable   =  1;
  852    if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) == 
  853                                   PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
  854    {
  855         pmsc->encrypt = 1;
  856         pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
  857         printf("agtiapi_attach: Encryption Enabled\n" );
  858    }
  859 #endif
  860   // ## for now, skip calls to ostiGetTransportParam(...)
  861   // ## for now, skip references to DIF & EDC
  862 
  863   // Create a /dev entry for this device. The kernel will assign us
  864   // a major number automatically. We use the unit number of this
  865   // device as the minor number and name the character device
  866   // "agtiapi<unit>".
  867   pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL,
  868                             0600, "spcv%u", thisCard );
  869   pmsc->my_cdev->si_drv1 = pmsc;
  870 
  871   mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
  872             NULL, MTX_DEF|MTX_RECURSE );
  873 
  874   struct cam_devq *devq;  
  875 
  876   /* set the maximum number of pending IOs */
  877   devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
  878   if (devq == NULL)
  879   {
  880     AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
  881     return( EIO );
  882   }
  883 
  884   struct cam_sim *lsim;
  885   lsim = cam_sim_alloc( agtiapi_cam_action,
  886                         agtiapi_cam_poll,
  887                         "pmspcbsd",
  888                         pmsc,
  889                         thisCard,
  890                         &thisCardInst->pmIOLock,
  891                         1,                       // queued per target
  892                         AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
  893                         devq );
  894   if ( lsim == NULL ) {
  895     cam_simq_free( devq );
  896     AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
  897     return( EIO );
  898   }
  899 
  900   pmsc->dev_scan = agFALSE;
  901   //one cam sim per scsi bus
  902   mtx_lock( &thisCardInst->pmIOLock );
  903   if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS ) 
  904   { // bus 0
  905     cam_sim_free( lsim, TRUE );
  906     mtx_unlock( &thisCardInst->pmIOLock );
  907     AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
  908     return( EIO );
  909   }
  910 
  911   pmsc->sim  = lsim;
  912   bus = cam_sim_path(pmsc->sim);
  913   tid = CAM_TARGET_WILDCARD;
  914   lun = CAM_LUN_WILDCARD;
  915   ccb = xpt_alloc_ccb_nowait();
  916   if (ccb == agNULL)
  917   {
  918         mtx_unlock( &thisCardInst->pmIOLock );
  919     cam_sim_free( lsim, TRUE );
  920     cam_simq_free( devq );
  921     return ( EIO );
  922   }
  923   if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
  924                       CAM_LUN_WILDCARD) != CAM_REQ_CMP) 
  925   { 
  926         mtx_unlock( &thisCardInst->pmIOLock );
  927         cam_sim_free( lsim, TRUE );
  928     cam_simq_free( devq );
  929     xpt_free_ccb(ccb);
  930     return( EIO );
  931   }
  932   pmsc->path = ccb->ccb_h.path;
  933   memset(&csa, 0, sizeof(csa));
  934   xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5);
  935   csa.ccb_h.func_code = XPT_SASYNC_CB;
  936   csa.event_enable = AC_FOUND_DEVICE;
  937   csa.callback = agtiapi_async;
  938   csa.callback_arg = pmsc;
  939   xpt_action((union ccb *)&csa);
  940   if (csa.ccb_h.status != CAM_REQ_CMP) {
  941           AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" );
  942   }
  943   lsim->devq = devq;
  944   mtx_unlock( &thisCardInst->pmIOLock );
  945 
  946 
  947 
  948   
  949   // get TD and lower layer memory requirements
  950   tiCOMGetResource( &pmsc->tiRoot,
  951                     &pRscInfo->tiLoLevelResource,
  952                     &pRscInfo->tiInitiatorResource,
  953                     NULL,
  954                     &pRscInfo->tiSharedMem );
  955 
  956   agtiapi_ScopeDMARes( thisCardInst );
  957   AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
  958                   " 0x%x \n", pmsc->typhn );
  959 
  960   // initialize card information and get resource ready
  961   if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) {
  962     AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n",
  963             thisCard );
  964   }
  965 
  966   // begin: allocate and initialize card portal info resource
  967   ag_portal_data_t   *pPortalData;
  968   if (pmsc->portCount == 0)
  969   {
  970     pmsc->pPortalData = NULL;
  971   }
  972   else 
  973   {
  974     pmsc->pPortalData = (ag_portal_data_t *)
  975                         malloc( sizeof(ag_portal_data_t) * pmsc->portCount,
  976                                 M_PMC_MPRT, M_ZERO | M_WAITOK );
  977     if (pmsc->pPortalData == NULL)
  978     {
  979       AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
  980     }
  981   }
  982 
  983   pPortalData = pmsc->pPortalData;
  984   for( idx = 0; idx < pmsc->portCount; idx++ ) {
  985     pPortalData->pCard = pmsc;
  986     pPortalData->portalInfo.portID = idx;
  987     pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData;
  988     pPortalData++;
  989   }
  990   // end: allocate and initialize card portal info resource
  991 
  992   // begin: enable msix
  993 
  994   // setup msix
  995   // map to interrupt handler
  996   int error = 0;
  997   int mesgs = MAX_MSIX_NUM_VECTOR;
  998   int i, cnt;
  999 
 1000   void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
 1001     {
 1002       agtiapi_IntrHandler0,
 1003       agtiapi_IntrHandler1,
 1004       agtiapi_IntrHandler2,
 1005       agtiapi_IntrHandler3,
 1006       agtiapi_IntrHandler4,
 1007       agtiapi_IntrHandler5,
 1008       agtiapi_IntrHandler6,
 1009       agtiapi_IntrHandler7,
 1010       agtiapi_IntrHandler8,
 1011       agtiapi_IntrHandler9,
 1012       agtiapi_IntrHandler10,
 1013       agtiapi_IntrHandler11,
 1014       agtiapi_IntrHandler12,
 1015       agtiapi_IntrHandler13,
 1016       agtiapi_IntrHandler14,
 1017       agtiapi_IntrHandler15
 1018       
 1019     };
 1020 
 1021   cnt = pci_msix_count(devx);
 1022   AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64
 1023   mesgs = MIN(mesgs, cnt);
 1024   error = pci_alloc_msix(devx, &mesgs);
 1025   if (error != 0) {
 1026     printf( "pci_alloc_msix error %d\n", error );
 1027     AGTIAPI_PRINTK("error %d\n", error);
 1028     return( EIO );
 1029   }
 1030 
 1031   for(i=0; i < mesgs; i++) {
 1032     pmsc->rscID[i] = i + 1;
 1033     pmsc->irq[i] = bus_alloc_resource_any( devx,
 1034                                            SYS_RES_IRQ,
 1035                                            &pmsc->rscID[i],
 1036                                            RF_ACTIVE );
 1037     if( pmsc->irq[i] == NULL ) {
 1038       printf( "RES_IRQ went terribly bad at %d\n", i );
 1039       return( EIO );
 1040     }
 1041 
 1042     if ( (error = bus_setup_intr( devx, pmsc->irq[i],
 1043                                   INTR_TYPE_CAM | INTR_MPSAFE,
 1044                                   NULL,
 1045                                   intrHandler[i],
 1046                                   pmsc,
 1047                                   &pmsc->intrcookie[i] )
 1048            ) != 0 ) {
 1049       device_printf( devx, "Failed to register handler" );
 1050       return( EIO );
 1051     }
 1052   }
 1053   pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
 1054   pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
 1055   // end: enable msix
 1056   
 1057   int ret = 0;
 1058   ret = agtiapi_InitCardSW(pmsc);
 1059   if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
 1060   {
 1061     AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
 1062                     ret );
 1063     return( EIO );
 1064   }    
 1065 
 1066   pmsc->ccbFreeList = NULL;
 1067   pmsc->ccbChainList = NULL;
 1068   pmsc->ccbAllocList = NULL;
 1069 
 1070   pmsc->flags |= ( AGTIAPI_INSTALLED );
 1071 
 1072   ret = agtiapi_alloc_requests( pmsc );
 1073   if( ret != 0 ) {
 1074     AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
 1075                     ret );
 1076     return( EIO );
 1077   }
 1078 
 1079   ret = agtiapi_alloc_ostimem( pmsc );
 1080   if (ret != AGTIAPI_SUCCESS)
 1081   {
 1082     AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
 1083                     ret );
 1084     return( EIO );
 1085   }
 1086 
 1087   ret = agtiapi_InitCardHW( pmsc );
 1088   if (ret != 0)
 1089   {
 1090     AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
 1091                     ret );
 1092     return( EIO );
 1093   }
 1094 
 1095 #ifdef HIALEAH_ENCRYPTION
 1096   if(pmsc->encrypt)
 1097   {
 1098         if((agtiapi_SetupEncryption(pmsc)) < 0)
 1099                 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
 1100   }
 1101 #endif
 1102 
 1103   pmsc->flags &= ~AGTIAPI_INIT_TIME;
 1104   return( 0 );
 1105 }
 1106 
 1107 /******************************************************************************
 1108 agtiapi_InitCardSW()
 1109 
 1110 Purpose:
 1111   Host Bus Adapter Initialization
 1112 Parameters: 
 1113   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 1114 Return:
 1115   AGTIAPI_SUCCESS - success
 1116   AGTIAPI_FAIL    - fail
 1117 Note:    
 1118   TBD, need chip register information
 1119 ******************************************************************************/
 1120 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc ) 
 1121 {
 1122   ag_card_info_t *thisCardInst = pmsc->pCardInfo;
 1123   ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
 1124   int initSWIdx;
 1125 
 1126   // begin: agtiapi_InitCardSW()
 1127   // now init some essential locks  n agtiapi_InitCardSW
 1128   mtx_init( &pmsc->sendLock,     "local q send lock",   NULL, MTX_DEF );
 1129   mtx_init( &pmsc->doneLock,     "local q done lock",   NULL, MTX_DEF );
 1130   mtx_init( &pmsc->sendSMPLock,  "local q send lock",   NULL, MTX_DEF );
 1131   mtx_init( &pmsc->doneSMPLock,  "local q done lock",   NULL, MTX_DEF );
 1132   mtx_init( &pmsc->ccbLock,      "ccb list lock",       NULL, MTX_DEF );
 1133   mtx_init( &pmsc->devListLock,  "hotP devListLock",    NULL, MTX_DEF );
 1134   mtx_init( &pmsc->memLock,      "dynamic memory lock", NULL, MTX_DEF );
 1135   mtx_init( &pmsc->freezeLock,   "sim freeze lock",     NULL, MTX_DEF | MTX_RECURSE);
 1136 
 1137   // initialize lower layer resources
 1138   //## if (pCard->flags & AGTIAPI_INIT_TIME) {
 1139 #ifdef HIALEAH_ENCRYPTION
 1140     /* Enable encryption if chip supports it */
 1141     if (pci_get_device(pmsc->pCardInfo->pPCIDev) == 
 1142                      PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
 1143         pmsc->encrypt = 1;
 1144 
 1145     if (pmsc->encrypt)
 1146         pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
 1147 #endif
 1148   pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
 1149 
 1150 
 1151   // For now, up to 16 MSIX vectors are supported
 1152   thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.
 1153     maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors;
 1154   AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d",
 1155                   pmsc->pCardInfo->maxInterruptVectors );
 1156   thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0;
 1157   thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0;
 1158   pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0;
 1159 
 1160   AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n",
 1161                   &pmsc->tiRoot, pmsc->my_dev, pmsc );
 1162   if( tiCOMInit( &pmsc->tiRoot,
 1163                  &thisCardInst->tiRscInfo.tiLoLevelResource,
 1164                  &thisCardInst->tiRscInfo.tiInitiatorResource,
 1165                  NULL,
 1166                  &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
 1167     AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
 1168     return AGTIAPI_FAIL;
 1169   }
 1170   int maxLocks;
 1171   maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
 1172   pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
 1173                                       M_ZERO | M_WAITOK );
 1174 
 1175   for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
 1176   {
 1177     // init all indexes
 1178     mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
 1179   }
 1180 
 1181   if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
 1182     printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
 1183     return AGTIAPI_FAIL;
 1184   }
 1185   AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
 1186                   " root %p, dev %p, pmsc %p\n", 
 1187                   &pmsc->tiRoot, pmsc->my_dev, pmsc );
 1188 
 1189   pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
 1190   pmsc->freezeSim = agFALSE;
 1191 
 1192 #ifdef HIALEAH_ENCRYPTION
 1193   atomic_set(&outstanding_encrypted_io_count, 0);
 1194   /*fix below*/
 1195   /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
 1196            if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
 1197              printf("SetupEncryptionPools failed\n"); */
 1198 #endif
 1199   return AGTIAPI_SUCCESS;
 1200   // end: agtiapi_InitCardSW()
 1201 }
 1202 
 1203 /******************************************************************************
 1204 agtiapi_InitCardHW()
 1205 
 1206 Purpose:
 1207   Host Bus Adapter Initialization
 1208 Parameters: 
 1209   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 1210 Return:
 1211   AGTIAPI_SUCCESS - success
 1212   AGTIAPI_FAIL    - fail
 1213 Note:    
 1214   TBD, need chip register information
 1215 ******************************************************************************/
 1216 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc ) 
 1217 {
 1218   U32 numVal;
 1219   U32 count;
 1220   U32 loop;
 1221   // begin: agtiapi_InitCardHW()
 1222 
 1223   ag_portal_info_t *pPortalInfo = NULL;
 1224   ag_portal_data_t *pPortalData;
 1225 
 1226   // ISR is registered, enable chip interrupt.
 1227   tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
 1228   pmsc->flags |= AGTIAPI_SYS_INTR_ON;
 1229 
 1230   numVal = sizeof(ag_device_t) * pmsc->devDiscover;
 1231   pmsc->pDevList =
 1232     (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK );
 1233   if( !pmsc->pDevList ) {
 1234     AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal );
 1235     panic( "agtiapi_InitCardHW\n" );
 1236     return AGTIAPI_FAIL;
 1237   }
 1238 
 1239 #ifdef LINUX_PERBI_SUPPORT
 1240   numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
 1241   pmsc->pSLRList =
 1242     (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK );
 1243   if( !pmsc->pSLRList ) {
 1244     AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal );
 1245     panic( "agtiapi_InitCardHW SLRL\n" );
 1246     return AGTIAPI_FAIL;
 1247   }
 1248 
 1249   numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
 1250   pmsc->pWWNList =
 1251     (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK );
 1252   if( !pmsc->pWWNList ) {
 1253     AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal );
 1254     panic( "agtiapi_InitCardHW WWNL\n" );
 1255     return AGTIAPI_FAIL;
 1256   }
 1257 
 1258   // Get the WWN_to_target_ID mappings from the
 1259   // holding area which contains the input of the
 1260   // system configuration file.
 1261   if( ag_Perbi )
 1262     agtiapi_GetWWNMappings( pmsc, agMappingList );
 1263   else {
 1264     agtiapi_GetWWNMappings( pmsc, 0 );
 1265     if( agMappingList )
 1266       printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
 1267   }
 1268 #endif
 1269 
 1270   //agtiapi_DelaySec(5);
 1271   DELAY( 500000 );
 1272 
 1273   pmsc->tgtCount = 0;
 1274 
 1275   pmsc->flags &= ~AGTIAPI_CB_DONE;
 1276   pPortalData = pmsc->pPortalData;
 1277 
 1278   //start port
 1279 
 1280   for (count = 0; count < pmsc->portCount; count++)
 1281   {
 1282     AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
 1283 
 1284     pPortalInfo = &pPortalData->portalInfo;
 1285     pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START      | 
 1286                                   AGTIAPI_PORT_DISC_READY |
 1287                                   AGTIAPI_DISC_DONE       |
 1288                                   AGTIAPI_DISC_COMPLETE );
 1289 
 1290     for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
 1291     {
 1292       AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
 1293                       &pmsc->tiRoot,
 1294                       pPortalInfo->portID,
 1295                       &pPortalInfo->tiPortalContext );
 1296 
 1297       if( tiCOMPortStart( &pmsc->tiRoot, 
 1298                           pPortalInfo->portID, 
 1299                           &pPortalInfo->tiPortalContext,
 1300                           0 )
 1301           != tiSuccess ) {
 1302         AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 1303         agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY );
 1304         AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
 1305         AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n",
 1306                         pPortalData );
 1307       }
 1308       else {
 1309         AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n", 
 1310                         pPortalData );
 1311         break;
 1312       }
 1313     } // end of for loop
 1314     /* release lock */
 1315     AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 1316 
 1317     if( loop >= AGTIAPI_LOOP_MAX ) {
 1318       return AGTIAPI_FAIL;
 1319     }
 1320     tiCOMGetPortInfo( &pmsc->tiRoot,
 1321                       &pPortalInfo->tiPortalContext,
 1322                       &pPortalInfo->tiPortInfo );
 1323     pPortalData++;
 1324   }
 1325 
 1326   /* discover target device */
 1327 #ifndef HOTPLUG_SUPPORT
 1328   agtiapi_DiscoverTgt( pCard );
 1329 #endif
 1330 
 1331 
 1332   pmsc->flags |= AGTIAPI_INSTALLED;
 1333   
 1334   if( pmsc->flags & AGTIAPI_INIT_TIME ) {
 1335     agtiapi_TITimer( (void *)pmsc );
 1336     pmsc->flags |= AGTIAPI_TIMER_ON;
 1337   }
 1338 
 1339   return 0;
 1340 }
 1341 
 1342 
 1343 
 1344 /******************************************************************************
 1345 agtiapi_IntrHandlerx_()
 1346 
 1347 Purpose:
 1348   Interrupt service routine.
 1349 Parameters:
 1350   void arg (IN)              Pointer to the HBA data structure
 1351   bit32 idx (IN)             Vector index
 1352 ******************************************************************************/
 1353 void  agtiapi_IntrHandlerx_( void *arg, int index )
 1354 {
 1355   
 1356   struct agtiapi_softc *pCard;
 1357   int rv;
 1358 
 1359   pCard = (struct agtiapi_softc *)arg;
 1360 
 1361 #ifndef AGTIAPI_DPC
 1362   ccb_t     *pccb;
 1363 #endif
 1364 
 1365   AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
 1366   AG_PERF_SPINLOCK(agtiapi_host_lock);
 1367   if (pCard->flags & AGTIAPI_SHUT_DOWN)
 1368     goto ext;
 1369 
 1370   rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
 1371   if (rv == agFALSE)
 1372   {
 1373     /* not our irq */
 1374     AG_SPIN_UNLOCK(agtiapi_host_lock);
 1375     AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));    
 1376     return;
 1377   }
 1378 
 1379 
 1380 #ifdef AGTIAPI_DPC
 1381   tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
 1382 #else
 1383   /* consume all completed entries, 100 is random number to be big enough */
 1384   tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext);
 1385   AG_GET_DONE_PCCB(pccb, pCard);
 1386   AG_GET_DONE_SMP_PCCB(pccb, pCard);
 1387 #endif
 1388 
 1389 ext:
 1390   AG_SPIN_UNLOCK(agtiapi_host_lock);
 1391   AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));  
 1392   return;
 1393 
 1394 }
 1395 
 1396 /******************************************************************************
 1397 agtiapi_IntrHandler0()
 1398 Purpose:     Interrupt service routine for interrupt vector index 0.
 1399 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1400 ******************************************************************************/
 1401 void agtiapi_IntrHandler0( void *arg )
 1402 {
 1403   agtiapi_IntrHandlerx_( arg, 0 );
 1404   return;
 1405 }
 1406 
 1407 /******************************************************************************
 1408 agtiapi_IntrHandler1()
 1409 Purpose:     Interrupt service routine for interrupt vector index 1.
 1410 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1411 ******************************************************************************/
 1412 void agtiapi_IntrHandler1( void *arg )
 1413 {
 1414   agtiapi_IntrHandlerx_( arg, 1 );
 1415   return;
 1416 }
 1417 
 1418 /******************************************************************************
 1419 agtiapi_IntrHandler2()
 1420 Purpose:     Interrupt service routine for interrupt vector index 2.
 1421 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1422 ******************************************************************************/
 1423 void agtiapi_IntrHandler2( void *arg )
 1424 {
 1425   agtiapi_IntrHandlerx_( arg, 2 );
 1426   return;
 1427 }
 1428 
 1429 /******************************************************************************
 1430 agtiapi_IntrHandler3()
 1431 Purpose:     Interrupt service routine for interrupt vector index 3.
 1432 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1433 ******************************************************************************/
 1434 void agtiapi_IntrHandler3( void *arg )
 1435 {
 1436   agtiapi_IntrHandlerx_( arg, 3 );
 1437   return;
 1438 }
 1439 
 1440 /******************************************************************************
 1441 agtiapi_IntrHandler4()
 1442 Purpose:     Interrupt service routine for interrupt vector index 4.
 1443 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1444 ******************************************************************************/
 1445 void agtiapi_IntrHandler4( void *arg )
 1446 {
 1447   agtiapi_IntrHandlerx_( arg, 4 );
 1448   return;
 1449 }
 1450 
 1451 /******************************************************************************
 1452 agtiapi_IntrHandler5()
 1453 Purpose:     Interrupt service routine for interrupt vector index 5.
 1454 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1455 ******************************************************************************/
 1456 void agtiapi_IntrHandler5( void *arg )
 1457 {
 1458   agtiapi_IntrHandlerx_( arg, 5 );
 1459   return;
 1460 }
 1461 
 1462 /******************************************************************************
 1463 agtiapi_IntrHandler6()
 1464 Purpose:     Interrupt service routine for interrupt vector index 6.
 1465 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1466 ******************************************************************************/
 1467 void agtiapi_IntrHandler6( void *arg )
 1468 {
 1469   agtiapi_IntrHandlerx_( arg, 6 );
 1470   return;
 1471 }
 1472 
 1473 /******************************************************************************
 1474 agtiapi_IntrHandler7()
 1475 Purpose:     Interrupt service routine for interrupt vector index 7.
 1476 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1477 ******************************************************************************/
 1478 void agtiapi_IntrHandler7( void *arg )
 1479 {
 1480   agtiapi_IntrHandlerx_( arg, 7 );
 1481   return;
 1482 }
 1483 
 1484 /******************************************************************************
 1485 agtiapi_IntrHandler8()
 1486 Purpose:     Interrupt service routine for interrupt vector index 8.
 1487 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1488 ******************************************************************************/
 1489 void agtiapi_IntrHandler8( void *arg )
 1490 {
 1491   agtiapi_IntrHandlerx_( arg, 8 );
 1492   return;
 1493 }
 1494 
 1495 /******************************************************************************
 1496 agtiapi_IntrHandler9()
 1497 Purpose:     Interrupt service routine for interrupt vector index 9.
 1498 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1499 ******************************************************************************/
 1500 void agtiapi_IntrHandler9( void *arg )
 1501 {
 1502   agtiapi_IntrHandlerx_( arg, 9 );
 1503   return;
 1504 }
 1505 
 1506 /******************************************************************************
 1507 agtiapi_IntrHandler10()
 1508 Purpose:     Interrupt service routine for interrupt vector index 10.
 1509 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1510 ******************************************************************************/
 1511 void agtiapi_IntrHandler10( void *arg )
 1512 {
 1513   agtiapi_IntrHandlerx_( arg, 10 );
 1514   return;
 1515 }
 1516 
 1517 /******************************************************************************
 1518 agtiapi_IntrHandler11()
 1519 Purpose:     Interrupt service routine for interrupt vector index 11.
 1520 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1521 ******************************************************************************/
 1522 void agtiapi_IntrHandler11( void *arg )
 1523 {
 1524   agtiapi_IntrHandlerx_( arg, 11 );
 1525   return;
 1526 }
 1527 
 1528 /******************************************************************************
 1529 agtiapi_IntrHandler12()
 1530 Purpose:     Interrupt service routine for interrupt vector index 12.
 1531 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1532 ******************************************************************************/
 1533 void agtiapi_IntrHandler12( void *arg )
 1534 {
 1535   agtiapi_IntrHandlerx_( arg, 12 );
 1536   return;
 1537 }
 1538 
 1539 /******************************************************************************
 1540 agtiapi_IntrHandler13()
 1541 Purpose:     Interrupt service routine for interrupt vector index 13.
 1542 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1543 ******************************************************************************/
 1544 void agtiapi_IntrHandler13( void *arg )
 1545 {
 1546   agtiapi_IntrHandlerx_( arg, 13 );
 1547   return;
 1548 }
 1549 
 1550 /******************************************************************************
 1551 agtiapi_IntrHandler14()
 1552 Purpose:     Interrupt service routine for interrupt vector index 14.
 1553 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1554 ******************************************************************************/
 1555 void agtiapi_IntrHandler14( void *arg )
 1556 {
 1557   agtiapi_IntrHandlerx_( arg, 14 );
 1558   return;
 1559 }
 1560 
 1561 /******************************************************************************
 1562 agtiapi_IntrHandler15()
 1563 Purpose:     Interrupt service routine for interrupt vector index 15.
 1564 Parameters:  void arg (IN)       Pointer to the HBA data structure
 1565 ******************************************************************************/
 1566 void agtiapi_IntrHandler15( void *arg )
 1567 {
 1568   agtiapi_IntrHandlerx_( arg, 15 );
 1569   return;
 1570 }
 1571 
 1572 static void agtiapi_SglMemoryCB( void *arg,
 1573                                  bus_dma_segment_t *dm_segs,
 1574                                  int nseg,
 1575                                  int error )
 1576 {
 1577   bus_addr_t *addr;
 1578   AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
 1579   if (error != 0)
 1580   {
 1581     AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
 1582     panic("agtiapi_SglMemoryCB: error %d\n", error);
 1583     return;  
 1584   } 
 1585   addr = arg;
 1586   *addr = dm_segs[0].ds_addr;
 1587   return;
 1588 }
 1589 
 1590 static void agtiapi_MemoryCB( void *arg,
 1591                               bus_dma_segment_t *dm_segs,
 1592                               int nseg,
 1593                               int error )
 1594 {
 1595   bus_addr_t *addr;
 1596   AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
 1597   if (error != 0)
 1598   {
 1599     AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
 1600     panic("agtiapi_MemoryCB: error %d\n", error);
 1601     return;  
 1602   } 
 1603   addr = arg;
 1604   *addr = dm_segs[0].ds_addr;
 1605   return;
 1606 }
 1607 
 1608 /******************************************************************************
 1609 agtiapi_alloc_requests()
 1610 
 1611 Purpose:
 1612   Allocates resources such as dma tag and timer
 1613 Parameters: 
 1614   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 1615 Return:
 1616   AGTIAPI_SUCCESS - success
 1617   AGTIAPI_FAIL    - fail
 1618 Note:    
 1619 ******************************************************************************/
 1620 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
 1621 {
 1622   
 1623   int rsize, nsegs;
 1624   U32 next_tick;
 1625 
 1626   nsegs = AGTIAPI_NSEGS;
 1627   rsize = AGTIAPI_MAX_DMA_SEGS;   // 128
 1628   AGTIAPI_PRINTK( "agtiapi_alloc_requests: maxphys 0x%lx PAGE_SIZE 0x%x \n",
 1629                   maxphys, PAGE_SIZE );
 1630   AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n",
 1631                   nsegs, rsize ); // 32, 128
 1632   // This is for csio->data_ptr
 1633   if( bus_dma_tag_create( agNULL,                      // parent
 1634                           1,                           // alignment
 1635                           0,                           // boundary
 1636                           BUS_SPACE_MAXADDR,           // lowaddr
 1637                           BUS_SPACE_MAXADDR,           // highaddr
 1638                           NULL,                        // filter
 1639                           NULL,                        // filterarg
 1640                           BUS_SPACE_MAXSIZE_32BIT,     // maxsize
 1641                           nsegs,                       // nsegments
 1642                           BUS_SPACE_MAXSIZE_32BIT,     // maxsegsize
 1643                           BUS_DMA_ALLOCNOW,            // flags
 1644                           busdma_lock_mutex,           // lockfunc
 1645                           &pmcsc->pCardInfo->pmIOLock, // lockarg
 1646                           &pmcsc->buffer_dmat ) ) {
 1647     AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
 1648     return( ENOMEM );
 1649   }
 1650 
 1651   // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
 1652   rsize =
 1653     (sizeof(tiSgl_t) * AGTIAPI_NSEGS) *
 1654     AGTIAPI_CCB_PER_DEVICE * maxTargets;
 1655   AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128
 1656   if( bus_dma_tag_create( agNULL,                  // parent
 1657                           32,                      // alignment
 1658                           0,                         // boundary
 1659                           BUS_SPACE_MAXADDR_32BIT, // lowaddr
 1660                           BUS_SPACE_MAXADDR,         // highaddr
 1661                           NULL,                    // filter
 1662                           NULL,                    // filterarg
 1663                           rsize,                   // maxsize
 1664                           1,                       // nsegments
 1665                           rsize,                   // maxsegsize
 1666                           BUS_DMA_ALLOCNOW,        // flags
 1667                           NULL,                    // lockfunc
 1668                           NULL,                    // lockarg
 1669                           &pmcsc->tisgl_dmat ) ) {
 1670     AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
 1671     return( ENOMEM );
 1672   }
 1673 
 1674   if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
 1675                         (void **)&pmcsc->tisgl_mem,
 1676                         BUS_DMA_NOWAIT,
 1677                         &pmcsc->tisgl_map ) ) {
 1678     AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
 1679     return( ENOMEM );
 1680   }
 1681 
 1682   bzero( pmcsc->tisgl_mem, rsize );
 1683   bus_dmamap_load( pmcsc->tisgl_dmat,
 1684                    pmcsc->tisgl_map,
 1685                    pmcsc->tisgl_mem,
 1686                    rsize,
 1687                    agtiapi_SglMemoryCB,
 1688                    &pmcsc->tisgl_busaddr,
 1689                    BUS_DMA_NOWAIT /* 0 */ );
 1690 
 1691   mtx_init( &pmcsc->OS_timer_lock,  "OS timer lock",      NULL, MTX_DEF );
 1692   mtx_init( &pmcsc->IO_timer_lock,  "IO timer lock",      NULL, MTX_DEF );
 1693   mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF );
 1694   callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 );
 1695   callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 );
 1696   callout_init_mtx( &pmcsc->devRmTimer,
 1697                     &pmcsc->devRmTimerLock, 0);
 1698 
 1699   next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource.
 1700               loLevelOption.usecsPerTick / USEC_PER_TICK;
 1701   AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, "
 1702                   "next_tick 0x%x\n", next_tick );
 1703   callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc );
 1704   return 0;
 1705 }
 1706 
 1707 /******************************************************************************
 1708 agtiapi_alloc_ostimem()
 1709 
 1710 Purpose:
 1711   Allocates memory used later in ostiAllocMemory
 1712 Parameters:
 1713   struct agtiapi_softc *pmcsc (IN)  Pointer to the HBA data structure
 1714 Return:
 1715   AGTIAPI_SUCCESS - success
 1716   AGTIAPI_FAIL    - fail
 1717 Note:
 1718   This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
 1719 ******************************************************************************/
 1720 int  agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
 1721   int rsize, nomsize;
 1722 
 1723   nomsize = 4096;
 1724   rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
 1725   AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
 1726  
 1727   if( bus_dma_tag_create( agNULL,                      // parent
 1728                           32,                          // alignment
 1729                           0,                           // boundary
 1730                           BUS_SPACE_MAXADDR,           // lowaddr
 1731                           BUS_SPACE_MAXADDR,           // highaddr
 1732                           NULL,                        // filter
 1733                           NULL,                        // filterarg
 1734                           rsize,                       // maxsize (size)
 1735                           1,                           // number of segments
 1736                           rsize,                       // maxsegsize
 1737                           0,                           // flags
 1738                           NULL,                        // lockfunc
 1739                           NULL,                        // lockarg
 1740                           &pmcsc->osti_dmat ) ) {
 1741     AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
 1742     return AGTIAPI_FAIL;
 1743   }
 1744 
 1745 
 1746   if( bus_dmamem_alloc( pmcsc->osti_dmat,
 1747                         &pmcsc->osti_mem,
 1748                         BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
 1749                         &pmcsc->osti_mapp ) ) {
 1750     AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n",
 1751                     rsize );
 1752     return AGTIAPI_FAIL;
 1753   }
 1754 
 1755 
 1756   bus_dmamap_load( pmcsc->osti_dmat,
 1757                    pmcsc->osti_mapp,
 1758                    pmcsc->osti_mem,
 1759                    rsize,
 1760                    agtiapi_MemoryCB, // try reuse of CB for same goal
 1761                    &pmcsc->osti_busaddr,
 1762                    BUS_DMA_NOWAIT );
 1763 
 1764   // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
 1765   //  handy reference when driver is in motion 
 1766   int idx;
 1767   ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
 1768   ag_dma_addr_t  *pMem;
 1769 
 1770   for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
 1771     pMem = &pCardInfo->dynamicMem[idx];
 1772     pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize );
 1773     pMem->nocache_mem     = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize ));
 1774     pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx];
 1775   }
 1776 
 1777   pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
 1778 
 1779   return AGTIAPI_SUCCESS;
 1780 }
 1781 
 1782 
 1783 /******************************************************************************
 1784 agtiapi_cam_action()
 1785 
 1786 Purpose:
 1787   Parses CAM frames and triggers a corresponding action
 1788 Parameters: 
 1789   struct cam_sim *sim (IN)  Pointer to SIM data structure
 1790   union ccb * ccb (IN)      Pointer to CAM ccb data structure
 1791 Return:
 1792 Note:    
 1793 ******************************************************************************/
 1794 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
 1795 {
 1796   struct agtiapi_softc *pmcsc;
 1797   tiDeviceHandle_t *pDevHandle = NULL;  // acts as flag as well
 1798   tiDeviceInfo_t devInfo;
 1799   int pathID, targetID, lunID;
 1800   int lRetVal;
 1801   U32 TID;
 1802   U32 speed = 150000;
 1803 
 1804   pmcsc = cam_sim_softc( sim );
 1805   AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
 1806 
 1807   if (pmcsc == agNULL)
 1808   {
 1809     AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
 1810     return;
 1811   }
 1812   mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
 1813 
 1814   AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
 1815 
 1816   pathID   = xpt_path_path_id( ccb->ccb_h.path );
 1817   targetID = xpt_path_target_id( ccb->ccb_h.path );
 1818   lunID    = xpt_path_lun_id( ccb->ccb_h.path );
 1819 
 1820   AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
 1821               pathID, targetID, lunID );
 1822 
 1823   switch (ccb->ccb_h.func_code) 
 1824   {
 1825   case XPT_PATH_INQ:
 1826   {
 1827     struct ccb_pathinq *cpi;
 1828 
 1829     /* See architecure book p180*/
 1830     cpi = &ccb->cpi;
 1831     cpi->version_num = 1;
 1832     cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16;
 1833     cpi->target_sprt = 0;
 1834     cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
 1835     cpi->hba_eng_cnt = 0;
 1836     cpi->max_target = maxTargets - 1;
 1837     cpi->max_lun = AGTIAPI_MAX_LUN;
 1838     /* Max supported I/O size, in bytes. */
 1839     cpi->maxio = ctob(AGTIAPI_NSEGS - 1);
 1840     cpi->initiator_id = 255;
 1841     strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 1842     strlcpy(cpi->hba_vid, "PMC", HBA_IDLEN);
 1843     strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 1844     cpi->unit_number = cam_sim_unit(sim);
 1845     cpi->bus_id = cam_sim_bus(sim);
 1846     // rate is set when XPT_GET_TRAN_SETTINGS is processed
 1847     cpi->base_transfer_speed = 150000;
 1848     cpi->transport = XPORT_SAS;
 1849     cpi->transport_version = 0;
 1850     cpi->protocol = PROTO_SCSI;
 1851     cpi->protocol_version = SCSI_REV_SPC3;
 1852     cpi->ccb_h.status = CAM_REQ_CMP;
 1853     break;
 1854   }
 1855   case XPT_GET_TRAN_SETTINGS:
 1856   {
 1857     struct ccb_trans_settings   *cts;
 1858     struct ccb_trans_settings_sas *sas;
 1859     struct ccb_trans_settings_scsi      *scsi;
 1860 
 1861     if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
 1862     {
 1863       return;
 1864     }
 1865 
 1866     cts = &ccb->cts;
 1867     sas = &ccb->cts.xport_specific.sas;
 1868     scsi = &cts->proto_specific.scsi;
 1869 
 1870     cts->protocol = PROTO_SCSI;
 1871     cts->protocol_version = SCSI_REV_SPC3;
 1872     cts->transport = XPORT_SAS;
 1873     cts->transport_version = 0;
 1874 
 1875     sas->valid = CTS_SAS_VALID_SPEED;
 1876 
 1877     /* this sets the "MB/s transfers" */ 
 1878     if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
 1879     {
 1880       if (pmcsc->pWWNList != NULL)
 1881       {
 1882         TID = INDEX(pmcsc, targetID);
 1883         if (TID < maxTargets)
 1884         {
 1885           pDevHandle = pmcsc->pDevList[TID].pDevHandle;
 1886         }
 1887       }
 1888     }
 1889     if (pDevHandle)
 1890     {
 1891       tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
 1892       switch (devInfo.info.devType_S_Rate & 0xF)
 1893       {
 1894         case 0x8: speed = 150000;
 1895           break;
 1896         case 0x9: speed = 300000;
 1897           break;
 1898         case 0xA: speed = 600000;
 1899           break;
 1900         case 0xB: speed = 1200000;
 1901           break;
 1902         default:  speed = 150000;
 1903           break;
 1904       }
 1905     }
 1906     sas->bitrate      = speed;
 1907     scsi->valid       = CTS_SCSI_VALID_TQ;
 1908     scsi->flags       = CTS_SCSI_FLAGS_TAG_ENB;
 1909     ccb->ccb_h.status = CAM_REQ_CMP;
 1910     break;
 1911   }  
 1912   case XPT_RESET_BUS:
 1913   {
 1914     lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
 1915     if ( SUCCESS == lRetVal )
 1916     {
 1917       AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
 1918     }
 1919     else
 1920     {
 1921       AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
 1922     }
 1923     ccb->ccb_h.status = CAM_REQ_CMP;
 1924     break;
 1925   }
 1926   case XPT_RESET_DEV:
 1927   {
 1928     ccb->ccb_h.status = CAM_REQ_CMP;
 1929     break;
 1930   }
 1931   case XPT_ABORT:
 1932   {
 1933     ccb->ccb_h.status = CAM_REQ_CMP;
 1934     break;
 1935   }
 1936 #if __FreeBSD_version >= 900026
 1937   case XPT_SMP_IO:
 1938   {
 1939     agtiapi_QueueSMP( pmcsc, ccb );
 1940     return;
 1941   }
 1942 #endif /* __FreeBSD_version >= 900026 */
 1943   case XPT_SCSI_IO:
 1944   {
 1945     if(pmcsc->dev_scan == agFALSE)
 1946     {
 1947        ccb->ccb_h.status = CAM_SEL_TIMEOUT;  
 1948        break;
 1949     }
 1950     if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
 1951     {
 1952       AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
 1953                       XPT_SCSI_IO );
 1954       ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 1955       break;
 1956     }
 1957     else
 1958     {
 1959       AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
 1960                   XPT_SCSI_IO );
 1961       agtiapi_QueueCmnd_( pmcsc, ccb );
 1962       return;
 1963     }
 1964   }
 1965 
 1966   case XPT_CALC_GEOMETRY:
 1967   {
 1968           cam_calc_geometry(&ccb->ccg, 1);
 1969           ccb->ccb_h.status = CAM_REQ_CMP;
 1970           break;
 1971   }       
 1972   default:
 1973   {
 1974     /*
 1975       XPT_SET_TRAN_SETTINGS     
 1976     */
 1977     AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
 1978                 ccb->ccb_h.func_code );
 1979     ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 1980     break;
 1981   }
 1982   } /* switch */
 1983   xpt_done(ccb);
 1984 }
 1985 
 1986 
 1987 /******************************************************************************
 1988 agtiapi_GetCCB()
 1989 
 1990 Purpose:
 1991   Get a ccb from free list or allocate a new one
 1992 Parameters:
 1993   struct agtiapi_softc *pmcsc (IN)  Pointer to HBA structure
 1994 Return:
 1995   Pointer to a ccb structure, or NULL if not available
 1996 Note:
 1997 ******************************************************************************/
 1998 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
 1999 {
 2000   pccb_t pccb;
 2001 
 2002   AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
 2003 
 2004   AG_LOCAL_LOCK( &pmcsc->ccbLock );
 2005 
 2006   /* get the ccb from the head of the free list */
 2007   if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
 2008   {
 2009     pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
 2010     pccb->pccbNext = NULL;
 2011     pccb->flags = ACTIVE;
 2012     pccb->startTime = 0;
 2013     pmcsc->activeCCB++;
 2014     AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
 2015   }
 2016   else
 2017   {
 2018     AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
 2019   }
 2020 
 2021   AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
 2022   return pccb;
 2023 }
 2024 
 2025 /******************************************************************************
 2026 agtiapi_QueueCmnd_()
 2027 
 2028 Purpose:
 2029   Calls for sending CCB and excuting on HBA.
 2030 Parameters:
 2031   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 2032   union ccb * ccb (IN)      Pointer to CAM ccb data structure
 2033 Return:
 2034   0 - Command is pending to execute
 2035   1 - Command returned without further process
 2036 Note:
 2037 ******************************************************************************/
 2038 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
 2039 {
 2040   struct ccb_scsiio *csio = &ccb->csio;
 2041   pccb_t     pccb = agNULL; // call dequeue
 2042   int        status = tiSuccess;
 2043   U32        Channel = CMND_TO_CHANNEL(ccb);
 2044   U32        TID     = CMND_TO_TARGET(ccb);
 2045   U32        LUN     = CMND_TO_LUN(ccb);
 2046 
 2047   AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
 2048 
 2049   /* no support for CBD > 16 */
 2050   if (csio->cdb_len > 16)
 2051   {
 2052     AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
 2053                     csio->cdb_len );
 2054     ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 2055     ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 2056     ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
 2057     xpt_done(ccb);
 2058     return tiError;
 2059   }
 2060   if (TID < 0 || TID >= maxTargets)
 2061   {
 2062     AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
 2063     ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 2064     ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 2065     ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
 2066     xpt_done(ccb);
 2067     return tiError;
 2068   }
 2069   /* get a ccb */
 2070   if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
 2071   {
 2072     AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
 2073     if (pmcsc != NULL)
 2074     {
 2075       ag_device_t *targ;
 2076       TID = INDEX(pmcsc, TID);
 2077       targ   = &pmcsc->pDevList[TID];
 2078       agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
 2079     }
 2080     ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 2081     ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 2082     ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 2083     xpt_done(ccb);
 2084     return tiBusy;
 2085   }
 2086   pccb->pmcsc = pmcsc;
 2087   /* initialize Command Control Block (CCB) */
 2088   pccb->targetId   = TID;
 2089   pccb->lun        = LUN;
 2090   pccb->channel    = Channel;
 2091   pccb->ccb        = ccb; /* for struct scsi_cmnd */
 2092   pccb->senseLen   = csio->sense_len;
 2093   pccb->startTime  = ticks;
 2094   pccb->pSenseData = (caddr_t) &csio->sense_data;
 2095   pccb->tiSuperScsiRequest.flags = 0;
 2096 
 2097   /* each channel is reserved for different addr modes */
 2098   pccb->addrMode = agtiapi_AddrModes[Channel];
 2099 
 2100   status = agtiapi_PrepareSGList(pmcsc, pccb);
 2101   if (status != tiSuccess)
 2102   {
 2103     AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
 2104     agtiapi_FreeCCB(pmcsc, pccb);
 2105     if (status == tiReject)
 2106     {
 2107       ccb->ccb_h.status = CAM_REQ_INVALID;
 2108     }
 2109     else
 2110     {
 2111       ccb->ccb_h.status = CAM_REQ_CMP;
 2112     }
 2113     xpt_done( ccb );
 2114     return tiError;
 2115   }
 2116   return status;
 2117 }
 2118 
 2119 /******************************************************************************
 2120 agtiapi_DumpCDB()
 2121 
 2122 Purpose:
 2123   Prints out CDB
 2124 Parameters:
 2125   const char *ptitle (IN)  A string to be printed
 2126   ccb_t *pccb (IN)         A pointer to the driver's own CCB, not CAM's CCB
 2127 Return:
 2128 Note:
 2129 ******************************************************************************/
 2130 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
 2131 {
 2132   union ccb *ccb;
 2133   struct ccb_scsiio *csio;
 2134   bit8  cdb[64];
 2135   int len;
 2136 
 2137   if (pccb == NULL)
 2138   {
 2139     printf( "agtiapi_DumpCDB: no pccb here \n" );
 2140     panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
 2141     return;
 2142   }
 2143   ccb = pccb->ccb;
 2144   if (ccb == NULL)
 2145   {
 2146     printf( "agtiapi_DumpCDB: no ccb here \n" );
 2147     panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
 2148            "called from %s\n",
 2149            pccb, pccb->ccb, pccb->flags, ptitle );
 2150     return;
 2151   }
 2152   csio = &ccb->csio;
 2153   if (csio == NULL)
 2154   {
 2155     printf( "agtiapi_DumpCDB: no csio here \n" );
 2156     panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
 2157            pccb, pccb->ccb, pccb->flags, ptitle );
 2158     return;
 2159   }
 2160   len = MIN(64, csio->cdb_len);
 2161   if (csio->ccb_h.flags & CAM_CDB_POINTER)
 2162   {
 2163     bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
 2164   }
 2165   else
 2166   {
 2167     bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
 2168   }
 2169 
 2170   AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
 2171               " len %d from %s\n",
 2172               pccb, cdb[0],
 2173               csio->cdb_len,
 2174               len,
 2175               ptitle );
 2176   return;
 2177 }
 2178 
 2179 /******************************************************************************
 2180 agtiapi_DoSoftReset()
 2181 
 2182 Purpose:
 2183   Do card reset
 2184 Parameters:
 2185   *data (IN)               point to pmcsc (struct agtiapi_softc *)
 2186 Return:
 2187 Note:
 2188 ******************************************************************************/
 2189 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
 2190 {
 2191   int  ret;
 2192   unsigned long flags;
 2193 
 2194   pmcsc->flags |=  AGTIAPI_SOFT_RESET;
 2195   AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
 2196   ret = agtiapi_ResetCard( pmcsc, &flags );
 2197   AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 2198                  
 2199   if( ret != AGTIAPI_SUCCESS )
 2200     return tiError;
 2201                 
 2202   return SUCCESS;
 2203 }
 2204 
 2205 /******************************************************************************
 2206 agtiapi_CheckIOTimeout()
 2207 
 2208 Purpose:
 2209   Timeout function for SCSI IO or TM 
 2210 Parameters:
 2211   *data (IN)               point to pCard (ag_card_t *)
 2212 Return:
 2213 Note:
 2214 ******************************************************************************/
 2215 STATIC void agtiapi_CheckIOTimeout(void *data)
 2216 {
 2217   U32       status = AGTIAPI_SUCCESS;
 2218   ccb_t *pccb;
 2219   struct agtiapi_softc *pmcsc;
 2220   pccb_t pccb_curr;
 2221   pccb_t pccb_next;
 2222   pmcsc = (struct agtiapi_softc *)data;
 2223 
 2224   //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
 2225 
 2226   //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
 2227 
 2228   pccb = (pccb_t)pmcsc->ccbChainList;
 2229 
 2230   /* if link is down, do nothing */
 2231   if ((pccb == NULL) || (pmcsc->activeCCB == 0))
 2232   {
 2233   //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
 2234     goto restart_timer;
 2235   }
 2236 
 2237   AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
 2238   if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
 2239     goto ext;
 2240 
 2241   pccb_curr = pccb;
 2242 
 2243   /* Walk thorugh the IO Chain linked list to find the pending io */
 2244   /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
 2245   while (pccb_curr != NULL)
 2246   {
 2247     /* start from 1st ccb in the chain */
 2248     pccb_next = pccb_curr->pccbChainNext;
 2249     if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
 2250         (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
 2251     {
 2252       //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
 2253     }
 2254     else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
 2255               !(pccb_curr->flags & TIMEDOUT) )
 2256     {
 2257       AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
 2258                       "function -- flags=%x startTime=%ld tdData = %p\n",
 2259                       pccb_curr, pccb_curr->flags, pccb->startTime,
 2260                       pccb_curr->tiIORequest.tdData );
 2261       pccb_curr->flags |= TIMEDOUT;
 2262       status = agtiapi_StartTM(pmcsc, pccb_curr);
 2263       if (status == AGTIAPI_SUCCESS)
 2264       {
 2265         AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
 2266                         "success\n" );
 2267         goto restart_timer;
 2268       }
 2269       else
 2270       {
 2271 #ifdef AGTIAPI_LOCAL_RESET
 2272         /* abort request did not go through */
 2273         AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
 2274         /* TODO: call Soft reset here */
 2275         AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
 2276                         "abort request did not go thru ==> soft reset#7, then "
 2277                         "restart timer\n" );
 2278         agtiapi_DoSoftReset (pmcsc);
 2279         goto restart_timer;
 2280 #endif
 2281       }
 2282     }
 2283     pccb_curr = pccb_next;
 2284   }
 2285 restart_timer:
 2286   callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
 2287 
 2288 ext:
 2289   AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
 2290   return;
 2291 }
 2292 
 2293 /******************************************************************************
 2294 agtiapi_StartTM()
 2295 
 2296 Purpose:
 2297   DDI calls for aborting outstanding IO command 
 2298 Parameters: 
 2299   struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted  
 2300   unsigned long flags (IN/out) spinlock flags used in locking from 
 2301                               calling layers
 2302 Return:
 2303   AGTIAPI_SUCCESS  - success
 2304   AGTIAPI_FAIL     - fail
 2305 ******************************************************************************/
 2306 int
 2307 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
 2308 {
 2309   ccb_t     *pTMccb = NULL;
 2310   U32       status = AGTIAPI_SUCCESS;
 2311   ag_device_t      *pDevice = NULL;
 2312   U32       TMstatus = tiSuccess;
 2313   AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
 2314                   pccb, pccb->flags );
 2315   if (pccb == NULL)
 2316   {
 2317     AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
 2318     status = AGTIAPI_SUCCESS;
 2319     goto ext;
 2320   }
 2321   if (!pccb->tiIORequest.tdData)
 2322   {
 2323     /* should not be the case */
 2324     AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
 2325                    "ERROR\n", pccb, pccb->flags, pccb->targetId);
 2326     status = AGTIAPI_FAIL;
 2327   }
 2328   else
 2329   {
 2330     /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
 2331        clear pending TM_ABORT_TASK */
 2332     /* Else Device State will not be put back to Operational, (refer FW) */
 2333     if (pccb->flags & TASK_MANAGEMENT)
 2334     {
 2335       if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
 2336       {
 2337         AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
 2338                         "TM failed\n" );
 2339         /* TODO: call Soft reset here */
 2340         AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
 2341                         "tiINIIOAbort() failed ==> soft reset#8\n" );
 2342         agtiapi_DoSoftReset( pCard );
 2343       }
 2344       else
 2345       {
 2346         AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
 2347                         "Request sent\n" );
 2348         status = AGTIAPI_SUCCESS; 
 2349       }
 2350     }
 2351     else
 2352     {
 2353       /* get a ccb */
 2354       if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
 2355       {
 2356         AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
 2357         status = AGTIAPI_FAIL;
 2358         goto ext;
 2359       }
 2360       pTMccb->pmcsc = pCard;
 2361       pTMccb->targetId = pccb->targetId;
 2362       pTMccb->devHandle = pccb->devHandle;
 2363       if (pTMccb->targetId >= pCard->devDiscover)
 2364       {
 2365         AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
 2366         status = AGTIAPI_FAIL;
 2367         goto ext;
 2368       }
 2369       if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
 2370       {
 2371         return AGTIAPI_FAIL;
 2372       }
 2373       if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
 2374       {
 2375         return AGTIAPI_FAIL;
 2376       }
 2377       pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
 2378       if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
 2379       {
 2380         return AGTIAPI_FAIL;
 2381       }
 2382 
 2383       /* save pending io to issue local abort at Task mgmt CB */
 2384       pTMccb->pccbIO = pccb;
 2385       AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
 2386                       "request !\n",
 2387                       pTMccb, pTMccb->flags, pTMccb->targetId );
 2388       pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
 2389       pTMccb->flags |= TASK_MANAGEMENT;
 2390       TMstatus = tiINITaskManagement(&pCard->tiRoot, 
 2391                               pccb->devHandle,
 2392                               AG_ABORT_TASK,
 2393                               &pccb->tiSuperScsiRequest.scsiCmnd.lun,
 2394                               &pccb->tiIORequest, 
 2395                               &pTMccb->tiIORequest); 
 2396       if (TMstatus == tiSuccess)
 2397       {
 2398         AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
 2399                         "%p, pTMccb %p\n", 
 2400                         pccb, pTMccb );
 2401         pTMccb->startTime = ticks;
 2402         status = AGTIAPI_SUCCESS; 
 2403       }
 2404       else if (TMstatus == tiIONoDevice)
 2405       {
 2406         AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
 2407                         "%p, pTMccb %p\n", 
 2408                         pccb, pTMccb );
 2409         status = AGTIAPI_SUCCESS; 
 2410       }
 2411       else
 2412       {
 2413         AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
 2414                         "pTMccb %p\n", 
 2415                         pccb, pTMccb );
 2416         status = AGTIAPI_FAIL;
 2417         agtiapi_FreeTMCCB(pCard, pTMccb);
 2418         /* TODO */
 2419         /* call TM_TARGET_RESET */
 2420       }
 2421     }
 2422   }
 2423   ext:
 2424   AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status, 
 2425                  (pccb) ? pccb->flags : -1);
 2426   return status;
 2427 } /* agtiapi_StartTM */
 2428 
 2429 #if __FreeBSD_version > 901000
 2430 /******************************************************************************
 2431 agtiapi_PrepareSGList()
 2432 
 2433 Purpose:
 2434   This function prepares scatter-gather list for the given ccb
 2435 Parameters:
 2436   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 2437   ccb_t *pccb (IN)      A pointer to the driver's own CCB, not CAM's CCB
 2438 Return:
 2439   0 - success
 2440   1 - failure
 2441 
 2442 Note:
 2443 ******************************************************************************/
 2444 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 2445 {
 2446   union ccb *ccb = pccb->ccb;
 2447   struct ccb_scsiio *csio = &ccb->csio;
 2448   struct ccb_hdr *ccbh = &ccb->ccb_h;
 2449   AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
 2450 
 2451 //  agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
 2452   AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
 2453 
 2454   if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) 
 2455   {
 2456         switch((ccbh->flags & CAM_DATA_MASK))
 2457         {
 2458           int error;
 2459           struct bus_dma_segment seg;
 2460           case CAM_DATA_VADDR:
 2461         /* Virtual address that needs to translated into one or more physical address ranges. */
 2462           //  int error;
 2463             //  AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
 2464             AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
 2465             error = bus_dmamap_load( pmcsc->buffer_dmat,
 2466                                  pccb->CCB_dmamap,
 2467                                  csio->data_ptr,
 2468                                  csio->dxfer_len,
 2469                                  agtiapi_PrepareSGListCB,
 2470                                  pccb,
 2471                                  BUS_DMA_NOWAIT/* 0 */ );
 2472             //  AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
 2473 
 2474             if (error == EINPROGRESS) 
 2475             {
 2476           /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
 2477           AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
 2478           xpt_freeze_simq(pmcsc->sim, 1);
 2479           pmcsc->SimQFrozen = agTRUE;     
 2480           ccbh->status |= CAM_RELEASE_SIMQ;
 2481         }
 2482         break;
 2483         case CAM_DATA_PADDR:
 2484             /* We have been given a pointer to single physical buffer. */
 2485             /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
 2486           //struct bus_dma_segment seg;
 2487           AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
 2488           seg.ds_addr =
 2489             (bus_addr_t)(vm_offset_t)csio->data_ptr;
 2490              seg.ds_len = csio->dxfer_len;
 2491              // * 0xFF to be defined
 2492              agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
 2493              break;
 2494         default:
 2495            AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
 2496            return tiReject;
 2497     }
 2498   }
 2499   else 
 2500   {
 2501     agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
 2502   }
 2503   return tiSuccess;
 2504 }
 2505 #else
 2506 /******************************************************************************
 2507 agtiapi_PrepareSGList()
 2508 
 2509 Purpose:
 2510   This function prepares scatter-gather list for the given ccb
 2511 Parameters:
 2512   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 2513   ccb_t *pccb (IN)      A pointer to the driver's own CCB, not CAM's CCB
 2514 Return:
 2515   0 - success
 2516   1 - failure
 2517 
 2518 Note:
 2519 ******************************************************************************/
 2520 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 2521 {
 2522   union ccb *ccb = pccb->ccb;
 2523   struct ccb_scsiio *csio = &ccb->csio;
 2524   struct ccb_hdr *ccbh = &ccb->ccb_h;
 2525   AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
 2526 //  agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
 2527   AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
 2528 
 2529   if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
 2530   {
 2531     if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
 2532     {
 2533       /* We've been given a pointer to a single buffer. */
 2534       if ((ccbh->flags & CAM_DATA_PHYS) == 0) 
 2535       {
 2536         /* Virtual address that needs to translated into one or more physical address ranges. */
 2537         int error;
 2538       //  AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
 2539         AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
 2540         error = bus_dmamap_load( pmcsc->buffer_dmat,
 2541                                  pccb->CCB_dmamap,
 2542                                  csio->data_ptr,
 2543                                  csio->dxfer_len,
 2544                                  agtiapi_PrepareSGListCB,
 2545                                  pccb,
 2546                                  BUS_DMA_NOWAIT/* 0 */ );
 2547       //  AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
 2548 
 2549             if (error == EINPROGRESS) 
 2550             {
 2551           /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
 2552           AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
 2553           xpt_freeze_simq(pmcsc->sim, 1);
 2554           pmcsc->SimQFrozen = agTRUE;     
 2555           ccbh->status |= CAM_RELEASE_SIMQ;
 2556         }
 2557       }
 2558       else
 2559       {
 2560             /* We have been given a pointer to single physical buffer. */
 2561             /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
 2562         struct bus_dma_segment seg;
 2563         AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
 2564         seg.ds_addr =
 2565           (bus_addr_t)(vm_offset_t)csio->data_ptr;
 2566         seg.ds_len = csio->dxfer_len;
 2567         // * 0xFF to be defined
 2568         agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
 2569       }
 2570     }
 2571     else
 2572     {
 2573       
 2574       AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
 2575       return tiReject;
 2576     }
 2577   }
 2578   else 
 2579   {
 2580     agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
 2581   }
 2582   return tiSuccess;
 2583 }
 2584 
 2585 #endif
 2586 /******************************************************************************
 2587 agtiapi_PrepareSGListCB()
 2588 
 2589 Purpose:
 2590   Callback function for bus_dmamap_load()
 2591   This fuctions sends IO to LL layer.
 2592 Parameters:
 2593   void *arg (IN)                Pointer to the HBA data structure
 2594   bus_dma_segment_t *segs (IN)  Pointer to dma segment
 2595   int nsegs (IN)                number of dma segment
 2596   int error (IN)                error
 2597 Return:
 2598 Note:
 2599 ******************************************************************************/
 2600 static void agtiapi_PrepareSGListCB( void *arg,
 2601                                      bus_dma_segment_t *segs,
 2602                                      int nsegs,
 2603                                      int error )
 2604 {
 2605   pccb_t     pccb = arg;
 2606   union ccb *ccb = pccb->ccb;
 2607   struct ccb_scsiio *csio = &ccb->csio;
 2608 
 2609   struct agtiapi_softc *pmcsc;
 2610   tiIniScsiCmnd_t *pScsiCmnd;
 2611   bit32 i;
 2612   bus_dmasync_op_t op;
 2613   U32_64     phys_addr;
 2614   U08        *CDB; 
 2615   int        io_is_encryptable = 0;
 2616   unsigned long long start_lba = 0;
 2617   ag_device_t *pDev;
 2618   U32        TID     = CMND_TO_TARGET(ccb);
 2619 
 2620   AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
 2621               nsegs, error );
 2622   pmcsc = pccb->pmcsc;
 2623  
 2624   if (error != tiSuccess)
 2625   {
 2626     if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
 2627     {
 2628       // do nothing
 2629     }
 2630     else
 2631     {
 2632       AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
 2633       bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 2634       agtiapi_FreeCCB(pmcsc, pccb);
 2635       if (error == EFBIG)
 2636         ccb->ccb_h.status = CAM_REQ_TOO_BIG;
 2637       else
 2638         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 2639       xpt_done(ccb);
 2640       return;
 2641     }
 2642   }
 2643 
 2644   if (nsegs > AGTIAPI_MAX_DMA_SEGS)
 2645   {
 2646     AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
 2647                     " AGTIAPI_MAX_DMA_SEGS %d\n", 
 2648                     nsegs, AGTIAPI_MAX_DMA_SEGS );
 2649     bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 2650     agtiapi_FreeCCB(pmcsc, pccb);
 2651     ccb->ccb_h.status = CAM_REQ_TOO_BIG;
 2652     xpt_done(ccb);   
 2653     return;
 2654   }
 2655 
 2656 
 2657   /* fill in IO information */
 2658   pccb->dataLen = csio->dxfer_len;
 2659 
 2660   /* start fill in sgl structure */
 2661   if (nsegs == 1 && error == 0xAABBCCDD)
 2662   {
 2663     /* to be tested */
 2664     /* A single physical buffer */
 2665     AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
 2666     CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
 2667     pccb->tiSuperScsiRequest.agSgl1.len   = htole32(pccb->dataLen);
 2668     pccb->tiSuperScsiRequest.agSgl1.type  = htole32(tiSgl);
 2669     pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
 2670     pccb->numSgElements = 1;
 2671   }
 2672   else if (nsegs == 0 && error == 0xAAAAAAAA)
 2673   {
 2674     /* no data transfer */
 2675     AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
 2676     pccb->tiSuperScsiRequest.agSgl1.len = 0;
 2677     pccb->dataLen = 0; 
 2678     pccb->numSgElements = 0;  
 2679   }
 2680   else
 2681   {
 2682     /* virtual/logical buffer */
 2683     if (nsegs == 1)
 2684     {
 2685       pccb->dataLen = segs[0].ds_len;
 2686 
 2687       CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);     
 2688       pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
 2689       pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
 2690       pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
 2691       pccb->numSgElements = nsegs;            
 2692                                         
 2693     }
 2694     else
 2695     {    
 2696       pccb->dataLen = 0;
 2697       /* loop */
 2698       for (i = 0; i < nsegs; i++)
 2699       {
 2700         pccb->sgList[i].len = htole32(segs[i].ds_len);
 2701         CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);     
 2702         pccb->sgList[i].type = htole32(tiSgl);
 2703         pccb->dataLen += segs[i].ds_len;
 2704 
 2705       } /* for */
 2706       pccb->numSgElements = nsegs;
 2707       /* set up sgl buffer address */      
 2708       CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1,  pccb->tisgl_busaddr);
 2709       pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
 2710       pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
 2711       pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
 2712       pccb->numSgElements = nsegs;  
 2713     } /* else */
 2714   }
 2715 
 2716   /* set data transfer direction */
 2717   if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 
 2718   {
 2719     op = BUS_DMASYNC_PREWRITE;
 2720     pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
 2721   }
 2722   else 
 2723   {
 2724     op = BUS_DMASYNC_PREREAD;
 2725     pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
 2726   }
 2727 
 2728   pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
 2729 
 2730   pScsiCmnd->expDataLength = pccb->dataLen;
 2731 
 2732   if (csio->ccb_h.flags & CAM_CDB_POINTER)
 2733   {
 2734     bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
 2735   }
 2736   else
 2737   {
 2738     bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
 2739   }
 2740 
 2741   CDB = &pScsiCmnd->cdb[0];
 2742 
 2743   switch (CDB[0])
 2744   {
 2745   case REQUEST_SENSE:  /* requires different buffer */
 2746     /* This code should not be excercised because SAS support auto sense 
 2747        For the completeness, vtophys() is still used here.
 2748      */
 2749     AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
 2750     pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
 2751     phys_addr = vtophys(&csio->sense_data);
 2752     CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
 2753     pccb->tiSuperScsiRequest.agSgl1.type  = htole32(tiSgl);
 2754     pccb->dataLen = pccb->senseLen;
 2755     pccb->numSgElements = 1;
 2756     break;
 2757   case INQUIRY:
 2758     /* only using lun 0 for device type detection */
 2759     pccb->flags |= AGTIAPI_INQUIRY;
 2760     break;
 2761   case TEST_UNIT_READY:
 2762   case RESERVE:
 2763   case RELEASE:
 2764   case START_STOP:
 2765         pccb->tiSuperScsiRequest.agSgl1.len = 0;
 2766     pccb->dataLen = 0;
 2767     break;
 2768   case READ_6:
 2769   case WRITE_6:
 2770     /* Extract LBA */
 2771     start_lba = ((CDB[1] & 0x1f) << 16) |
 2772                  (CDB[2] << 8)          |
 2773                  (CDB[3]);
 2774 #ifdef HIALEAH_ENCRYPTION
 2775     io_is_encryptable = 1;
 2776 #endif
 2777     break;
 2778   case READ_10:
 2779   case WRITE_10:
 2780   case READ_12:
 2781   case WRITE_12:
 2782     /* Extract LBA */
 2783     start_lba = (CDB[2] << 24) |
 2784                 (CDB[3] << 16) |
 2785                 (CDB[4] << 8)  |
 2786                 (CDB[5]);
 2787 #ifdef HIALEAH_ENCRYPTION
 2788     io_is_encryptable = 1;
 2789 #endif
 2790     break;
 2791   case READ_16:
 2792   case WRITE_16:
 2793     /* Extract LBA */
 2794     start_lba = (CDB[2] << 24) |
 2795                 (CDB[3] << 16) |
 2796                 (CDB[4] << 8)  |
 2797                 (CDB[5]);
 2798     start_lba <<= 32;
 2799     start_lba |= ((CDB[6] << 24) |
 2800                   (CDB[7] << 16) |
 2801                   (CDB[8] << 8)  |
 2802                   (CDB[9]));
 2803 #ifdef HIALEAH_ENCRYPTION
 2804     io_is_encryptable = 1;
 2805 #endif
 2806     break;
 2807   default:
 2808     break;
 2809   }
 2810 
 2811   /* fill device lun based one address mode */
 2812   agtiapi_SetLunField(pccb);
 2813 
 2814   if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
 2815   {
 2816     pccb->ccbStatus   = tiIOFailed;
 2817     pccb->scsiStatus  = tiDetailNoLogin;
 2818     agtiapi_FreeCCB(pmcsc, pccb);
 2819     ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
 2820     xpt_done(ccb);
 2821     pccb->ccb         = NULL;
 2822     return;
 2823   }
 2824   if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
 2825   {
 2826     pccb->ccbStatus   = tiIOFailed;
 2827     pccb->scsiStatus  = tiDetailNoLogin;
 2828     agtiapi_FreeCCB(pmcsc, pccb);
 2829     ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
 2830     xpt_done(ccb);
 2831     pccb->ccb         = NULL;
 2832     return;
 2833   }
 2834   pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
 2835 
 2836 #if 1 
 2837   if ((pmcsc->flags & EDC_DATA) &&
 2838       (pDev->flags & EDC_DATA))
 2839   {
 2840     /*
 2841      * EDC support:
 2842      *
 2843      * Possible command supported -
 2844      * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
 2845      * READ_DEFECT_DATA, etc.
 2846      * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2, 
 2847      * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
 2848      *
 2849      * Do some data length adjustment and set chip operation instruction.
 2850      */
 2851     switch (CDB[0])
 2852     {
 2853       case READ_6:
 2854       case READ_10:
 2855       case READ_12:
 2856       case READ_16:
 2857         //  BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
 2858 #ifdef AGTIAPI_TEST_DIF
 2859         pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
 2860 #endif
 2861         pccb->flags |= EDC_DATA;
 2862 
 2863 #ifdef TEST_VERIFY_AND_FORWARD
 2864         pccb->tiSuperScsiRequest.Dif.flags =
 2865           DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
 2866         if(pDev->sector_size == 520) {
 2867             pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
 2868         } else if(pDev->sector_size == 4104) {
 2869             pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
 2870         }
 2871 #else
 2872 #ifdef AGTIAPI_TEST_DIF
 2873         pccb->tiSuperScsiRequest.Dif.flags =
 2874           DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
 2875 #endif
 2876 #endif
 2877 #ifdef AGTIAPI_TEST_DIF
 2878         switch(pDev->sector_size) {
 2879             case 528:
 2880                 pccb->tiSuperScsiRequest.Dif.flags |=
 2881                   ( DIF_BLOCK_SIZE_520 << 16 );
 2882                 break;
 2883             case 4104:
 2884                 pccb->tiSuperScsiRequest.Dif.flags |=
 2885                   ( DIF_BLOCK_SIZE_4096 << 16 );
 2886                 break;
 2887             case 4168:
 2888                 pccb->tiSuperScsiRequest.Dif.flags |=
 2889                   ( DIF_BLOCK_SIZE_4160 << 16 );
 2890                 break;
 2891         }
 2892 
 2893         if(pCard->flags & EDC_DATA_CRC)
 2894             pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
 2895 
 2896         /* Turn on upper 4 bits of UVM */
 2897         pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
 2898 
 2899 #endif
 2900 #ifdef AGTIAPI_TEST_DPL
 2901         if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
 2902             printk(KERN_ERR "SetupDifPerLA Failed.\n");
 2903             cmnd->result = SCSI_HOST(DID_ERROR);
 2904             goto err;
 2905         }
 2906         pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;        
 2907 #endif
 2908 #ifdef AGTIAPI_TEST_DIF
 2909         /* Set App Tag */
 2910         pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
 2911         pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
 2912 
 2913         /* Set LBA in UDT array */
 2914         if(CDB[0] == READ_6) {
 2915             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
 2916             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
 2917             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
 2918             pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
 2919         } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
 2920             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
 2921             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
 2922             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
 2923             pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
 2924         } else if(CDB[0] == READ_16) {
 2925             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
 2926             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
 2927             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
 2928             pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
 2929             /* Note: 32 bits lost */
 2930         }
 2931 #endif
 2932 
 2933         break;
 2934       case WRITE_6:
 2935       case WRITE_10:
 2936       case WRITE_12:
 2937       case WRITE_16:
 2938         //   BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
 2939         pccb->flags |= EDC_DATA;
 2940 #ifdef AGTIAPI_TEST_DIF
 2941         pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
 2942         pccb->tiSuperScsiRequest.Dif.flags =
 2943           DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
 2944         switch(pDev->sector_size) {
 2945             case 528:
 2946                 pccb->tiSuperScsiRequest.Dif.flags |=
 2947                   (DIF_BLOCK_SIZE_520 << 16);
 2948                 break;
 2949             case 4104:
 2950                 pccb->tiSuperScsiRequest.Dif.flags |=
 2951                   ( DIF_BLOCK_SIZE_4096 << 16 );
 2952                 break;
 2953             case 4168:
 2954                 pccb->tiSuperScsiRequest.Dif.flags |=
 2955                   ( DIF_BLOCK_SIZE_4160 << 16 );
 2956                 break;
 2957         }
 2958 
 2959         /* Turn on upper 4 bits of UUM */
 2960         pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
 2961 #endif
 2962 #ifdef AGTIAPI_TEST_DPL
 2963         if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
 2964             printk(KERN_ERR "SetupDifPerLA Failed.\n");
 2965             cmnd->result = SCSI_HOST(DID_ERROR);
 2966             goto err;
 2967         }
 2968         pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
 2969 #endif
 2970 #ifdef AGTIAPI_TEST_DIF
 2971         /* Set App Tag */
 2972         pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
 2973         pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
 2974 
 2975         /* Set LBA in UDT array */
 2976         if(CDB[0] == WRITE_6) {
 2977             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
 2978             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
 2979             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
 2980         } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
 2981             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
 2982             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
 2983             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
 2984             pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
 2985         } else if(CDB[0] == WRITE_16) {
 2986             pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
 2987             pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
 2988             pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
 2989             pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
 2990             /* Note: 32 bits lost */
 2991         }
 2992 #endif
 2993         break;
 2994     }
 2995   }
 2996 #endif /* end of DIF */
 2997 
 2998   if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
 2999   {
 3000     switch(csio->tag_action)
 3001     {
 3002     case MSG_HEAD_OF_Q_TAG:
 3003       pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
 3004       break;
 3005     case MSG_ACA_TASK:
 3006       pScsiCmnd->taskAttribute = TASK_ACA;
 3007       break;
 3008     case MSG_ORDERED_Q_TAG:
 3009       pScsiCmnd->taskAttribute = TASK_ORDERED;
 3010       break;
 3011     case MSG_SIMPLE_Q_TAG: /* fall through */
 3012     default:
 3013       pScsiCmnd->taskAttribute = TASK_SIMPLE;
 3014       break;
 3015     }
 3016   }
 3017 
 3018   if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
 3019   {
 3020     /* should be just before start IO */
 3021     bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
 3022   }
 3023 
 3024   /*
 3025    * If assigned pDevHandle is not available
 3026    * then there is no need to send it to StartIO()
 3027    */
 3028   if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
 3029   {
 3030     pccb->ccbStatus   = tiIOFailed;
 3031     pccb->scsiStatus  = tiDetailNoLogin;
 3032     agtiapi_FreeCCB(pmcsc, pccb);
 3033     ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
 3034     xpt_done(ccb);
 3035     pccb->ccb         = NULL;
 3036     return;
 3037   }
 3038   TID = INDEX(pmcsc, pccb->targetId);
 3039   if ((TID >= pmcsc->devDiscover) ||
 3040       !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
 3041   {
 3042     /*
 3043     AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
 3044                     " target %d tid %d/%d card %p ERROR pccb %p\n",
 3045                     pccb->devHandle, pccb->targetId, TID,
 3046                     pmcsc->devDiscover, pmcsc, pccb );
 3047     */
 3048     pccb->ccbStatus   = tiIOFailed;
 3049     pccb->scsiStatus  = tiDetailNoLogin;
 3050     agtiapi_FreeCCB(pmcsc, pccb);
 3051     ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
 3052     xpt_done(ccb);
 3053     pccb->ccb         = NULL;
 3054     return;
 3055   }
 3056   AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
 3057                   "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
 3058                   pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
 3059                   pmcsc );
 3060 #ifdef HIALEAH_ENCRYPTION
 3061   if(pmcsc->encrypt && io_is_encryptable) {
 3062     agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
 3063   } else{
 3064         io_is_encryptable = 0;
 3065         pccb->tiSuperScsiRequest.flags = 0;
 3066   }
 3067 #endif
 3068   // put the request in send queue
 3069   agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
 3070                     AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
 3071   agtiapi_StartIO(pmcsc);
 3072   return;
 3073 }
 3074 
 3075 /******************************************************************************
 3076 agtiapi_StartIO()
 3077 
 3078 Purpose:
 3079   Send IO request down for processing.
 3080 Parameters:
 3081   (struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 3082 Return:
 3083 Note:
 3084 ******************************************************************************/
 3085 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
 3086 {
 3087   ccb_t *pccb;
 3088   int TID;                      
 3089   ag_device_t *targ;    
 3090 
 3091   AGTIAPI_IO( "agtiapi_StartIO: start\n" );
 3092 
 3093   AG_LOCAL_LOCK( &pmcsc->sendLock );
 3094   pccb = pmcsc->ccbSendHead;
 3095 
 3096   /* if link is down, do nothing */
 3097   if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
 3098   {
 3099     AG_LOCAL_UNLOCK( &pmcsc->sendLock );
 3100     AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
 3101     goto ext;
 3102   }
 3103 
 3104 
 3105  if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
 3106   {
 3107       TID = INDEX(pmcsc, pccb->targetId);
 3108       targ   = &pmcsc->pDevList[TID];
 3109   }
 3110 
 3111 
 3112   /* clear send queue */
 3113   pmcsc->ccbSendHead = NULL;
 3114   pmcsc->ccbSendTail = NULL;
 3115   AG_LOCAL_UNLOCK( &pmcsc->sendLock );
 3116 
 3117   /* send all ccbs down */
 3118   while (pccb) 
 3119   {
 3120     pccb_t pccb_next;
 3121     U32    status;
 3122 
 3123     pccb_next = pccb->pccbNext;
 3124     pccb->pccbNext = NULL;
 3125 
 3126     if (!pccb->ccb)
 3127     {
 3128       AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
 3129       pccb = pccb_next;
 3130       continue;
 3131     }
 3132     AG_IO_DUMPCCB( pccb );
 3133 
 3134     if (!pccb->devHandle)
 3135     {
 3136       agtiapi_DumpCCB( pccb );
 3137       AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
 3138       pccb = pccb_next;
 3139       continue;
 3140     }
 3141     AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
 3142 
 3143 #ifndef ABORT_TEST
 3144     if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
 3145         !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
 3146     {
 3147       AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n", 
 3148                       pccb->devHandle );
 3149       if( pccb->devHandle ) {
 3150         AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
 3151                         " -- osData:%p\n",
 3152                         pccb->devHandle->osData );
 3153         if( pccb->devHandle->osData ) {
 3154           AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
 3155                           " -- active flag:%d\n",
 3156                           ( (ag_device_t *)
 3157                             (pccb->devHandle->osData))->flags & ACTIVE );
 3158         }
 3159       }
 3160       pccb->ccbStatus  = tiIOFailed;
 3161       pccb->scsiStatus = tiDetailNoLogin;
 3162       agtiapi_Done( pmcsc, pccb );
 3163       pccb = pccb_next;
 3164       continue;
 3165     }
 3166 #endif
 3167 
 3168 #ifdef FAST_IO_TEST
 3169     status = agtiapi_FastIOTest( pmcsc, pccb );
 3170 #else
 3171     status = tiINISuperIOStart( &pmcsc->tiRoot, 
 3172                                 &pccb->tiIORequest,
 3173                                 pccb->devHandle, 
 3174                                 &pccb->tiSuperScsiRequest,
 3175                                 (void *)&pccb->tdIOReqBody,
 3176                                 tiInterruptContext );
 3177 #endif
 3178     switch( status )
 3179     {
 3180       case tiSuccess:
 3181         /*
 3182         static int squelchCount = 0;
 3183         if ( 200000 == squelchCount++ ) // squelch prints
 3184         {
 3185           AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
 3186                           pccb );
 3187           squelchCount = 0; // reset count
 3188         }
 3189         */
 3190 
 3191  
 3192         break;   
 3193       case tiDeviceBusy:
 3194         AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
 3195                         pccb->ccb );
 3196 #ifdef LOGEVENT 
 3197         agtiapi_LogEvent( pmcsc,
 3198                           IOCTL_EVT_SEV_INFORMATIONAL,
 3199                           0,
 3200                           agNULL,
 3201                           0,
 3202                           "tiINIIOStart tiDeviceBusy " );
 3203 #endif
 3204         pccb->ccbStatus = tiIOFailed;
 3205         pccb->scsiStatus = tiDeviceBusy;        
 3206         agtiapi_Done(pmcsc, pccb);
 3207         break;
 3208       case tiBusy:
 3209         
 3210         AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
 3211                         pccb->ccb );
 3212 #ifdef LOGEVENT 
 3213         agtiapi_LogEvent( pmcsc,
 3214                           IOCTL_EVT_SEV_INFORMATIONAL,
 3215                           0,
 3216                           agNULL,
 3217                           0,
 3218                           "tiINIIOStart tiBusy " );
 3219 #endif
 3220 
 3221         pccb->ccbStatus = tiIOFailed;
 3222         pccb->scsiStatus = tiBusy;        
 3223         agtiapi_Done(pmcsc, pccb);
 3224 
 3225         break;
 3226       case tiIONoDevice:
 3227         AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
 3228                         "ERROR\n", pccb->ccb );
 3229 #ifdef LOGEVENT
 3230         agtiapi_LogEvent( pmcsc,
 3231                           IOCTL_EVT_SEV_INFORMATIONAL,
 3232                           0,
 3233                           agNULL,
 3234                           0,
 3235                           "tiINIIOStart invalid device handle " );
 3236 #endif
 3237 #ifndef ABORT_TEST
 3238         /* return command back to OS due to no device available */
 3239         ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
 3240         pccb->ccbStatus  = tiIOFailed;
 3241         pccb->scsiStatus = tiDetailNoLogin;
 3242         agtiapi_Done(pmcsc, pccb);
 3243 #else
 3244         /* for short cable pull, we want IO retried - 3-18-2005 */
 3245         agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
 3246                          AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb); 
 3247 #endif
 3248         break;
 3249       case tiError:
 3250         AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
 3251                        pccb->ccb);
 3252 #ifdef LOGEVENT
 3253         agtiapi_LogEvent(pmcsc, 
 3254                          IOCTL_EVT_SEV_INFORMATIONAL, 
 3255                          0, 
 3256                          agNULL, 
 3257                          0, 
 3258                          "tiINIIOStart tiError ");
 3259 #endif
 3260         pccb->ccbStatus  = tiIOFailed;
 3261         pccb->scsiStatus = tiDetailOtherError;
 3262         agtiapi_Done(pmcsc, pccb);
 3263         break;
 3264       default:
 3265         AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
 3266                        status, pccb->ccb);
 3267 #ifdef LOGEVENT
 3268         agtiapi_LogEvent(pmcsc, 
 3269                          IOCTL_EVT_SEV_ERROR, 
 3270                          0, 
 3271                          agNULL, 
 3272                          0, 
 3273                          "tiINIIOStart unexpected status ");
 3274 #endif
 3275         pccb->ccbStatus  = tiIOFailed;
 3276         pccb->scsiStatus = tiDetailOtherError;
 3277         agtiapi_Done(pmcsc, pccb);
 3278     }
 3279     
 3280     pccb = pccb_next;
 3281   }
 3282 ext:
 3283   /* some IO requests might have been completed */
 3284   AG_GET_DONE_PCCB(pccb, pmcsc);
 3285   return;
 3286 }
 3287 
 3288 /******************************************************************************
 3289 agtiapi_StartSMP()
 3290 
 3291 Purpose:
 3292   Send SMP request down for processing.
 3293 Parameters:
 3294   (struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 3295 Return:
 3296 Note:
 3297 ******************************************************************************/
 3298 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
 3299 {
 3300   ccb_t *pccb;
 3301 
 3302   AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
 3303 
 3304   AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
 3305   pccb = pmcsc->smpSendHead;
 3306 
 3307   /* if link is down, do nothing */
 3308   if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
 3309   {
 3310     AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
 3311     AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
 3312     goto ext;
 3313   }
 3314 
 3315   /* clear send queue */
 3316   pmcsc->smpSendHead = NULL;
 3317   pmcsc->smpSendTail = NULL;
 3318   AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
 3319 
 3320   /* send all ccbs down */
 3321   while (pccb)
 3322   {
 3323     pccb_t pccb_next;
 3324     U32    status;
 3325 
 3326     pccb_next = pccb->pccbNext;
 3327     pccb->pccbNext = NULL;
 3328 
 3329     if (!pccb->ccb)
 3330     {
 3331       AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
 3332       pccb = pccb_next;
 3333       continue;
 3334     }
 3335 
 3336     if (!pccb->devHandle)
 3337     {
 3338       AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
 3339       pccb = pccb_next;
 3340       continue;
 3341     }
 3342     pccb->flags |= TAG_SMP; // mark as SMP for later tracking
 3343     AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
 3344                     pccb, pccb->retryCount );
 3345     status = tiINISMPStart( &pmcsc->tiRoot, 
 3346                             &pccb->tiIORequest,
 3347                             pccb->devHandle, 
 3348                             &pccb->tiSMPFrame,
 3349                             (void *)&pccb->tdIOReqBody,
 3350                             tiInterruptContext);
 3351 
 3352     switch (status)
 3353     {
 3354     case tiSuccess:
 3355       break;
 3356     case tiBusy:
 3357       AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
 3358                      pccb->ccb);
 3359       /* pending ccb back to send queue */
 3360       agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
 3361                        AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
 3362       break;
 3363     case tiError:
 3364       AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
 3365                      pccb->ccb);
 3366       pccb->ccbStatus = tiSMPFailed;
 3367       agtiapi_SMPDone(pmcsc, pccb);
 3368       break;
 3369     default:
 3370       AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
 3371                      status, pccb->ccb);
 3372       pccb->ccbStatus = tiSMPFailed;
 3373       agtiapi_SMPDone(pmcsc, pccb);
 3374     }
 3375 
 3376     pccb = pccb_next;
 3377   }
 3378   ext:
 3379   /* some SMP requests might have been completed */
 3380   AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
 3381 
 3382   return;
 3383 }
 3384 
 3385 #if __FreeBSD_version > 901000
 3386 /******************************************************************************
 3387 agtiapi_PrepareSMPSGList()
 3388 
 3389 Purpose:
 3390   This function prepares scatter-gather list for the given ccb
 3391 Parameters:
 3392   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 3393   ccb_t *pccb (IN)      A pointer to the driver's own CCB, not CAM's CCB
 3394 Return:
 3395   0 - success
 3396   1 - failure
 3397 
 3398 Note:
 3399 ******************************************************************************/
 3400 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
 3401 {
 3402   /* Pointer to CAM's ccb */
 3403   union ccb *ccb = pccb->ccb;
 3404   struct ccb_smpio *csmpio = &ccb->smpio;
 3405   struct ccb_hdr *ccbh = &ccb->ccb_h;
 3406 
 3407   AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
 3408   switch((ccbh->flags & CAM_DATA_MASK))
 3409   {
 3410     case CAM_DATA_PADDR:
 3411     case CAM_DATA_SG_PADDR:
 3412       AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
 3413       ccb->ccb_h.status = CAM_REQ_INVALID;
 3414       xpt_done(ccb);
 3415       return tiReject;
 3416     case CAM_DATA_SG:
 3417 
 3418     /* 
 3419      * Currently we do not support Multiple SG list 
 3420      * return error for now 
 3421      */
 3422       if ( (csmpio->smp_request_sglist_cnt > 1)
 3423            || (csmpio->smp_response_sglist_cnt > 1) )
 3424       {
 3425         AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
 3426         ccb->ccb_h.status = CAM_REQ_INVALID;
 3427         xpt_done(ccb);
 3428         return tiReject;
 3429       }
 3430     }
 3431     if ( csmpio->smp_request_sglist_cnt != 0 )
 3432     {
 3433       /* 
 3434        * Virtual address that needs to translated into
 3435        * one or more physical address ranges.
 3436        */
 3437       int error;
 3438       //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));  
 3439       AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
 3440       error = bus_dmamap_load( pmcsc->buffer_dmat,
 3441                                pccb->CCB_dmamap, 
 3442                                csmpio->smp_request, 
 3443                                csmpio->smp_request_len,
 3444                                agtiapi_PrepareSMPSGListCB, 
 3445                                pccb, 
 3446                                BUS_DMA_NOWAIT /* 0 */ );
 3447       
 3448       //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));  
 3449 
 3450       if (error == EINPROGRESS)
 3451       {
 3452         /*
 3453          * So as to maintain ordering,
 3454          * freeze the controller queue
 3455          * until our mapping is
 3456          * returned.
 3457          */
 3458         AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
 3459         xpt_freeze_simq( pmcsc->sim, 1 );
 3460         pmcsc->SimQFrozen = agTRUE;     
 3461         ccbh->status |= CAM_RELEASE_SIMQ;
 3462       }
 3463     }
 3464     if( csmpio->smp_response_sglist_cnt != 0 )
 3465     {
 3466       /*
 3467        * Virtual address that needs to translated into
 3468        * one or more physical address ranges.
 3469        */
 3470       int error;
 3471       //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );  
 3472       AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
 3473       error = bus_dmamap_load( pmcsc->buffer_dmat,
 3474                                pccb->CCB_dmamap, 
 3475                                csmpio->smp_response, 
 3476                                csmpio->smp_response_len,
 3477                                agtiapi_PrepareSMPSGListCB, 
 3478                                pccb, 
 3479                                BUS_DMA_NOWAIT /* 0 */ );
 3480       
 3481       //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
 3482 
 3483       if ( error == EINPROGRESS )
 3484       {
 3485         /*
 3486          * So as to maintain ordering,
 3487          * freeze the controller queue
 3488          * until our mapping is
 3489          * returned.
 3490          */
 3491         AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
 3492         xpt_freeze_simq( pmcsc->sim, 1 );
 3493         pmcsc->SimQFrozen = agTRUE;     
 3494         ccbh->status |= CAM_RELEASE_SIMQ;
 3495       }
 3496     }
 3497  
 3498   else
 3499   {
 3500     if ( (csmpio->smp_request_sglist_cnt == 0) &&
 3501          (csmpio->smp_response_sglist_cnt == 0) )
 3502     {
 3503       AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
 3504       pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
 3505       pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
 3506       pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
 3507 
 3508       // 0xFF to be defined
 3509       agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
 3510     }
 3511     pccb->tiSMPFrame.flag = 0;
 3512   }
 3513 
 3514   return tiSuccess;
 3515 }
 3516 #else
 3517 
 3518 /******************************************************************************
 3519 agtiapi_PrepareSMPSGList()
 3520 
 3521 Purpose:
 3522   This function prepares scatter-gather list for the given ccb
 3523 Parameters:
 3524   struct agtiapi_softc *pmsc (IN)  Pointer to the HBA data structure
 3525   ccb_t *pccb (IN)      A pointer to the driver's own CCB, not CAM's CCB
 3526 Return:
 3527   0 - success
 3528   1 - failure
 3529 
 3530 Note:
 3531 ******************************************************************************/
 3532 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
 3533 {
 3534   /* Pointer to CAM's ccb */
 3535   union ccb *ccb = pccb->ccb;
 3536   struct ccb_smpio *csmpio = &ccb->smpio;
 3537   struct ccb_hdr *ccbh = &ccb->ccb_h;
 3538 
 3539   AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
 3540 
 3541   if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS)) 
 3542   {
 3543     AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
 3544                     "not supported\n" );
 3545     ccb->ccb_h.status = CAM_REQ_INVALID;
 3546     xpt_done(ccb);
 3547     return tiReject;
 3548   }
 3549 
 3550   if (ccbh->flags & CAM_SCATTER_VALID)
 3551   {
 3552     /* 
 3553      * Currently we do not support Multiple SG list 
 3554      * return error for now 
 3555      */
 3556     if ( (csmpio->smp_request_sglist_cnt > 1)
 3557          || (csmpio->smp_response_sglist_cnt > 1) )
 3558     {
 3559       AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
 3560                       "not supported\n" );
 3561       ccb->ccb_h.status = CAM_REQ_INVALID;
 3562       xpt_done(ccb);
 3563       return tiReject;
 3564     }
 3565     if ( csmpio->smp_request_sglist_cnt != 0 )
 3566     {
 3567       /* 
 3568        * Virtual address that needs to translated into
 3569        * one or more physical address ranges.
 3570        */
 3571       int error;
 3572       //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));  
 3573       AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
 3574       error = bus_dmamap_load( pmcsc->buffer_dmat,
 3575                                pccb->CCB_dmamap, 
 3576                                csmpio->smp_request, 
 3577                                csmpio->smp_request_len,
 3578                                agtiapi_PrepareSMPSGListCB, 
 3579                                pccb, 
 3580                                BUS_DMA_NOWAIT /* 0 */ );
 3581       
 3582       //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));  
 3583 
 3584       if (error == EINPROGRESS)
 3585       {
 3586         /*
 3587          * So as to maintain ordering,
 3588          * freeze the controller queue
 3589          * until our mapping is
 3590          * returned.
 3591          */
 3592         AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
 3593         xpt_freeze_simq( pmcsc->sim, 1 );
 3594         pmcsc->SimQFrozen = agTRUE;     
 3595         ccbh->status |= CAM_RELEASE_SIMQ;
 3596       }
 3597     }
 3598     if( csmpio->smp_response_sglist_cnt != 0 )
 3599     {
 3600       /*
 3601        * Virtual address that needs to translated into
 3602        * one or more physical address ranges.
 3603        */
 3604       int error;
 3605       //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );  
 3606       AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
 3607       error = bus_dmamap_load( pmcsc->buffer_dmat,
 3608                                pccb->CCB_dmamap, 
 3609                                csmpio->smp_response, 
 3610                                csmpio->smp_response_len,
 3611                                agtiapi_PrepareSMPSGListCB, 
 3612                                pccb, 
 3613                                BUS_DMA_NOWAIT /* 0 */ );
 3614       
 3615       //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
 3616 
 3617       if ( error == EINPROGRESS )
 3618       {
 3619         /*
 3620          * So as to maintain ordering,
 3621          * freeze the controller queue
 3622          * until our mapping is
 3623          * returned.
 3624          */
 3625         AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
 3626         xpt_freeze_simq( pmcsc->sim, 1 );
 3627         pmcsc->SimQFrozen = agTRUE;     
 3628         ccbh->status |= CAM_RELEASE_SIMQ;
 3629       }
 3630     }
 3631   }
 3632   else
 3633   {
 3634     if ( (csmpio->smp_request_sglist_cnt == 0) &&
 3635          (csmpio->smp_response_sglist_cnt == 0) )
 3636     {
 3637       AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
 3638       pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
 3639       pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
 3640       pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
 3641 
 3642       // 0xFF to be defined
 3643       agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
 3644     }
 3645     pccb->tiSMPFrame.flag = 0;
 3646   }
 3647 
 3648   return tiSuccess;
 3649 }
 3650 
 3651 #endif
 3652 /******************************************************************************
 3653 agtiapi_PrepareSMPSGListCB()
 3654 
 3655 Purpose:
 3656   Callback function for bus_dmamap_load()
 3657   This fuctions sends IO to LL layer.
 3658 Parameters:
 3659   void *arg (IN)                Pointer to the HBA data structure
 3660   bus_dma_segment_t *segs (IN)  Pointer to dma segment
 3661   int nsegs (IN)                number of dma segment
 3662   int error (IN)                error
 3663 Return:
 3664 Note:
 3665 ******************************************************************************/
 3666 static void agtiapi_PrepareSMPSGListCB( void *arg,
 3667                                         bus_dma_segment_t *segs,
 3668                                         int nsegs,
 3669                                         int error )
 3670 {
 3671   pccb_t                pccb = arg;
 3672   union ccb            *ccb  = pccb->ccb;
 3673   struct agtiapi_softc *pmcsc;
 3674   U32        TID     = CMND_TO_TARGET(ccb);
 3675   int status;
 3676   tiDeviceHandle_t     *tiExpDevHandle;
 3677   tiPortalContext_t    *tiExpPortalContext;
 3678   ag_portal_info_t     *tiExpPortalInfo;
 3679 
 3680   AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
 3681                   nsegs, error );
 3682   pmcsc = pccb->pmcsc;
 3683 
 3684   if ( error != tiSuccess )
 3685   {
 3686     if (error == 0xAABBCCDD)
 3687     {
 3688       // do nothing
 3689     }
 3690     else
 3691     {
 3692       AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
 3693                       error );
 3694       bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
 3695       agtiapi_FreeCCB( pmcsc, pccb );
 3696       if (error == EFBIG)
 3697         ccb->ccb_h.status = CAM_REQ_TOO_BIG;
 3698       else
 3699         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 3700       xpt_done( ccb );
 3701       return;
 3702     }
 3703   }
 3704 
 3705   if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
 3706   {
 3707     AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
 3708                     "AGTIAPI_MAX_DMA_SEGS %d\n",
 3709                     nsegs, AGTIAPI_MAX_DMA_SEGS );
 3710     bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
 3711     agtiapi_FreeCCB( pmcsc, pccb );
 3712     ccb->ccb_h.status = CAM_REQ_TOO_BIG;
 3713     xpt_done( ccb );
 3714     return;
 3715   }
 3716 
 3717   /*
 3718    * If assigned pDevHandle is not available
 3719    * then there is no need to send it to StartIO()
 3720    */
 3721   /* TODO: Add check for deviceType */
 3722   if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
 3723   {
 3724     agtiapi_FreeCCB( pmcsc, pccb );
 3725     ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 3726     xpt_done(ccb);
 3727     pccb->ccb        = NULL; 
 3728     return;
 3729   }
 3730   TID = INDEX( pmcsc, pccb->targetId );
 3731   if ( (TID >= pmcsc->devDiscover) ||
 3732        !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
 3733   {
 3734     AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
 3735                     "target %d tid %d/%d "
 3736                     "card %p ERROR pccb %p\n",
 3737                     pccb->devHandle,
 3738                     pccb->targetId,
 3739                     TID, 
 3740                     pmcsc->devDiscover,
 3741                     pmcsc,
 3742                     pccb );
 3743     agtiapi_FreeCCB( pmcsc, pccb );
 3744     ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 3745     xpt_done( ccb );
 3746     pccb->ccb        = NULL; 
 3747     return;
 3748   }
 3749   /* TODO: add indirect handling */
 3750   /* set the flag correctly based on Indiret SMP request and response */
 3751 
 3752   AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
 3753                   "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
 3754                   pccb->devHandle,
 3755                   pccb->targetId, TID,
 3756                   pmcsc->devDiscover,
 3757                   pmcsc );
 3758   tiExpDevHandle = pccb->devHandle;
 3759   tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
 3760   tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
 3761   /* Look for the expander associated with the ses device */
 3762   status = tiINIGetExpander( &pmcsc->tiRoot, 
 3763                              tiExpPortalContext,
 3764                              pccb->devHandle, 
 3765                              &tiExpDevHandle );
 3766 
 3767   if ( status != tiSuccess )
 3768   {
 3769     AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
 3770                     "device\n" );
 3771     agtiapi_FreeCCB( pmcsc, pccb );
 3772     ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 3773     xpt_done( ccb );
 3774     pccb->ccb        = NULL; 
 3775     return;
 3776   }
 3777         
 3778   /* this is expander device */
 3779   pccb->devHandle = tiExpDevHandle;
 3780   /* put the request in send queue */
 3781   agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
 3782                     AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
 3783 
 3784   agtiapi_StartSMP( pmcsc );
 3785 
 3786   return;
 3787 }
 3788 
 3789 
 3790 /******************************************************************************
 3791 agtiapi_Done()
 3792 
 3793 Purpose:
 3794   Processing completed ccbs
 3795 Parameters:
 3796   struct agtiapi_softc *pmcsc (IN)   Pointer to HBA data structure
 3797   ccb_t *pccb (IN)     A pointer to the driver's own CCB, not CAM's CCB
 3798 Return:
 3799 Note:
 3800 ******************************************************************************/
 3801 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 3802 {
 3803   pccb_t pccb_curr = pccb;
 3804   pccb_t pccb_next;
 3805 
 3806   tiIniScsiCmnd_t *cmnd;
 3807   union ccb * ccb;
 3808 
 3809   AGTIAPI_IO("agtiapi_Done: start\n");
 3810   while (pccb_curr)
 3811   {
 3812     /* start from 1st ccb in the chain */
 3813     pccb_next = pccb_curr->pccbNext;
 3814 
 3815     if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
 3816     {
 3817       /* send command back and release the ccb */
 3818       cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
 3819 
 3820       if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
 3821       {
 3822         AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
 3823                        "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
 3824                        pccb_curr);
 3825       }
 3826 
 3827       CMND_DMA_UNMAP(pmcsc, ccb);
 3828 
 3829       /* send the request back to the CAM */
 3830       ccb = pccb_curr->ccb;
 3831       agtiapi_FreeCCB(pmcsc, pccb_curr);
 3832       xpt_done(ccb);
 3833         }
 3834     pccb_curr = pccb_next;
 3835   }
 3836   return;
 3837 }
 3838 
 3839 /******************************************************************************
 3840 agtiapi_SMPDone()
 3841 
 3842 Purpose:
 3843   Processing completed ccbs
 3844 Parameters:
 3845   struct agtiapi_softc *pmcsc (IN)  Ponter to HBA data structure
 3846   ccb_t *pccb (IN)                  A pointer to the driver's own CCB, not
 3847                                     CAM's CCB
 3848 Return:
 3849 Note:
 3850 ******************************************************************************/
 3851 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 3852 {
 3853   pccb_t pccb_curr = pccb;
 3854   pccb_t pccb_next;
 3855 
 3856   union ccb * ccb;
 3857 
 3858   AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
 3859 
 3860   while (pccb_curr)
 3861   {
 3862     /* start from 1st ccb in the chain */
 3863     pccb_next = pccb_curr->pccbNext;
 3864 
 3865     if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
 3866     {
 3867       CMND_DMA_UNMAP(pmcsc, ccb);
 3868 
 3869       /* send the request back to the CAM */
 3870       ccb = pccb_curr->ccb;
 3871       agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
 3872       xpt_done(ccb);
 3873 
 3874     }
 3875     pccb_curr = pccb_next;
 3876   }
 3877 
 3878   AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
 3879   return;
 3880 }
 3881 
 3882 /******************************************************************************
 3883 agtiapi_hexdump()
 3884 
 3885 Purpose:
 3886   Utility function for dumping in hex
 3887 Parameters:
 3888   const char *ptitle (IN)  A string to be printed
 3889   bit8 *pbuf (IN)          A pointer to a buffer to be printed. 
 3890   int len (IN)             The lengther of the buffer
 3891 Return:
 3892 Note:
 3893 ******************************************************************************/
 3894 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
 3895 {
 3896   int i;
 3897   AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
 3898   if (!pbuf)
 3899   {
 3900     AGTIAPI_PRINTK("pbuf is NULL\n");
 3901     return;
 3902   }
 3903   for (i = 0; i < len; )
 3904   {
 3905     if (len - i > 4)
 3906     {
 3907       AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
 3908                       pbuf[i+2], pbuf[i+3] );
 3909       i += 4;
 3910     }
 3911     else
 3912     {
 3913       AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
 3914       i++;
 3915     }
 3916   }
 3917   AGTIAPI_PRINTK("\n");
 3918 }
 3919 
 3920 
 3921 /******************************************************************************
 3922 agtiapi_CheckError()
 3923 
 3924 Purpose:
 3925   Processes status pertaining to the ccb -- whether it was
 3926   completed successfully, aborted, or error encountered.
 3927 Parameters: 
 3928   ag_card_t *pCard (IN)  Pointer to HBA data structure
 3929   ccb_t *pccd (IN)       A pointer to the driver's own CCB, not CAM's CCB
 3930 Return:
 3931   0 - the command retry is required
 3932   1 - the command process is completed
 3933 Note:    
 3934 
 3935 ******************************************************************************/
 3936 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 3937 {
 3938   ag_device_t      *pDevice;
 3939   // union ccb * ccb = pccb->ccb;
 3940   union ccb * ccb;
 3941   int is_error, TID;
 3942 
 3943   if (pccb == NULL) {
 3944     return 0;
 3945   }
 3946   ccb = pccb->ccb;
 3947   AGTIAPI_IO("agtiapi_CheckError: start\n");
 3948   if (ccb == NULL)
 3949   {
 3950     /* shouldn't be here but just in case we do */
 3951     AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
 3952     agtiapi_FreeCCB(pmcsc, pccb);
 3953     return 0;
 3954   }
 3955 
 3956   is_error = 1;
 3957   pDevice = NULL;
 3958   if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
 3959   {
 3960     if (pmcsc->pWWNList != NULL)
 3961     {
 3962       TID = INDEX(pmcsc, pccb->targetId);
 3963       if (TID < maxTargets)
 3964       {
 3965         pDevice = &pmcsc->pDevList[TID];
 3966         if (pDevice != NULL)
 3967         {
 3968           is_error = 0;
 3969         }
 3970       }
 3971     }
 3972   }
 3973   if (is_error)
 3974   {
 3975     AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
 3976     agtiapi_FreeCCB(pmcsc, pccb);
 3977     return 0;
 3978   }
 3979 
 3980   /* SCSI status */
 3981   ccb->csio.scsi_status = pccb->scsiStatus;
 3982 
 3983    if(pDevice->CCBCount > 0){
 3984     atomic_subtract_int(&pDevice->CCBCount,1);
 3985 }
 3986   AG_LOCAL_LOCK(&pmcsc->freezeLock);
 3987   if(pmcsc->freezeSim == agTRUE)
 3988   { 
 3989     pmcsc->freezeSim = agFALSE;
 3990     xpt_release_simq(pmcsc->sim, 1); 
 3991   }
 3992   AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
 3993 
 3994   switch (pccb->ccbStatus)
 3995   {
 3996   case tiIOSuccess:
 3997     AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
 3998     /* CAM status */
 3999     if (pccb->scsiStatus == SCSI_STATUS_OK)
 4000     {
 4001       ccb->ccb_h.status = CAM_REQ_CMP;
 4002     }
 4003     else
 4004       if (pccb->scsiStatus == SCSI_TASK_ABORTED)
 4005     {
 4006       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4007     }
 4008     else
 4009     {
 4010       ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
 4011     }
 4012     if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
 4013     {
 4014       ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
 4015     }
 4016  
 4017     break;
 4018 
 4019   case tiIOOverRun:
 4020     AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
 4021     /* resid is ignored for this condition */
 4022     ccb->csio.resid = 0;
 4023     ccb->ccb_h.status = CAM_DATA_RUN_ERR;
 4024     break;
 4025   case tiIOUnderRun:
 4026     AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
 4027     ccb->csio.resid = pccb->scsiStatus;
 4028     ccb->ccb_h.status = CAM_REQ_CMP;
 4029     ccb->csio.scsi_status = SCSI_STATUS_OK;
 4030     break;
 4031 
 4032   case tiIOFailed:
 4033     AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
 4034                     pccb, pccb->scsiStatus, pccb->targetId );
 4035     if (pccb->scsiStatus == tiDeviceBusy)
 4036     {
 4037       AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
 4038                   pccb );
 4039       ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 4040       ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 4041       if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) 
 4042       {
 4043         ccb->ccb_h.status |= CAM_DEV_QFRZN;
 4044         xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
 4045       }
 4046     }
 4047     else if(pccb->scsiStatus == tiBusy)
 4048     {
 4049       AG_LOCAL_LOCK(&pmcsc->freezeLock);
 4050       if(pmcsc->freezeSim == agFALSE)
 4051       {
 4052         pmcsc->freezeSim = agTRUE;
 4053         xpt_freeze_simq(pmcsc->sim, 1);
 4054       }
 4055       AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
 4056       ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 4057       ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 4058     }
 4059     else if (pccb->scsiStatus == tiDetailNoLogin)
 4060     {
 4061       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4062                       "tiDetailNoLogin ERROR\n", pccb );
 4063       ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 4064     }
 4065     else if (pccb->scsiStatus == tiDetailNotValid)
 4066     {
 4067       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4068                       "tiDetailNotValid ERROR\n", pccb );
 4069       ccb->ccb_h.status = CAM_REQ_INVALID;
 4070     }
 4071     else if (pccb->scsiStatus == tiDetailAbortLogin)
 4072     {
 4073       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4074                       "tiDetailAbortLogin ERROR\n", pccb );
 4075       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4076     }
 4077     else if (pccb->scsiStatus == tiDetailAbortReset)
 4078     {
 4079       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4080                       "tiDetailAbortReset ERROR\n", pccb );
 4081       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4082     }
 4083     else if (pccb->scsiStatus == tiDetailAborted)
 4084     {
 4085       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4086                       "tiDetailAborted ERROR\n", pccb );
 4087       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4088     }
 4089     else if (pccb->scsiStatus == tiDetailOtherError)
 4090     {
 4091       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4092                       "tiDetailOtherError ERROR\n", pccb );
 4093       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4094     }
 4095     break;
 4096   case tiIODifError:
 4097     AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
 4098                     pccb, pccb->scsiStatus, pccb->targetId );
 4099     if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
 4100     {
 4101       AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4102                   "tiDetailDifAppTagMismatch\n", pccb );
 4103       ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4104     }
 4105     else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
 4106     {
 4107       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4108                       "tiDetailDifRefTagMismatch\n", pccb );
 4109       ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4110     }
 4111     else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
 4112     {
 4113       AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
 4114                       "tiDetailDifCrcMismatch\n", pccb );
 4115       ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4116     }
 4117     break;
 4118 #ifdef HIALEAH_ENCRYPTION
 4119   case tiIOEncryptError:
 4120     AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
 4121                     pccb, pccb->scsiStatus, pccb->targetId );
 4122     if (pccb->scsiStatus == tiDetailDekKeyCacheMiss) 
 4123     {
 4124       AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
 4125                       "tiDetailDekKeyCacheMiss ERROR\n",
 4126                       __FUNCTION__, pccb );
 4127       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4128       agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
 4129     }
 4130     else if (pccb->scsiStatus == tiDetailDekIVMismatch)
 4131     {
 4132       AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
 4133                       "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
 4134       ccb->ccb_h.status = CAM_REQ_ABORTED;
 4135       agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
 4136     }
 4137     break;
 4138 #endif
 4139   default:
 4140     AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
 4141                     pccb, pccb->ccbStatus, pccb->targetId );
 4142     ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4143     break;
 4144   }
 4145 
 4146   return 1;
 4147 }
 4148 
 4149 
 4150 /******************************************************************************
 4151 agtiapi_SMPCheckError()
 4152 
 4153 Purpose:
 4154   Processes status pertaining to the ccb -- whether it was
 4155   completed successfully, aborted, or error encountered.
 4156 Parameters: 
 4157   ag_card_t *pCard (IN)  Pointer to HBA data structure
 4158   ccb_t *pccd (IN)       A pointer to the driver's own CCB, not CAM's CCB
 4159 Return:
 4160   0 - the command retry is required
 4161   1 - the command process is completed
 4162 Note:    
 4163 
 4164 ******************************************************************************/
 4165 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
 4166 {
 4167         union ccb * ccb = pccb->ccb;
 4168 
 4169         AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
 4170 
 4171         if (!ccb)
 4172         {
 4173                 /* shouldn't be here but just in case we do */
 4174                 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
 4175                               pccb );
 4176                 agtiapi_FreeSMPCCB(pmcsc, pccb);
 4177                 return 0;
 4178         }
 4179 
 4180         switch (pccb->ccbStatus)
 4181         {
 4182         case tiSMPSuccess:
 4183                 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
 4184                               pccb );
 4185                 /* CAM status */
 4186                 ccb->ccb_h.status = CAM_REQ_CMP;
 4187                 break;
 4188   case tiSMPFailed:
 4189                 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
 4190                               pccb );
 4191                 /* CAM status */
 4192                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4193                 break;
 4194   default:
 4195                 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
 4196                               "id %d ERROR\n",
 4197                               pccb, 
 4198                               pccb->ccbStatus,
 4199                               pccb->targetId );
 4200                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4201                 break;
 4202         }
 4203 
 4204 
 4205   return 1;
 4206 
 4207 }
 4208 
 4209 /******************************************************************************
 4210 agtiapi_HandleEncryptedIOFailure():
 4211 
 4212 Purpose:
 4213 Parameters:
 4214 Return:
 4215 Note: 
 4216   Currently not used.
 4217 ******************************************************************************/
 4218 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
 4219 {
 4220   
 4221   AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
 4222   return;
 4223 }
 4224 
 4225 /******************************************************************************
 4226 agtiapi_Retry()
 4227 
 4228 Purpose:
 4229   Retry a ccb.
 4230 Parameters: 
 4231   struct agtiapi_softc *pmcsc (IN)  Pointer to the HBA structure
 4232   ccb_t *pccb (IN)            A pointer to the driver's own CCB, not CAM's CCB 
 4233 Return:
 4234 Note:
 4235   Currently not used.    
 4236 ******************************************************************************/
 4237 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
 4238 {
 4239   pccb->retryCount++;
 4240   pccb->flags      = ACTIVE | AGTIAPI_RETRY;
 4241   pccb->ccbStatus  = 0;
 4242   pccb->scsiStatus = 0;
 4243   pccb->startTime  = ticks;
 4244 
 4245   AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
 4246   AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
 4247                   pccb->retryCount, pccb->flags );
 4248 
 4249   agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
 4250                    AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
 4251   return;
 4252 }
 4253 
 4254 
 4255 /******************************************************************************
 4256 agtiapi_DumpCCB()
 4257 
 4258 Purpose:
 4259   Dump CCB for debuging
 4260 Parameters:
 4261   ccb_t *pccb (IN)  A pointer to the driver's own CCB, not CAM's CCB
 4262 Return:
 4263 Note:
 4264 ******************************************************************************/
 4265 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
 4266 {
 4267   AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n", 
 4268          pccb, 
 4269          pccb->devHandle, 
 4270          pccb->targetId, 
 4271          pccb->lun);
 4272   AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n", 
 4273          pccb->flags,
 4274          pccb->addrMode, 
 4275          pccb->ccbStatus, 
 4276          pccb->scsiStatus);
 4277   AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n", 
 4278          pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
 4279          pccb->numSgElements);
 4280   AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
 4281          pccb->dataLen, 
 4282          pccb->senseLen);
 4283   AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
 4284   AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
 4285          pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
 4286          pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
 4287   AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
 4288          pccb->tiSuperScsiRequest.scsiCmnd.cdb[0], 
 4289          pccb->tiSuperScsiRequest.scsiCmnd.cdb[1], 
 4290          pccb->tiSuperScsiRequest.scsiCmnd.cdb[2], 
 4291          pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]); 
 4292   AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
 4293          pccb->tiSuperScsiRequest.scsiCmnd.cdb[4], 
 4294          pccb->tiSuperScsiRequest.scsiCmnd.cdb[5], 
 4295          pccb->tiSuperScsiRequest.scsiCmnd.cdb[6], 
 4296          pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
 4297   AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
 4298                   "cdb[11] = 0x%x\n",
 4299                   pccb->tiSuperScsiRequest.scsiCmnd.cdb[8], 
 4300                   pccb->tiSuperScsiRequest.scsiCmnd.cdb[9], 
 4301                   pccb->tiSuperScsiRequest.scsiCmnd.cdb[10], 
 4302                   pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
 4303   AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
 4304          pccb->tiSuperScsiRequest.agSgl1.upper, 
 4305          pccb->tiSuperScsiRequest.agSgl1.lower, 
 4306          pccb->tiSuperScsiRequest.agSgl1.len, 
 4307          pccb->tiSuperScsiRequest.agSgl1.type); 
 4308 }
 4309 
 4310 /******************************************************************************
 4311 agtiapi_eh_HostReset()
 4312 
 4313 Purpose:
 4314   A new error handler of Host Reset command.
 4315 Parameters:
 4316   scsi_cmnd *cmnd (IN)  Pointer to a command to the HBA to be reset
 4317 Return:
 4318   SUCCESS - success
 4319   FAILED  - fail
 4320 Note:
 4321 ******************************************************************************/
 4322 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
 4323 {
 4324   AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
 4325                   cmnd );
 4326 
 4327   if( cmnd == NULL )
 4328   {
 4329     printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
 4330     return tiInvalidHandle;
 4331   }
 4332 
 4333 #ifdef LOGEVENT
 4334   agtiapi_LogEvent( pmcsc,
 4335                     IOCTL_EVT_SEV_INFORMATIONAL,
 4336                     0,
 4337                     agNULL,
 4338                     0,
 4339                     "agtiapi_eh_HostReset! " );
 4340 #endif
 4341 
 4342   return agtiapi_DoSoftReset( pmcsc );
 4343 }
 4344 
 4345 
 4346 /******************************************************************************
 4347 agtiapi_QueueCCB()
 4348 
 4349 Purpose:
 4350   Put ccb in ccb queue at the tail
 4351 Parameters:
 4352   struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 4353   pccb_t *phead (IN)                Double pointer to ccb queue head
 4354   pccb_t *ptail (IN)                Double pointer to ccb queue tail
 4355   ccb_t *pccb (IN)                  Poiner to a ccb to be queued
 4356 Return:
 4357 Note:
 4358   Put the ccb to the tail of queue
 4359 ******************************************************************************/
 4360 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
 4361                               pccb_t *phead,
 4362                               pccb_t *ptail, 
 4363 #ifdef AGTIAPI_LOCAL_LOCK
 4364                               struct mtx *mutex,
 4365 #endif
 4366                               ccb_t *pccb )
 4367 {
 4368   AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
 4369   AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
 4370   if (phead == NULL || ptail == NULL)
 4371   {
 4372     panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
 4373   }
 4374   pccb->pccbNext = NULL;
 4375   AG_LOCAL_LOCK( mutex );
 4376   if (*phead == NULL)
 4377   {
 4378     //WARN_ON(*ptail != NULL); /* critical, just get more logs */
 4379     *phead = pccb;
 4380   }
 4381   else
 4382   {
 4383     //WARN_ON(*ptail == NULL); /* critical, just get more logs */
 4384     if (*ptail)
 4385       (*ptail)->pccbNext = pccb;
 4386   }
 4387   *ptail = pccb;
 4388   AG_LOCAL_UNLOCK( mutex );
 4389   return;
 4390 }
 4391 
 4392 
 4393 /******************************************************************************
 4394 agtiapi_QueueCCB()
 4395 
 4396 Purpose:
 4397  
 4398 Parameters:
 4399   
 4400   
 4401 Return:
 4402 Note:
 4403   
 4404 ******************************************************************************/
 4405 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
 4406 {
 4407   pccb_t pccb = agNULL; /* call dequeue */
 4408   int        status = tiSuccess;
 4409   int        targetID = xpt_path_target_id(ccb->ccb_h.path);
 4410 
 4411   AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");  
 4412 
 4413   /* get a ccb */
 4414   if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
 4415   {
 4416     AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
 4417     ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 4418     xpt_done(ccb);
 4419     return tiBusy;
 4420   }
 4421   pccb->pmcsc = pmcsc;
 4422 
 4423   /* initialize Command Control Block (CCB) */
 4424   pccb->targetId   = targetID;
 4425   pccb->ccb        = ccb;       /* for struct scsi_cmnd */
 4426 
 4427   status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
 4428 
 4429   if (status != tiSuccess)
 4430   {
 4431     AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
 4432     agtiapi_FreeCCB(pmcsc, pccb);
 4433     if (status == tiReject)
 4434     {
 4435       ccb->ccb_h.status = CAM_REQ_INVALID;
 4436     }
 4437     else
 4438     {
 4439       ccb->ccb_h.status = CAM_REQ_CMP;
 4440     }
 4441     xpt_done(ccb);
 4442     return tiError;
 4443   }
 4444 
 4445   return status;
 4446 }
 4447 
 4448 /******************************************************************************
 4449 agtiapi_SetLunField()
 4450 
 4451 Purpose:
 4452   Set LUN field based on different address mode
 4453 Parameters:
 4454   ccb_t *pccb (IN)  A pointer to the driver's own CCB, not CAM's CCB
 4455 Return:
 4456 Note:
 4457 ******************************************************************************/
 4458 void agtiapi_SetLunField(ccb_t *pccb)
 4459 {
 4460   U08 *pchar;
 4461 
 4462   pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
 4463 
 4464 //  AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
 4465   
 4466   switch (pccb->addrMode)
 4467   {
 4468   case AGTIAPI_PERIPHERAL:
 4469        *pchar++ = 0;
 4470        *pchar   = (U08)pccb->lun;
 4471        break;
 4472   case AGTIAPI_VOLUME_SET:
 4473        *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) | 
 4474                   (U08)((pccb->lun >> 8) & 0x3F);
 4475        *pchar   = (U08)pccb->lun;
 4476        break;
 4477   case AGTIAPI_LUN_ADDR:
 4478        *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) | 
 4479                   pccb->targetId;
 4480        *pchar   = (U08)pccb->lun;
 4481        break;
 4482   }
 4483 
 4484 
 4485 }
 4486 
 4487 
 4488 /*****************************************************************************
 4489 agtiapi_FreeCCB()
 4490 
 4491 Purpose:
 4492   Free a ccb and put it back to ccbFreeList.
 4493 Parameters:
 4494   struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 4495   pccb_t pccb (IN)                  A pointer to the driver's own CCB, not
 4496                                     CAM's CCB
 4497 Returns:
 4498 Note:
 4499 *****************************************************************************/
 4500 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
 4501 {
 4502   union ccb *ccb = pccb->ccb;
 4503   bus_dmasync_op_t op;
 4504 
 4505   AG_LOCAL_LOCK(&pmcsc->ccbLock);
 4506   AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
 4507 
 4508 #ifdef AGTIAPI_TEST_EPL
 4509   tiEncrypt_t *encrypt;
 4510 #endif
 4511 
 4512   agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
 4513 
 4514   if (pccb->sgList != agNULL)
 4515   {
 4516     AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
 4517   }
 4518   else
 4519   {
 4520     AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
 4521   }
 4522 
 4523   /* set data transfer direction */
 4524   if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 
 4525   {
 4526     op = BUS_DMASYNC_POSTWRITE;
 4527   }
 4528   else 
 4529   {
 4530     op = BUS_DMASYNC_POSTREAD;
 4531   }
 4532 
 4533   if (pccb->numSgElements == 0)
 4534   {
 4535     // do nothing
 4536     AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
 4537   }
 4538   else if (pccb->numSgElements == 1)
 4539   {
 4540     AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
 4541     //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
 4542     bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
 4543     bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 4544   }
 4545   else
 4546   {
 4547     AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
 4548     //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
 4549     bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
 4550     bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 4551   }
 4552 
 4553 #ifdef AGTIAPI_TEST_DPL
 4554   if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
 4555     if(pccb->dplPtr)
 4556         memset( (char *) pccb->dplPtr,
 4557                 0,
 4558                 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
 4559     pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
 4560     pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
 4561     pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
 4562   }
 4563 #endif
 4564 
 4565 #ifdef AGTIAPI_TEST_EPL
 4566   encrypt = &pccb->tiSuperScsiRequest.Encrypt;
 4567   if (encrypt->enableEncryptionPerLA == TRUE) {
 4568     encrypt->enableEncryptionPerLA = FALSE;
 4569     encrypt->EncryptionPerLAAddrLo = 0;
 4570     encrypt->EncryptionPerLAAddrHi = 0;
 4571   }
 4572 #endif
 4573 
 4574 #ifdef ENABLE_SATA_DIF
 4575   if (pccb->holePtr && pccb->dmaHandleHole)
 4576     pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
 4577                          512,
 4578                          pccb->holePtr,
 4579                          pccb->dmaHandleHole );
 4580   pccb->holePtr    = 0;
 4581   pccb->dmaHandleHole = 0;
 4582 #endif
 4583 
 4584   pccb->dataLen    = 0;
 4585   pccb->retryCount = 0;
 4586   pccb->ccbStatus  = 0;
 4587   pccb->scsiStatus = 0;
 4588   pccb->startTime  = 0;
 4589   pccb->dmaHandle  = 0;
 4590   pccb->numSgElements = 0;
 4591   pccb->tiIORequest.tdData = 0;
 4592   memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
 4593 
 4594 #ifdef HIALEAH_ENCRYPTION
 4595   if (pmcsc->encrypt)
 4596     agtiapi_CleanupEncryptedIO(pmcsc, pccb);
 4597 #endif
 4598 
 4599   pccb->flags      = 0;
 4600   pccb->ccb        = NULL;
 4601   pccb->pccbIO = NULL;
 4602   pccb->pccbNext     = (pccb_t)pmcsc->ccbFreeList;
 4603   pmcsc->ccbFreeList = (caddr_t *)pccb;
 4604 
 4605   pmcsc->activeCCB--;
 4606 
 4607   AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
 4608   return;
 4609 }
 4610 
 4611 
 4612 /******************************************************************************
 4613 agtiapi_FlushCCBs()
 4614 
 4615 Purpose:
 4616   Flush all in processed ccbs.
 4617 Parameters:
 4618   ag_card_t *pCard (IN)  Pointer to HBA data structure
 4619   U32 flag (IN)            Flag to call back
 4620 Return:
 4621 Note:
 4622 ******************************************************************************/
 4623 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
 4624 {
 4625   union ccb *ccb;
 4626   ccb_t     *pccb;
 4627 
 4628   AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
 4629   for( pccb = (pccb_t)pCard->ccbChainList;
 4630        pccb != NULL;
 4631        pccb = pccb->pccbChainNext ) {
 4632     if( pccb->flags == 0 )
 4633     {
 4634       // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
 4635       continue;
 4636     }
 4637     ccb = pccb->ccb;
 4638     if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
 4639     {
 4640       AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
 4641       agtiapi_FreeTMCCB( pCard, pccb );
 4642     }
 4643     else
 4644     {
 4645       if ( pccb->flags & TAG_SMP )
 4646       {
 4647         AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
 4648         agtiapi_FreeSMPCCB( pCard, pccb );
 4649       }
 4650       else
 4651       {
 4652         AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
 4653         agtiapi_FreeCCB( pCard, pccb );
 4654       }
 4655       if( ccb ) {
 4656         CMND_DMA_UNMAP( pCard, ccb );
 4657         if( flag == AGTIAPI_CALLBACK ) {
 4658           ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
 4659           xpt_done( ccb );
 4660         }
 4661       }
 4662     }
 4663   }
 4664 }
 4665 
 4666 /*****************************************************************************
 4667 agtiapi_FreeSMPCCB()
 4668 
 4669 Purpose:
 4670   Free a ccb and put it back to ccbFreeList.
 4671 Parameters:
 4672   struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 4673   pccb_t pccb (IN)                  A pointer to the driver's own CCB, not
 4674                                     CAM's CCB
 4675 Returns:
 4676 Note:
 4677 *****************************************************************************/
 4678 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
 4679 {
 4680   union ccb *ccb = pccb->ccb;
 4681   bus_dmasync_op_t op;
 4682 
 4683   AG_LOCAL_LOCK(&pmcsc->ccbLock);
 4684   AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
 4685 
 4686   /* set data transfer direction */
 4687   if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
 4688   {
 4689     op = BUS_DMASYNC_POSTWRITE;
 4690   }
 4691   else
 4692   {
 4693     op = BUS_DMASYNC_POSTREAD;
 4694   }
 4695 
 4696   if (pccb->numSgElements == 0)
 4697   {
 4698     // do nothing
 4699     AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
 4700   }
 4701   else if (pccb->numSgElements == 1)
 4702   {
 4703     AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
 4704     //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
 4705     bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
 4706     bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 4707   }
 4708   else
 4709   {
 4710     AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
 4711     //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
 4712     bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
 4713     bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
 4714   }
 4715 
 4716   /*dma api cleanning*/
 4717   pccb->dataLen    = 0;
 4718   pccb->retryCount = 0;
 4719   pccb->ccbStatus  = 0;
 4720   pccb->startTime  = 0;
 4721   pccb->dmaHandle  = 0;
 4722   pccb->numSgElements = 0;
 4723   pccb->tiIORequest.tdData = 0;
 4724   memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
 4725 
 4726   pccb->flags        = 0;
 4727   pccb->ccb = NULL;
 4728   pccb->pccbNext     = (pccb_t)pmcsc->ccbFreeList;
 4729   pmcsc->ccbFreeList = (caddr_t *)pccb;
 4730 
 4731   pmcsc->activeCCB--;
 4732 
 4733   AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
 4734   return;
 4735 
 4736 }
 4737 
 4738 /*****************************************************************************
 4739 agtiapi_FreeTMCCB()
 4740 
 4741 Purpose:
 4742   Free a ccb and put it back to ccbFreeList.
 4743 Parameters:
 4744   struct agtiapi_softc *pmcsc (IN)  Pointer to HBA data structure
 4745   pccb_t pccb (IN)                  A pointer to the driver's own CCB, not
 4746                                     CAM's CCB
 4747 Returns:
 4748 Note:
 4749 *****************************************************************************/
 4750 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
 4751 {
 4752   AG_LOCAL_LOCK(&pmcsc->ccbLock);
 4753   AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
 4754   pccb->dataLen    = 0;
 4755   pccb->retryCount = 0;
 4756   pccb->ccbStatus  = 0;
 4757   pccb->scsiStatus = 0;
 4758   pccb->startTime  = 0;
 4759   pccb->dmaHandle  = 0;
 4760   pccb->numSgElements = 0;
 4761   pccb->tiIORequest.tdData = 0;
 4762   memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
 4763   pccb->flags        = 0;
 4764   pccb->ccb = NULL;
 4765   pccb->pccbIO = NULL;
 4766   pccb->pccbNext     = (pccb_t)pmcsc->ccbFreeList;
 4767   pmcsc->ccbFreeList = (caddr_t *)pccb;
 4768   pmcsc->activeCCB--;
 4769   AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
 4770   return;
 4771 }
 4772 /******************************************************************************
 4773 agtiapi_CheckAllVectors():
 4774 
 4775 Purpose:
 4776 Parameters:
 4777 Return:
 4778 Note:
 4779   Currently, not used.
 4780 ******************************************************************************/
 4781 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
 4782 {
 4783 #ifdef SPC_MSIX_INTR
 4784   if (!agtiapi_intx_mode)
 4785   {
 4786     int i;
 4787 
 4788     for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
 4789       if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
 4790         tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
 4791   }
 4792   else
 4793   if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
 4794     tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
 4795 #else
 4796   if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
 4797     tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
 4798 #endif
 4799 
 4800 }
 4801 
 4802 
 4803 /******************************************************************************
 4804 agtiapi_CheckCB()
 4805 
 4806 Purpose:
 4807   Check call back function returned event for process completion
 4808 Parameters: 
 4809   struct agtiapi_softc *pCard  Pointer to card data structure
 4810   U32 milisec (IN)       Waiting time for expected event
 4811   U32 flag (IN)          Flag of the event to check
 4812   U32 *pStatus (IN)      Pointer to status of the card or port to check
 4813 Return:
 4814   AGTIAPI_SUCCESS - event comes as expected
 4815   AGTIAPI_FAIL    - event not coming
 4816 Note:
 4817   Currently, not used    
 4818 ******************************************************************************/
 4819 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
 4820                            U32 milisec,
 4821                            U32 flag,
 4822                            volatile U32 *pStatus )
 4823 {
 4824   U32    msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
 4825                         initiatorOption.usecsPerTick / 1000;
 4826   S32    i = milisec/msecsPerTick;
 4827   AG_GLOBAL_ARG( _flags );
 4828 
 4829   AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
 4830   AGTIAPI_FLOW(   "agtiapi_CheckCB: start\n" );
 4831 
 4832   if( i <= 0 )
 4833     i = 1;
 4834   while (i > 0)
 4835   {
 4836     if (*pStatus & TASK_MANAGEMENT)
 4837     {
 4838       if (*pStatus & AGTIAPI_CB_DONE) 
 4839       {
 4840         if( flag == 0 || *pStatus & flag )
 4841           return AGTIAPI_SUCCESS;
 4842         else
 4843           return AGTIAPI_FAIL;
 4844       }
 4845     }
 4846     else if (pCard->flags & AGTIAPI_CB_DONE) 
 4847     {
 4848       if( flag == 0 || *pStatus & flag )
 4849         return AGTIAPI_SUCCESS;
 4850       else
 4851         return AGTIAPI_FAIL;
 4852     }
 4853 
 4854     agtiapi_DelayMSec( msecsPerTick );
 4855 
 4856     AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
 4857     tiCOMTimerTick( &pCard->tiRoot );
 4858 
 4859     agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
 4860     AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
 4861 
 4862     i--;
 4863   }
 4864 
 4865   if( *pStatus & TASK_MANAGEMENT )
 4866     *pStatus |= TASK_TIMEOUT;
 4867 
 4868   return AGTIAPI_FAIL;
 4869 }
 4870 
 4871 
 4872 /******************************************************************************
 4873 agtiapi_DiscoverTgt()
 4874 
 4875 Purpose:
 4876   Discover available devices
 4877 Parameters:
 4878   struct agtiapi_softc *pCard (IN)  Pointer to the HBA data structure
 4879 Return:
 4880 Note:
 4881 ******************************************************************************/
 4882 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
 4883 {
 4884 
 4885   ag_portal_data_t *pPortalData;
 4886   U32              count;
 4887 
 4888   AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
 4889   AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
 4890   AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
 4891 
 4892   pPortalData = pCard->pPortalData;
 4893   for (count = 0; count < pCard->portCount; count++, pPortalData++)
 4894   {
 4895     pCard->flags &= ~AGTIAPI_CB_DONE;
 4896     if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
 4897     {
 4898       if (pCard->flags & AGTIAPI_INIT_TIME)
 4899       {
 4900         if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY, 
 4901             &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
 4902         {
 4903           AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
 4904                           "discovery\n", 
 4905                           pPortalData, count );
 4906           /* 
 4907            * There is no need to spend time on discovering device 
 4908            * if port is not ready to do so.
 4909            */
 4910           continue;
 4911         }
 4912       }
 4913       else
 4914         continue;
 4915     }
 4916 
 4917     AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
 4918                   pPortalData );
 4919     AGTIAPI_INIT_DELAY(1000);
 4920 
 4921     pCard->flags &= ~AGTIAPI_CB_DONE;
 4922     if (tiINIDiscoverTargets(&pCard->tiRoot, 
 4923                              &pPortalData->portalInfo.tiPortalContext,
 4924                              FORCE_PERSISTENT_ASSIGN_MASK)
 4925         != tiSuccess)
 4926       AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
 4927 
 4928     /*
 4929      * Should wait till discovery completion to start
 4930      * next portal. However, lower layer have issue on 
 4931      * multi-portal case under Linux.
 4932      */
 4933   }
 4934 
 4935   pPortalData = pCard->pPortalData;
 4936   for (count = 0; count < pCard->portCount; count++, pPortalData++)
 4937   {
 4938     if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
 4939     {
 4940       if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
 4941           &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
 4942       {
 4943         if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
 4944           AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
 4945                           "status 0x%x\n",
 4946                           pPortalData,
 4947                           PORTAL_STATUS(pPortalData) );
 4948         else
 4949           AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
 4950                           "completed, status 0x%x\n",
 4951                           pPortalData, PORTAL_STATUS(pPortalData) );
 4952         continue;
 4953       }
 4954       AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
 4955                       "success\n",
 4956                       count );
 4957     }
 4958   }
 4959 
 4960   /* 
 4961    * Calling to get device handle should be done per portal based 
 4962    * and better right after discovery is done. However, lower iscsi
 4963    * layer may not returns discovery complete in correct sequence or we
 4964    * ran out time. We get device handle for all portals together
 4965    * after discovery is done or timed out.
 4966    */
 4967   pPortalData = pCard->pPortalData;
 4968   for (count = 0; count < pCard->portCount; count++, pPortalData++)
 4969   {
 4970     /* 
 4971      * We try to get device handle no matter 
 4972      * if discovery is completed or not. 
 4973      */
 4974     if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
 4975     {
 4976       U32 i;
 4977 
 4978       for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
 4979       {
 4980         if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
 4981           break;
 4982         agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
 4983       }
 4984 
 4985       if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
 4986           (pCard->tgtCount > 0))
 4987         PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
 4988                                         AGTIAPI_PORT_LINK_UP );
 4989     }
 4990   }
 4991   
 4992   return;
 4993 
 4994 }
 4995 
 4996 
 4997 
 4998 /******************************************************************************
 4999 agtiapi_PrepCCBs()
 5000 
 5001 Purpose:
 5002   Prepares CCB including DMA map.
 5003 Parameters: 
 5004   struct agtiapi_softc *pCard (IN)  Pointer to the HBA data structure
 5005   ccb_hdr_t *hdr (IN)               Pointer to the CCB header
 5006   U32 size (IN)                     size
 5007   U32 max_ccb (IN)                  count
 5008   
 5009 Return:
 5010 Note:    
 5011 ******************************************************************************/
 5012 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
 5013                               ccb_hdr_t *hdr,
 5014                               U32 size,
 5015                               U32 max_ccb,
 5016                               int tid )
 5017 {
 5018 
 5019   int i;
 5020   U32 hdr_sz, ccb_sz;
 5021   ccb_t *pccb = NULL;
 5022   int offset = 0;
 5023   int nsegs = 0;
 5024   int sgl_sz = 0;
 5025 
 5026   AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
 5027   offset = tid * AGTIAPI_CCB_PER_DEVICE;
 5028   nsegs = AGTIAPI_NSEGS;
 5029   sgl_sz = sizeof(tiSgl_t) * nsegs;
 5030   AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
 5031                   "%lu, max_ccb %d\n",
 5032                   tid,
 5033                   offset,
 5034                   nsegs,
 5035                   sizeof(tiSgl_t),
 5036                   max_ccb );
 5037 
 5038   ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
 5039   hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
 5040 
 5041   AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
 5042 
 5043   memset((void *)hdr, 0, size);
 5044   hdr->next = pCard->ccbAllocList;
 5045   pCard->ccbAllocList = hdr;
 5046 
 5047   AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
 5048 
 5049   pccb = (ccb_t*) ((char*)hdr + hdr_sz);
 5050 
 5051   for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
 5052   {
 5053     pccb->tiIORequest.osData = (void *)pccb;
 5054 
 5055     /*
 5056      * Initially put all the ccbs on the free list
 5057      * in addition to chainlist.
 5058      * ccbChainList is a list of all available ccbs
 5059      * (free/active everything)
 5060      */
 5061     pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
 5062     pccb->pccbNext      = (pccb_t)pCard->ccbFreeList;
 5063 
 5064     pCard->ccbChainList = (caddr_t *)pccb;
 5065     pCard->ccbFreeList  = (caddr_t *)pccb;
 5066     pCard->ccbTotal++;
 5067 
 5068 #ifdef AGTIAPI_ALIGN_CHECK
 5069     if (&pccb & 0x63)
 5070       AGTIAPI_PRINTK("pccb = %p\n", pccb);
 5071     if (pccb->devHandle & 0x63)
 5072       AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
 5073     if (&pccb->lun & 0x63)
 5074       AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
 5075     if (&pccb->targetId & 0x63)
 5076       AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
 5077     if (&pccb->ccbStatus & 0x63)
 5078       AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
 5079     if (&pccb->scsiStatus & 0x63)
 5080       AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
 5081     if (&pccb->dataLen & 0x63)
 5082       AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
 5083     if (&pccb->senseLen & 0x63)
 5084       AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
 5085     if (&pccb->numSgElements & 0x63)
 5086       AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
 5087     if (&pccb->retryCount & 0x63)
 5088       AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
 5089     if (&pccb->flags & 0x63)
 5090       AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
 5091     if (&pccb->pSenseData & 0x63)
 5092       AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
 5093     if (&pccb->sgList[0] & 0x63)
 5094       AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
 5095     if (&pccb->pccbNext & 0x63)
 5096       AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
 5097     if (&pccb->pccbChainNext & 0x63)
 5098       AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
 5099     if (&pccb->cmd & 0x63)
 5100       AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
 5101     if( &pccb->startTime & 0x63 )
 5102       AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
 5103     if (&pccb->tiIORequest & 0x63)
 5104       AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
 5105     if (&pccb->tdIOReqBody & 0x63)
 5106       AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
 5107     if (&pccb->tiSuperScsiRequest & 0x63)
 5108       AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
 5109                       &pccb->tiSuperScsiRequest );
 5110 #endif
 5111     if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
 5112          tiSuccess)
 5113     {
 5114       AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
 5115       return;
 5116     }      
 5117     /* assigns tiSgl_t memory to pccb */
 5118     pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
 5119     pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
 5120     pccb->ccb = NULL;      
 5121     pccb->pccbIO = NULL;      
 5122     pccb->startTime = 0;
 5123   }
 5124 
 5125 #ifdef AGTIAPI_ALIGN_CHECK
 5126   AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
 5127 #endif
 5128   return;
 5129 }
 5130 
 5131 /******************************************************************************
 5132 agtiapi_InitCCBs()
 5133 
 5134 Purpose:
 5135   Create and initialize per card based CCB pool.
 5136 Parameters: 
 5137   struct agtiapi_softc *pCard (IN)  Pointer to the HBA data structure
 5138   int tgtCount (IN)                 Count
 5139 Return:
 5140   Total number of ccb allocated
 5141 Note:    
 5142 ******************************************************************************/
 5143 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
 5144 {
 5145 
 5146   U32   max_ccb, size, ccb_sz, hdr_sz;
 5147   int   no_allocs = 0, i;
 5148   ccb_hdr_t  *hdr = NULL;
 5149 
 5150   AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
 5151   AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
 5152   AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
 5153 
 5154 #ifndef HOTPLUG_SUPPORT
 5155   if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
 5156     return 1;
 5157 #else
 5158   if (tgtCount > AGSA_MAX_INBOUND_Q)
 5159     tgtCount = AGSA_MAX_INBOUND_Q;
 5160 #endif
 5161 
 5162   max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;//      / 4; // TBR
 5163   ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
 5164   hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
 5165   size = ccb_sz * max_ccb + hdr_sz;
 5166   
 5167   for (i = 0; i < (1 << no_allocs); i++) 
 5168   {
 5169     hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
 5170     if( !hdr )
 5171     {
 5172       panic( "agtiapi_InitCCBs: bug!!!\n" );
 5173     }
 5174     else
 5175     {
 5176       agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
 5177     }
 5178   }
 5179 
 5180   return 1;
 5181 
 5182 }
 5183 
 5184 
 5185 #ifdef LINUX_PERBI_SUPPORT
 5186 /******************************************************************************
 5187 agtiapi_GetWWNMappings()
 5188 
 5189 Purpose:
 5190   Get the mappings from target IDs to WWNs, if any.
 5191   Store them in the WWN_list array, indexed by target ID.
 5192   Leave the devListIndex field blank; this will be filled-in later.
 5193 Parameters:
 5194   ag_card_t *pCard (IN)        Pointer to HBA data structure
 5195   ag_mapping_t *pMapList (IN)  Pointer to mapped device list
 5196 Return:
 5197 Note:  The boot command line parameters are used to load the
 5198   mapping information, which is contained in the system
 5199   configuration file.
 5200 ******************************************************************************/
 5201 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
 5202                                     ag_mapping_t         *pMapList )
 5203 {
 5204   int           devDisc;
 5205   int           lIdx = 0;
 5206   ag_tgt_map_t *pWWNList;
 5207   ag_slr_map_t *pSLRList;
 5208   ag_device_t  *pDevList;
 5209 
 5210   if( !pCard )
 5211     panic( "agtiapi_GetWWNMappings: no pCard \n" );
 5212 
 5213   AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
 5214 
 5215   pWWNList = pCard->pWWNList;
 5216   pSLRList = pCard->pSLRList;
 5217   pDevList = pCard->pDevList;
 5218   pCard->numTgtHardMapped = 0;
 5219   devDisc = pCard->devDiscover;
 5220 
 5221   pWWNList[devDisc-1].devListIndex  = maxTargets;
 5222   pSLRList[devDisc-1].localeNameLen = -2;
 5223   pSLRList[devDisc-1].remoteNameLen = -2;
 5224   pDevList[devDisc-1].targetId      = maxTargets;
 5225 
 5226   /*
 5227    * Get the mappings from holding area which contains
 5228    * the input of the system file and store them
 5229    * in the WWN_list array, indexed by target ID.
 5230    */
 5231   for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
 5232     pWWNList[lIdx].flags = 0;
 5233     pWWNList[lIdx].devListIndex  = maxTargets;
 5234     pSLRList[lIdx].localeNameLen = -1;
 5235     pSLRList[lIdx].remoteNameLen = -1;
 5236   }
 5237 
 5238   //  this is where we would propagate values fed to pMapList
 5239 
 5240 } /* agtiapi_GetWWNMappings */
 5241 
 5242 #endif
 5243 
 5244 
 5245 /******************************************************************************
 5246 agtiapi_FindWWNListNext()
 5247 Purpose:
 5248   finds first available new (unused) wwn list entry
 5249 
 5250 Parameters:
 5251   ag_tgt_map_t *pWWNList              Pointer to head of wwn list
 5252   int lstMax                          Number of entries in WWNList
 5253 Return:
 5254   index into WWNList indicating available entry space;
 5255   if available entry space is not found, return negative value
 5256 ******************************************************************************/
 5257 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
 5258 {
 5259   int  lLstIdx;
 5260 
 5261   for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
 5262   {
 5263     if ( pWWNList[lLstIdx].devListIndex == lstMax &&
 5264          pWWNList[lLstIdx].targetLen == 0 )
 5265     {
 5266       AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
 5267                       lLstIdx,
 5268                       pWWNList[lLstIdx].devListIndex,
 5269                       pWWNList[lLstIdx].targetLen,
 5270                       pWWNList[lLstIdx].portId,
 5271                       lstMax );
 5272       return lLstIdx;
 5273     }
 5274   }
 5275   return -1;
 5276 }
 5277 
 5278 
 5279 /******************************************************************************
 5280 agtiapi_GetDevHandle()
 5281 
 5282 Purpose:
 5283   Get device handle.  Handles will be placed in the
 5284   devlist array with same order as TargetList provided and
 5285   will be mapped to a scsi target id and registered to OS later.
 5286 Parameters:
 5287   struct agtiapi_softc *pCard (IN)    Pointer to the HBA data structure
 5288   ag_portal_info_t *pPortalInfo (IN)  Pointer to the portal data structure
 5289   U32 eType (IN)                      Port event
 5290   U32 eStatus (IN)                    Port event status
 5291 Return:
 5292   Number of device handle slot present
 5293 Note:
 5294   The sequence of device handle will match the sequence of taregt list
 5295 ******************************************************************************/
 5296 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
 5297                                  ag_portal_info_t *pPortalInfo,
 5298                                  U32 eType,
 5299                                  U32 eStatus )
 5300 {
 5301   ag_device_t       *pDevice;
 5302   // tiDeviceHandle_t *agDev[pCard->devDiscover];
 5303   tiDeviceHandle_t **agDev;
 5304   int                devIdx, szdv, devTotal, cmpsetRtn;
 5305   int                lDevIndex = 0, lRunScanFlag = FALSE;
 5306   int               *lDevFlags;
 5307   tiPortInfo_t       portInfT;
 5308   ag_device_t        lTmpDevice;
 5309   ag_tgt_map_t      *pWWNList;
 5310   ag_slr_map_t      *pSLRList;
 5311   bit32              lReadRm;
 5312   bit16              lReadCt;
 5313 
 5314 
 5315   AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
 5316   AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
 5317                   pCard->devDiscover, pCard->tgtCount );
 5318   AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
 5319   AGTIAPI_INIT_DELAY( 1000 );
 5320 
 5321   agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
 5322                                         M_PMC_MDEV, M_ZERO | M_NOWAIT);
 5323   if (agDev == NULL) 
 5324   {
 5325     AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
 5326     return 0;
 5327   }
 5328 
 5329   lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
 5330                               M_PMC_MFLG, M_ZERO | M_NOWAIT );
 5331   if (lDevFlags == NULL)
 5332   {
 5333     free((caddr_t)agDev, M_PMC_MDEV);
 5334     AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
 5335     return 0;
 5336   }
 5337 
 5338   pWWNList = pCard->pWWNList;
 5339   pSLRList = pCard->pSLRList;
 5340 
 5341   memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
 5342   memset( lDevFlags,     0, sizeof(int)    * pCard->devDiscover );
 5343 
 5344   // get device handles
 5345   devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
 5346                                     &pPortalInfo->tiPortalContext,
 5347                                     (tiDeviceHandle_t **)agDev,
 5348                                     pCard->devDiscover );
 5349 
 5350   AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
 5351                   "status %u card %p pCard->devDiscover %d devTotal %d "
 5352                   "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
 5353                   "AGTIAPI_INIT_TIME %x\n",
 5354                   pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
 5355                   pCard->devDiscover, devTotal, pPortalInfo->devTotal,
 5356                   pPortalInfo->devPrev,
 5357                   pCard->flags & AGTIAPI_INIT_TIME );
 5358 
 5359   // reset devTotal from any previous runs of this
 5360   pPortalInfo->devPrev  = devTotal;
 5361   pPortalInfo->devTotal = devTotal;
 5362 
 5363   AG_LIST_LOCK( &pCard->devListLock );
 5364 
 5365   if ( tiCOMGetPortInfo( &pCard->tiRoot,
 5366                          &pPortalInfo->tiPortalContext,
 5367                          &portInfT )
 5368        != tiSuccess)
 5369   {
 5370     AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
 5371   }
 5372 
 5373 
 5374   szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
 5375   if (szdv > pCard->devDiscover)
 5376   {
 5377     szdv = pCard->devDiscover;
 5378   }
 5379 
 5380   // reconstructing dev list via comparison of wwn
 5381 
 5382   for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
 5383   {
 5384     if ( agDev[devIdx] != NULL )
 5385     {
 5386       // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
 5387       //                 devIdx, agDev[devIdx] );
 5388 
 5389       // pack temp device structure for tiINIGetDeviceInfo call
 5390       pDevice                  = &lTmpDevice;
 5391       pDevice->devType         = DIRECT_DEVICE;
 5392       pDevice->pCard           = (void *)pCard;
 5393       pDevice->flags           = ACTIVE;
 5394       pDevice->pPortalInfo     = pPortalInfo;
 5395       pDevice->pDevHandle      = agDev[devIdx];
 5396       pDevice->qbusy           = agFALSE; 
 5397 
 5398       //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
 5399       //                devIdx, pCard->devDiscover, agDev[devIdx] );
 5400 
 5401       tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
 5402                           &pDevice->devInfo );
 5403 
 5404       //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
 5405       //                sizeof(pDevice->targetName),
 5406       //                pDevice->devInfo.osAddress1,
 5407       //                pDevice->devInfo.osAddress2 );
 5408 
 5409       wwncpy( pDevice );
 5410       wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
 5411 
 5412       for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
 5413       {
 5414         if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
 5415              pDevice->targetLen     > 0 &&
 5416              portInfT.localNameLen  > 0 &&
 5417              portInfT.remoteNameLen > 0 &&
 5418              pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
 5419              pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
 5420              ( portInfT.localNameLen ==
 5421                pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
 5422              ( portInfT.remoteNameLen ==
 5423                pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
 5424              memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
 5425                      pDevice->targetLen )   == 0  &&
 5426              memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
 5427                      portInfT.localName,
 5428                      portInfT.localNameLen )   == 0  &&
 5429              memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
 5430                      portInfT.remoteName,
 5431                      portInfT.remoteNameLen )   == 0  )
 5432         {
 5433           AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
 5434                           lDevIndex, devIdx, pPortalInfo->portID );
 5435 
 5436           if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
 5437                ( pPortalInfo->pDevList[lDevIndex] ==
 5438                  &pCard->pDevList[lDevIndex] )  ) // active
 5439           {
 5440 
 5441             AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
 5442                             lDevIndex, devTotal, pPortalInfo->portID );
 5443             lDevFlags[devIdx]    |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
 5444             lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
 5445             lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
 5446             if ( lReadRm )   // cleared timeout, now remove count for timer
 5447             {
 5448               AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
 5449                               " %d of %d\n",
 5450                               lDevIndex, pPortalInfo->portID );
 5451               atomic_subtract_16( &pCard->rmChkCt, 1 );
 5452               lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
 5453               if ( 0 == lReadCt )
 5454               {
 5455                 callout_stop( &pCard->devRmTimer );
 5456               }
 5457             }
 5458             break;
 5459           }
 5460 
 5461           AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
 5462                           lDevIndex,  // reactivate now
 5463                           devTotal, pPortalInfo->portID );
 5464 
 5465           // pDevice going fresh
 5466           lRunScanFlag = TRUE; // scan and clear outstanding removals
 5467 
 5468           // pCard->tgtCount++; ##
 5469           pDevice->targetId  = lDevIndex;
 5470           pDevice->portalId  = pPortalInfo->portID;
 5471 
 5472           memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
 5473           agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
 5474           if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
 5475           {
 5476             AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
 5477                             "tgtCnt %d ERROR!\n", pCard->tgtCount );
 5478             AG_LIST_UNLOCK( &pCard->devListLock );
 5479             free((caddr_t)lDevFlags, M_PMC_MFLG);
 5480             free((caddr_t)agDev, M_PMC_MDEV);
 5481             return 0;
 5482           }
 5483           pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex];     // (ag_device_t *)
 5484           if ( 0 == lDevFlags[devIdx] )
 5485           {
 5486             pPortalInfo->devTotal++;
 5487             lDevFlags[devIdx]    |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
 5488             lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
 5489           }
 5490           else
 5491           {
 5492             AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
 5493                             "status inspect %d %d %d\n",
 5494                             lDevFlags[devIdx], devIdx, lDevIndex );
 5495             pPortalInfo->devTotal++;
 5496             lDevFlags[devIdx]    |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
 5497             lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
 5498 
 5499           }
 5500           break;
 5501         }
 5502       }
 5503       // end: match this wwn with previous wwn list
 5504 
 5505       // we have an agDev entry, but no pWWNList target for it
 5506       if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
 5507       { // flag dev handle not accounted for yet
 5508         lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
 5509         // later, get an empty pDevice and map this agDev.
 5510         // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
 5511         //                 devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
 5512       }
 5513     }
 5514     else
 5515     {
 5516       lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
 5517     }
 5518   }
 5519 
 5520   // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
 5521   //                 "devLstIdx/flags/(WWNL)portId ... \n" );
 5522   // review device list for further action needed
 5523   for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
 5524   {
 5525     if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
 5526     {
 5527       int lNextDyad; // find next available dyad entry
 5528 
 5529       AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
 5530                       "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
 5531       lRunScanFlag = TRUE; // scan and clear outstanding removals
 5532       for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
 5533       {
 5534         if ( pSLRList[lNextDyad].localeNameLen < 0 &&
 5535              pSLRList[lNextDyad].remoteNameLen < 0    )
 5536           break;
 5537       }
 5538 
 5539       if ( lNextDyad == pCard->devDiscover )
 5540       {
 5541         printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
 5542         AG_LIST_UNLOCK( &pCard->devListLock );
 5543         free( (caddr_t)lDevFlags, M_PMC_MFLG );
 5544         free( (caddr_t)agDev, M_PMC_MDEV );
 5545         return 0;
 5546       }
 5547       // index of new entry
 5548       lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
 5549       AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
 5550                       lDevIndex, devTotal, pPortalInfo->portID );
 5551       if ( 0 > lDevIndex )
 5552       {
 5553         printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
 5554         continue;
 5555       }
 5556 
 5557       pDevice = &pCard->pDevList[lDevIndex];
 5558 
 5559       tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
 5560       wwncpy( pDevice );
 5561       agtiapi_InitCCBs( pCard, 1, lDevIndex );
 5562 
 5563       pDevice->pCard   = (void *)pCard;
 5564       pDevice->devType = DIRECT_DEVICE;
 5565 
 5566       // begin to populate new WWNList entry
 5567       memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
 5568       pWWNList[lDevIndex].targetLen = pDevice->targetLen;
 5569 
 5570       pWWNList[lDevIndex].flags         = SOFT_MAPPED;
 5571       pWWNList[lDevIndex].portId        = pPortalInfo->portID;
 5572       pWWNList[lDevIndex].devListIndex  = lDevIndex;
 5573       pWWNList[lDevIndex].sasLrIdx      = lNextDyad;
 5574 
 5575       pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
 5576       pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
 5577       memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
 5578       memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
 5579       // end of populating new WWNList entry
 5580 
 5581       pDevice->targetId = lDevIndex;
 5582 
 5583       pDevice->flags = ACTIVE;
 5584       pDevice->CCBCount = 0; 
 5585       pDevice->pDevHandle = agDev[devIdx];
 5586       agDev[devIdx]->osData = (void*)pDevice;
 5587 
 5588       pDevice->pPortalInfo = pPortalInfo;
 5589       pDevice->portalId = pPortalInfo->portID;
 5590       pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
 5591       lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
 5592     }
 5593 
 5594     if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
 5595          !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
 5596     {
 5597       pDevice = &pCard->pDevList[devIdx];
 5598       //pDevice->flags &= ~ACTIVE;
 5599       if ( ( pDevice->pDevHandle != NULL ||
 5600              pPortalInfo->pDevList[devIdx] != NULL ) )
 5601       {
 5602         atomic_add_16( &pCard->rmChkCt, 1 );      // show count of lost device
 5603 
 5604         if (FALSE == lRunScanFlag)
 5605         {
 5606 
 5607           AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
 5608                           devIdx, devTotal, pPortalInfo->portID );
 5609           // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
 5610           cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
 5611           if ( 0 == cmpsetRtn )
 5612           {
 5613             AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
 5614                     devIdx );
 5615           }
 5616           else
 5617           {
 5618             callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
 5619           }
 5620         }
 5621         // else ... scan coming soon enough anyway, ignore timer for dropout
 5622       }
 5623     }
 5624   } // end of for ( devIdx = 0; ...
 5625 
 5626   AG_LIST_UNLOCK( &pCard->devListLock );
 5627 
 5628   free((caddr_t)lDevFlags, M_PMC_MFLG);
 5629   free((caddr_t)agDev, M_PMC_MDEV);
 5630 
 5631   if ( TRUE == lRunScanFlag )
 5632     agtiapi_clrRmScan( pCard );
 5633 
 5634   return devTotal;
 5635 } // end  agtiapi_GetDevHandle
 5636 
 5637 /******************************************************************************
 5638 agtiapi_scan()
 5639 
 5640 Purpose:
 5641   Triggers CAM's scan
 5642 Parameters: 
 5643   struct agtiapi_softc *pCard (IN)    Pointer to the HBA data structure
 5644 Return:
 5645 Note:    
 5646 ******************************************************************************/
 5647 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
 5648 {
 5649   union ccb *ccb;
 5650   int bus, tid, lun;
 5651  
 5652   AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
 5653     
 5654   bus = cam_sim_path(pmcsc->sim);
 5655  
 5656   tid = CAM_TARGET_WILDCARD;
 5657   lun = CAM_LUN_WILDCARD;
 5658 
 5659   mtx_lock(&(pmcsc->pCardInfo->pmIOLock)); 
 5660   ccb = xpt_alloc_ccb_nowait();
 5661   if (ccb == agNULL)
 5662   {
 5663     mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 
 5664     return;
 5665   }
 5666   if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
 5667                       CAM_LUN_WILDCARD) != CAM_REQ_CMP) 
 5668   { 
 5669     mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 
 5670     xpt_free_ccb(ccb);
 5671     return;
 5672   }
 5673 
 5674   mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 
 5675   pmcsc->dev_scan = agTRUE;
 5676   xpt_rescan(ccb);
 5677   return;
 5678 }
 5679 
 5680 /******************************************************************************
 5681 agtiapi_DeQueueCCB()
 5682 
 5683 Purpose:
 5684   Remove a ccb from a queue
 5685 Parameters: 
 5686   struct agtiapi_softc *pCard (IN)  Pointer to the card structure
 5687   pccb_t *phead (IN)     Pointer to a head of ccb queue
 5688   ccb_t  *pccd  (IN)     Pointer to the ccb to be processed
 5689 Return:
 5690   AGTIAPI_SUCCESS - the ccb is removed from queue
 5691   AGTIAPI_FAIL    - the ccb is not found from queue
 5692 Note:    
 5693 ******************************************************************************/
 5694 STATIC agBOOLEAN 
 5695 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail, 
 5696 #ifdef AGTIAPI_LOCAL_LOCK
 5697                    struct mtx *lock,
 5698 #endif
 5699                    ccb_t *pccb)
 5700 {
 5701   ccb_t  *pccb_curr;
 5702   U32     status = AGTIAPI_FAIL;
 5703 
 5704   AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
 5705 
 5706   if (pccb == NULL || *phead == NULL)
 5707   {
 5708     return AGTIAPI_FAIL;
 5709   }
 5710 
 5711   AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
 5712   AG_LOCAL_LOCK(lock);
 5713 
 5714   if (pccb == *phead)
 5715   {
 5716     *phead = (*phead)->pccbNext;
 5717     if (pccb == *ptail)
 5718     {
 5719       *ptail = NULL;
 5720     }
 5721     else
 5722       pccb->pccbNext = NULL;
 5723     status = AGTIAPI_SUCCESS;
 5724   }
 5725   else
 5726   {
 5727     pccb_curr = *phead;
 5728     while (pccb_curr->pccbNext != NULL)
 5729     {
 5730       if (pccb_curr->pccbNext == pccb)
 5731       {
 5732         pccb_curr->pccbNext = pccb->pccbNext;
 5733         pccb->pccbNext = NULL;
 5734         if (pccb == *ptail)
 5735         {
 5736           *ptail = pccb_curr;
 5737         }
 5738         else
 5739           pccb->pccbNext = NULL;
 5740         status = AGTIAPI_SUCCESS;
 5741         break;
 5742       }
 5743       pccb_curr = pccb_curr->pccbNext;
 5744     }
 5745   }
 5746   AG_LOCAL_UNLOCK(lock);
 5747 
 5748   return status;
 5749 }
 5750 
 5751 
 5752 STATIC void wwnprintk( unsigned char *name, int len )
 5753 {
 5754   int i;
 5755 
 5756   for (i = 0; i < len; i++, name++)
 5757     AGTIAPI_PRINTK("%02x", *name); 
 5758   AGTIAPI_PRINTK("\n");
 5759 }
 5760 /* 
 5761  * SAS and SATA behind expander has 8 byte long unique address. 
 5762  * However, direct connect SATA device use 512 byte unique device id.
 5763  * SPC uses remoteName to indicate length of ID and remoteAddress for the
 5764  * address of memory that holding ID.
 5765  */ 
 5766 STATIC int wwncpy( ag_device_t      *pDevice )
 5767 {
 5768   int rc = 0;
 5769 
 5770   if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 + 
 5771                                      pDevice->devInfo.osAddress2) 
 5772   {
 5773     memcpy(pDevice->targetName, 
 5774              pDevice->devInfo.remoteName, 
 5775              pDevice->devInfo.osAddress1);
 5776     memcpy(pDevice->targetName + pDevice->devInfo.osAddress1, 
 5777              pDevice->devInfo.remoteAddress, 
 5778              pDevice->devInfo.osAddress2);
 5779     pDevice->targetLen = pDevice->devInfo.osAddress1 + 
 5780                          pDevice->devInfo.osAddress2;
 5781     rc = pDevice->targetLen;
 5782   }
 5783   else 
 5784   {
 5785     AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n", 
 5786            pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
 5787     rc = -1;
 5788   }
 5789   return rc;
 5790 }
 5791 
 5792 
 5793 /******************************************************************************
 5794 agtiapi_ReleaseCCBs()
 5795 
 5796 Purpose:
 5797   Free all allocated CCB memories for the Host Adapter.
 5798 Parameters:
 5799   struct agtiapi_softc *pCard (IN)  Pointer to HBA data structure
 5800 Return:
 5801 Note:
 5802 ******************************************************************************/
 5803 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
 5804 {
 5805 
 5806   ccb_hdr_t *hdr;
 5807   U32 hdr_sz;
 5808   ccb_t *pccb = NULL;
 5809 
 5810   AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
 5811 
 5812 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
 5813   ccb_t *pccb;
 5814 #endif
 5815 
 5816 #ifdef AGTIAPI_TEST_DPL
 5817   for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
 5818        pccb = pccb->pccbChainNext)
 5819   {
 5820     if(pccb->dplPtr && pccb->dplDma)
 5821       pci_pool_free(pCard->dpl_ctx_pool,   pccb->dplPtr, pccb->dplDma);
 5822   }
 5823 #endif
 5824 
 5825 #ifdef AGTIAPI_TEST_EPL
 5826   for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
 5827        pccb = pccb->pccbChainNext)
 5828   {
 5829     if(pccb->epl_ptr && pccb->epl_dma_ptr)
 5830         pci_pool_free(
 5831             pCard->epl_ctx_pool,
 5832             pccb->epl_ptr, 
 5833             pccb->epl_dma_ptr
 5834         );
 5835   }
 5836 #endif
 5837 
 5838   while ((hdr = pCard->ccbAllocList) != NULL)
 5839   {
 5840     pCard->ccbAllocList = hdr->next;
 5841     hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
 5842     pccb = (ccb_t*) ((char*)hdr + hdr_sz);
 5843     if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
 5844     {
 5845       bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
 5846     }
 5847     free(hdr, M_PMC_MCCB);
 5848   }
 5849   pCard->ccbAllocList = NULL;
 5850 
 5851 
 5852   return;
 5853 }
 5854 
 5855 /******************************************************************************
 5856 agtiapi_TITimer()
 5857 
 5858 Purpose:
 5859   Timer tick for tisa common layer
 5860 Parameters:
 5861   void *data (IN)  Pointer to the HBA data structure
 5862 Return:
 5863 Note:
 5864 ******************************************************************************/
 5865 STATIC void agtiapi_TITimer( void *data )
 5866 {
 5867 
 5868   U32                   next_tick;
 5869   struct agtiapi_softc *pCard;
 5870 
 5871   pCard = (struct agtiapi_softc *)data;
 5872 
 5873 //  AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
 5874   AG_GLOBAL_ARG( flags );
 5875 
 5876   next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
 5877               loLevelOption.usecsPerTick / USEC_PER_TICK;
 5878 
 5879   if( next_tick == 0 )               /* no timer required */
 5880     return;
 5881   AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
 5882   if( pCard->flags & AGTIAPI_SHUT_DOWN )
 5883     goto ext;
 5884   tiCOMTimerTick( &pCard->tiRoot );  /* tisa common layer timer tick */
 5885 
 5886   //add for polling mode
 5887 #ifdef PMC_SPC
 5888   if( agtiapi_polling_mode )
 5889     agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
 5890 #endif
 5891   callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
 5892 ext:
 5893   AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 5894   return;
 5895 }
 5896 
 5897 /******************************************************************************
 5898 agtiapi_clrRmScan()
 5899 
 5900 Purpose:
 5901   Clears device list entries scheduled for timeout and calls scan
 5902 Parameters:
 5903   struct agtiapi_softc *pCard (IN)  Pointer to HBA data structure
 5904 ******************************************************************************/
 5905 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
 5906 {
 5907   ag_tgt_map_t         *pWWNList;
 5908   ag_portal_info_t     *pPortalInfo;
 5909   ag_portal_data_t     *pPortalData;
 5910   int                   lIdx;
 5911   bit32                 lReadRm;
 5912   bit16                 lReadCt;
 5913 
 5914   pWWNList = pCard->pWWNList;
 5915 
 5916   AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
 5917 
 5918   AG_LIST_LOCK( &pCard->devListLock );
 5919 
 5920   for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
 5921   {
 5922     lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
 5923     if ( 0 == lReadCt )
 5924     {
 5925       break;  // trim to who cares
 5926     }
 5927 
 5928     lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
 5929     if ( lReadRm > 0 )
 5930     {
 5931       pCard->pDevList[lIdx].flags &= ~ACTIVE;
 5932       pCard->pDevList[lIdx].pDevHandle = NULL;
 5933 
 5934       pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
 5935       pPortalInfo = &pPortalData->portalInfo;
 5936       pPortalInfo->pDevList[lIdx] = NULL;
 5937       AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
 5938                       lIdx, pWWNList[lIdx].portId );
 5939       atomic_subtract_16( &pCard->rmChkCt, 1 );
 5940     }
 5941   }
 5942   AG_LIST_UNLOCK( &pCard->devListLock );
 5943 
 5944   agtiapi_scan( pCard );
 5945 }
 5946 
 5947 
 5948 /******************************************************************************
 5949 agtiapi_devRmCheck()
 5950 
 5951 Purpose:
 5952   Timer tick to check for timeout on missing targets
 5953   Removes device list entry when timeout is reached
 5954 Parameters:
 5955   void *data (IN)  Pointer to the HBA data structure
 5956 ******************************************************************************/
 5957 STATIC void agtiapi_devRmCheck( void *data )
 5958 {
 5959   struct agtiapi_softc *pCard;
 5960   ag_tgt_map_t         *pWWNList;
 5961   int                   lIdx, cmpsetRtn, lRunScanFlag = FALSE;
 5962   bit16                 lReadCt;
 5963   bit32                 lReadRm;
 5964 
 5965   pCard = ( struct agtiapi_softc * )data;
 5966 
 5967   // routine overhead
 5968   if ( callout_pending( &pCard->devRmTimer ) )  // callout was reset
 5969   {
 5970     return;
 5971   }
 5972   if ( !callout_active( &pCard->devRmTimer ) )  // callout was stopped
 5973   {
 5974     return;
 5975   }
 5976   callout_deactivate( &pCard->devRmTimer );
 5977 
 5978   if( pCard->flags & AGTIAPI_SHUT_DOWN )
 5979   {
 5980     return;  // implicit timer clear
 5981   }
 5982 
 5983   pWWNList = pCard->pWWNList;
 5984 
 5985   AG_LIST_LOCK( &pCard->devListLock );
 5986   lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
 5987   if ( lReadCt )
 5988   {
 5989     if ( callout_pending(&pCard->devRmTimer) == FALSE )
 5990     {
 5991       callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
 5992     }
 5993     else
 5994     {
 5995       AG_LIST_UNLOCK( &pCard->devListLock );
 5996           return;
 5997     }
 5998 
 5999     for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
 6000     {
 6001       lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
 6002       if ( 0 == lReadCt )
 6003       {
 6004         break;  // if handled somewhere else, get out
 6005       }
 6006 
 6007       lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
 6008       if ( lReadRm > 0 )
 6009       {
 6010         if ( 1 == lReadRm ) // timed out
 6011         { // no decrement of devRemoved as way to leave a clrRmScan marker
 6012           lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
 6013           break; // ... so bail out
 6014         }
 6015         else
 6016         {
 6017           AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
 6018                           lIdx, lReadRm, lReadCt );
 6019           cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
 6020                                         lReadRm,
 6021                                         lReadRm-1 );
 6022           if ( 0 == cmpsetRtn )
 6023           {
 6024             printf( "agtiapi_devRmCheck: %d decrement already handled\n",
 6025                     lIdx );
 6026           }
 6027         }
 6028       }
 6029     }
 6030     AG_LIST_UNLOCK( &pCard->devListLock );
 6031 
 6032     if ( TRUE == lRunScanFlag )
 6033       agtiapi_clrRmScan( pCard );
 6034   }
 6035   else
 6036   {
 6037     AG_LIST_UNLOCK( &pCard->devListLock );
 6038   }
 6039 
 6040   return;
 6041 }
 6042 
 6043 
 6044 static void agtiapi_cam_poll( struct cam_sim *asim )
 6045 {
 6046   return;
 6047 }
 6048 
 6049 /*****************************************************************************
 6050 agtiapi_ResetCard()
 6051 
 6052 Purpose:
 6053   Hard or soft reset on the controller and resend any
 6054   outstanding requests if needed.
 6055 Parameters:
 6056   struct agtiapi_softc *pCard (IN)  Pointer to HBA data structure
 6057   unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
 6058 Return:
 6059   AGTIAPI_SUCCESS - reset successful
 6060   AGTIAPI_FAIL    - reset failed
 6061 Note:
 6062 *****************************************************************************/
 6063 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
 6064 {
 6065   ag_device_t      *pDevice;
 6066   U32               lIdx = 0;
 6067   U32               lFlagVal;
 6068   agBOOLEAN         ret;
 6069   ag_portal_info_t *pPortalInfo;
 6070   ag_portal_data_t *pPortalData;
 6071   U32               count, loop;
 6072   int               szdv;
 6073 
 6074   if( pCard->flags & AGTIAPI_RESET ) {
 6075     AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
 6076     return AGTIAPI_FAIL;
 6077   }
 6078 
 6079   AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
 6080                   pCard->resetCount );
 6081 #ifdef LOGEVENT
 6082   agtiapi_LogEvent( pCard,
 6083                     IOCTL_EVT_SEV_INFORMATIONAL,
 6084                     0,
 6085                     agNULL,
 6086                     0,
 6087                     "Reset initiator time = %d!",
 6088                     pCard->resetCount + 1 );
 6089 #endif
 6090 
 6091   pCard->flags |= AGTIAPI_RESET;
 6092   pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
 6093   tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
 6094   pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
 6095 
 6096   agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
 6097 
 6098   for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
 6099   {
 6100     if( pCard->flags & AGTIAPI_SOFT_RESET )
 6101     {
 6102       AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
 6103       tiCOMReset( &pCard->tiRoot, tiSoftReset );
 6104     }
 6105     else
 6106     {
 6107       AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
 6108     }
 6109 
 6110     lFlagVal = AGTIAPI_RESET_SUCCESS;
 6111     AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
 6112     ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
 6113     AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
 6114 
 6115     if( ret == AGTIAPI_FAIL )
 6116     {
 6117       AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
 6118               "try again?\n" );
 6119     }
 6120     else
 6121     {
 6122       break;
 6123     }
 6124   }
 6125   if ( 1 < lIdx )
 6126   {
 6127     if ( AGTIAPI_FAIL == ret )
 6128     {
 6129       AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
 6130                       lIdx );
 6131     }
 6132     else
 6133     {
 6134       AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
 6135                       lIdx );
 6136     }
 6137   }
 6138   if( AGTIAPI_FAIL == ret )
 6139   {
 6140     printf( "agtiapi_ResetCard: reset ERROR\n" );
 6141     pCard->flags &= ~AGTIAPI_INSTALLED;
 6142     return AGTIAPI_FAIL;
 6143   }
 6144 
 6145   pCard->flags &= ~AGTIAPI_SOFT_RESET;
 6146 
 6147   // disable all devices
 6148   pDevice = pCard->pDevList;
 6149   for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
 6150   {
 6151     /* if ( pDevice->flags & ACTIVE )
 6152     {
 6153       printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
 6154     } */
 6155     pDevice->flags &= ~ACTIVE;
 6156   }
 6157 
 6158   AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
 6159   if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
 6160     printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
 6161   else
 6162     AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
 6163 
 6164   if( !pCard->pDevList ) {  // try to get a little sanity here
 6165     AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
 6166                     pCard->pDevList );
 6167     return AGTIAPI_FAIL;
 6168   }
 6169 
 6170   AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
 6171                   pCard->tgtCount, pCard->portCount );
 6172   pCard->tgtCount = 0;
 6173 
 6174   DELAY( 500000 );
 6175 
 6176   pCard->flags &= ~AGTIAPI_CB_DONE;
 6177 
 6178   pPortalData = pCard->pPortalData;
 6179 
 6180   for( count = 0; count < pCard->portCount; count++ ) {
 6181     AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
 6182     pPortalInfo = &pPortalData->portalInfo;
 6183     pPortalInfo->portStatus = 0;
 6184     pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START      |
 6185                                   AGTIAPI_PORT_DISC_READY |
 6186                                   AGTIAPI_DISC_DONE       |
 6187                                   AGTIAPI_DISC_COMPLETE );
 6188 
 6189     szdv =
 6190       sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
 6191     if (szdv > pCard->devDiscover)
 6192     {
 6193       szdv = pCard->devDiscover;
 6194     }
 6195     
 6196     for( lIdx = 0, loop = 0;
 6197          lIdx < szdv  &&  loop < pPortalInfo->devTotal;
 6198          lIdx++ )
 6199     {
 6200       pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
 6201       if( pDevice )
 6202       {
 6203         loop++;
 6204         pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
 6205         // don't erase more as the device is scheduled for removal on DPC
 6206       }
 6207       AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
 6208                       pDevice, pPortalInfo->pDevList, lIdx );
 6209       pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
 6210     }
 6211 
 6212     for( lIdx = 0; lIdx < maxTargets; lIdx++ )
 6213     { // we reconstruct dev list later in get dev handle
 6214       pPortalInfo->pDevList[lIdx] = NULL;
 6215     }
 6216 
 6217     for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
 6218     {
 6219       AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
 6220                       "%p / %d / %p\n",
 6221                       &pCard->tiRoot,
 6222                       pPortalInfo->portID,
 6223                       &pPortalInfo->tiPortalContext );
 6224 
 6225       if( tiCOMPortStart( &pCard->tiRoot,
 6226                           pPortalInfo->portID,
 6227                           &pPortalInfo->tiPortalContext,
 6228                           0 )
 6229           != tiSuccess )
 6230       {
 6231         printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
 6232                 pPortalInfo->portID );
 6233       }
 6234       else
 6235       {
 6236         AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
 6237                         pPortalInfo->portID );
 6238         break;
 6239       }
 6240     }
 6241     AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 6242     tiCOMGetPortInfo( &pCard->tiRoot,
 6243                       &pPortalInfo->tiPortalContext,
 6244                       &pPortalInfo->tiPortInfo );
 6245     pPortalData++;
 6246   }
 6247   // ## fail case:  pCard->flags &= ~AGTIAPI_INSTALLED;
 6248 
 6249 
 6250   AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
 6251 
 6252   if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
 6253   {
 6254     printf( "agtiapi_ResetCard: error, driver not intstalled? "
 6255             "!AGTIAPI_INSTALLED \n" );
 6256     return AGTIAPI_FAIL;
 6257   }
 6258 
 6259   AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
 6260 
 6261 #ifdef LOGEVENT
 6262   agtiapi_LogEvent( pCard,
 6263                     IOCTL_EVT_SEV_INFORMATIONAL,
 6264                     0,
 6265                     agNULL,
 6266                     0,
 6267                     "Reset initiator total device = %d!",
 6268                     pCard->tgtCount );
 6269 #endif
 6270   pCard->resetCount++;
 6271 
 6272   AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
 6273   // clear send & done queue
 6274   AG_LOCAL_LOCK( &pCard->sendLock );
 6275   pCard->ccbSendHead = NULL;
 6276   pCard->ccbSendTail = NULL;
 6277   AG_LOCAL_UNLOCK( &pCard->sendLock );
 6278 
 6279   AG_LOCAL_LOCK( &pCard->doneLock );
 6280   pCard->ccbDoneHead = NULL;
 6281   pCard->ccbDoneTail = NULL;
 6282   AG_LOCAL_UNLOCK( &pCard->doneLock );
 6283 
 6284   // clear smp queues also
 6285   AG_LOCAL_LOCK( &pCard->sendSMPLock );
 6286   pCard->smpSendHead = NULL;
 6287   pCard->smpSendTail = NULL;
 6288   AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
 6289 
 6290   AG_LOCAL_LOCK( &pCard->doneSMPLock );
 6291   pCard->smpDoneHead = NULL;
 6292   pCard->smpDoneTail = NULL;
 6293   AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
 6294 
 6295   // finished with all reset stuff, now start things back up
 6296   tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
 6297   pCard->flags |= AGTIAPI_SYS_INTR_ON;
 6298   pCard->flags |= AGTIAPI_HAD_RESET;
 6299   pCard->flags &= ~AGTIAPI_RESET;  // ##
 6300   agtiapi_StartIO( pCard );
 6301   AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
 6302   return AGTIAPI_SUCCESS;
 6303 } // agtiapi_ResetCard
 6304 
 6305 
 6306 /******************************************************************************
 6307 agtiapi_ReleaseHBA()
 6308 
 6309 Purpose:
 6310   Releases all resources previously acquired to support 
 6311   a specific Host Adapter, including the I/O Address range, 
 6312   and unregisters the agtiapi Host Adapter.
 6313 Parameters: 
 6314   device_t dev (IN)  - device pointer
 6315 Return:
 6316   always return 0 - success
 6317 Note:    
 6318 ******************************************************************************/
 6319 int agtiapi_ReleaseHBA( device_t dev )
 6320 {
 6321   
 6322   int thisCard = device_get_unit( dev ); // keeping get_unit call to once
 6323   int i;
 6324   ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
 6325   struct ccb_setasync csa; 
 6326   struct agtiapi_softc *pCard;
 6327   pCard = device_get_softc( dev );
 6328   ag_card_info_t *pCardInfo = pCard->pCardInfo;
 6329   ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
 6330   
 6331   AG_GLOBAL_ARG(flags);
 6332 
 6333   AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
 6334   
 6335   if (thisCardInst != pCardInfo)
 6336   {
 6337     AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
 6338                     "pCardInfo %p\n",
 6339                     thisCardInst,
 6340                     pCardInfo );
 6341     panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
 6342            "%p\n",
 6343            thisCardInst,
 6344            pCardInfo );
 6345     return( EIO );
 6346   }
 6347 
 6348 
 6349   AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
 6350   pCard->flags |= AGTIAPI_SHUT_DOWN;
 6351 
 6352 
 6353   // remove timer
 6354   if (pCard->flags & AGTIAPI_TIMER_ON)
 6355   {
 6356     AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
 6357     callout_drain( &pCard->OS_timer );
 6358     callout_drain( &pCard->devRmTimer );
 6359     callout_drain(&pCard->IO_timer);
 6360     AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
 6361     AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
 6362   }
 6363 
 6364 #ifdef HIALEAH_ENCRYPTION
 6365 //Release encryption table memory - Fix it
 6366    //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
 6367         //agtiapi_CleanupEncryption(pCard);
 6368 #endif
 6369 
 6370   /*
 6371    * Shutdown the channel so that chip gets frozen
 6372    * and it does not do any more pci-bus accesses.
 6373    */
 6374   if (pCard->flags & AGTIAPI_SYS_INTR_ON)
 6375   {
 6376     tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
 6377     pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
 6378     AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
 6379   }
 6380   if (pCard->flags & AGTIAPI_INSTALLED)
 6381   {
 6382     tiCOMShutDown( &pCard->tiRoot );
 6383     AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
 6384   }
 6385   
 6386   /* 
 6387    * first release IRQ, so that we do not get any more interrupts
 6388    * from this host
 6389    */
 6390   if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
 6391   {
 6392     if (!agtiapi_intx_mode)
 6393     {
 6394       int i;
 6395       for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
 6396       {
 6397         if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
 6398         {
 6399           bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
 6400           bus_release_resource( dev,
 6401                                 SYS_RES_IRQ,
 6402                                 pCard->rscID[i],
 6403                                 pCard->irq[i] );
 6404         }
 6405       }
 6406       pci_release_msi(dev);
 6407     }    
 6408     pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
 6409 
 6410 
 6411 
 6412 #ifdef AGTIAPI_DPC
 6413     for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
 6414       tasklet_kill(&pCard->tasklet_dpc[i]);
 6415 #endif
 6416     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
 6417   }
 6418 
 6419   // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
 6420   if( pCard->osti_busaddr != 0 ) {
 6421     bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
 6422   }
 6423   if( pCard->osti_mem != NULL )  {
 6424     bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
 6425   }    
 6426   if( pCard->osti_dmat != NULL ) {
 6427     bus_dma_tag_destroy( pCard->osti_dmat );
 6428   }
 6429 
 6430   /* unmap the mapped PCI memory */ 
 6431   /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */ 
 6432   agtiapi_ReleasePCIMem(thisCardInst);
 6433 
 6434   /* release all ccbs */
 6435   if (pCard->ccbTotal)
 6436   {
 6437     //calls bus_dmamap_destroy() for all pccbs
 6438     agtiapi_ReleaseCCBs(pCard);
 6439     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
 6440   }
 6441 
 6442 #ifdef HIALEAH_ENCRYPTION
 6443 /*release encryption resources - Fix it*/
 6444   if(pCard->encrypt)
 6445   {
 6446     /*Check that all IO's are completed */
 6447     if(atomic_read (&outstanding_encrypted_io_count) > 0)
 6448     {
 6449        printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
 6450     }
 6451     //agtiapi_CleanupEncryptionPools(pCard);
 6452   }
 6453 #endif
 6454 
 6455 
 6456   /* release device list */
 6457   if( pCard->pDevList ) {
 6458     free((caddr_t)pCard->pDevList, M_PMC_MDVT);
 6459     pCard->pDevList = NULL;
 6460     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
 6461   }
 6462 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
 6463   AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
 6464   if( pCard->pWWNList ) {
 6465     free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
 6466     pCard->pWWNList = NULL;
 6467     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
 6468   }
 6469   if( pCard->pSLRList ) {
 6470     free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
 6471     pCard->pSLRList = NULL;
 6472     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
 6473   }
 6474 
 6475 #endif
 6476   if (pCard->pPortalData)
 6477   {
 6478     free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
 6479     pCard->pPortalData = NULL;
 6480     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
 6481   }
 6482   //calls contigfree() or free()  
 6483   agtiapi_MemFree(pCardInfo);
 6484   AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
 6485 
 6486 #ifdef HOTPLUG_SUPPORT
 6487   if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
 6488   {
 6489     //    agtiapi_FreeDevWorkList(pCard);
 6490     AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
 6491   }
 6492 #endif
 6493 
 6494   /* 
 6495    * TBD, scsi_unregister may release wrong host data structure
 6496    * which cause NULL pointer shows up.  
 6497    */
 6498   if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
 6499   {
 6500     pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
 6501 
 6502 
 6503 #ifdef AGTIAPI_LOCAL_LOCK
 6504     if (pCard->STLock)
 6505     {
 6506       //destroy mtx
 6507       int maxLocks;
 6508       maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
 6509 
 6510       for( i = 0; i < maxLocks; i++ ) 
 6511       { 
 6512         mtx_destroy(&pCard->STLock[i]);
 6513       }     
 6514       free(pCard->STLock, M_PMC_MSTL);
 6515       pCard->STLock = NULL;
 6516     }
 6517 #endif
 6518 
 6519   }
 6520   ag_card_good--;
 6521 
 6522   /* reset agtiapi_1st_time if this is the only card */
 6523   if (!ag_card_good && !agtiapi_1st_time)
 6524   {
 6525     agtiapi_1st_time = 1;
 6526   }
 6527 
 6528   /* for tiSgl_t memeory */
 6529   if (pCard->tisgl_busaddr != 0)
 6530   {
 6531     bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
 6532   }    
 6533   if (pCard->tisgl_mem != NULL)
 6534   {  
 6535     bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
 6536   }    
 6537   if (pCard->tisgl_dmat != NULL)
 6538   {  
 6539     bus_dma_tag_destroy(pCard->tisgl_dmat);
 6540   }
 6541       
 6542   if (pCard->buffer_dmat != agNULL)
 6543   {
 6544     bus_dma_tag_destroy(pCard->buffer_dmat);
 6545   }
 6546   
 6547   if (pCard->sim != NULL) 
 6548   {
 6549     mtx_lock(&thisCardInst->pmIOLock);
 6550       memset(&csa, 0, sizeof(csa));
 6551       xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
 6552       csa.ccb_h.func_code = XPT_SASYNC_CB;
 6553       csa.event_enable = 0;
 6554       csa.callback = agtiapi_async;
 6555       csa.callback_arg = pCard;
 6556       xpt_action((union ccb *)&csa);
 6557       xpt_free_path(pCard->path);
 6558  //   if (pCard->ccbTotal == 0)
 6559     if (pCard->ccbTotal <= thisCard)
 6560     {
 6561       /*
 6562         no link up so that simq has not been released.
 6563         In order to remove cam, we call this.
 6564       */
 6565       xpt_release_simq(pCard->sim, 1);
 6566     }
 6567     xpt_bus_deregister(cam_sim_path(pCard->sim));
 6568     cam_sim_free(pCard->sim, FALSE);
 6569     mtx_unlock(&thisCardInst->pmIOLock);
 6570   }
 6571   if (pCard->devq != NULL)
 6572   {
 6573     cam_simq_free(pCard->devq);
 6574   }
 6575 
 6576   //destroy mtx
 6577   mtx_destroy( &thisCardInst->pmIOLock );
 6578   mtx_destroy( &pCard->sendLock );
 6579   mtx_destroy( &pCard->doneLock );
 6580   mtx_destroy( &pCard->sendSMPLock );
 6581   mtx_destroy( &pCard->doneSMPLock );
 6582   mtx_destroy( &pCard->ccbLock );
 6583   mtx_destroy( &pCard->devListLock );
 6584   mtx_destroy( &pCard->OS_timer_lock );
 6585   mtx_destroy( &pCard->devRmTimerLock );
 6586   mtx_destroy( &pCard->memLock );
 6587   mtx_destroy( &pCard->freezeLock );
 6588 
 6589   destroy_dev( pCard->my_cdev );
 6590   memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
 6591   return 0;
 6592 }
 6593 
 6594 
 6595 // Called during system shutdown after sync
 6596 static int agtiapi_shutdown( device_t dev )
 6597 {
 6598   AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
 6599   return( 0 );
 6600 }
 6601 
 6602 static int agtiapi_suspend( device_t dev )  // Device suspend routine.
 6603 {
 6604   AGTIAPI_PRINTK( "agtiapi_suspend\n" );
 6605   return( 0 );
 6606 }
 6607 
 6608 static int agtiapi_resume( device_t dev ) // Device resume routine.
 6609 {
 6610   AGTIAPI_PRINTK( "agtiapi_resume\n" );
 6611   return( 0 );
 6612 }
 6613 
 6614 static device_method_t agtiapi_methods[] = {   // Device interface
 6615   DEVMETHOD( device_probe,    agtiapi_probe      ),
 6616   DEVMETHOD( device_attach,   agtiapi_attach     ),
 6617   DEVMETHOD( device_detach,   agtiapi_ReleaseHBA ),
 6618   DEVMETHOD( device_shutdown, agtiapi_shutdown   ),
 6619   DEVMETHOD( device_suspend,  agtiapi_suspend    ),
 6620   DEVMETHOD( device_resume,   agtiapi_resume     ),
 6621   { 0, 0 }
 6622 };
 6623 
 6624 static driver_t pmspcv_driver = {
 6625   "pmspcv",
 6626   agtiapi_methods,
 6627   sizeof( struct agtiapi_softc )
 6628 };
 6629 
 6630 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, 0, 0 );
 6631 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
 6632 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
 6633 
 6634 #include <dev/pms/freebsd/driver/common/lxosapi.c>
 6635 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
 6636 #include <dev/pms/freebsd/driver/common/lxutil.c>
 6637 #include <dev/pms/freebsd/driver/common/lxencrypt.c>
 6638 
 6639 

Cache object: b5e8a9acd5d6054f8d02dc4739b09e7c


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


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