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