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