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