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