xref: /freebsd/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c (revision 81ad6265)
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 
6640