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