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