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