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