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