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