1 /*******************************************************************************
3 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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.
11 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
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
20 *******************************************************************************/
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24 #include <dev/pms/config.h>
26 #define MAJOR_REVISION 1
27 #define MINOR_REVISION 3
28 #define BUILD_REVISION 10800
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>
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>
51 #include <sys/mutex.h>
53 #include <sys/queue.h>
54 #include <sys/taskqueue.h>
55 #include <machine/atomic.h>
56 #include <sys/libkern.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>
74 MALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" );
76 MALLOC_DEFINE( M_PMC_MSTL, "STLock malloc",
77 "allocated in agtiapi_attach as memory for lock use" );
78 MALLOC_DEFINE( M_PMC_MDVT, "ag_device_t malloc",
79 "allocated in agtiapi_attach as mem for ag_device_t pDevList" );
80 MALLOC_DEFINE( M_PMC_MPRT, "ag_portal_data_t malloc",
81 "allocated in agtiapi_attach as mem for *pPortalData" );
82 MALLOC_DEFINE( M_PMC_MDEV, "tiDeviceHandle_t * malloc",
83 "allocated in agtiapi_GetDevHandle as local mem for **agDev" );
84 MALLOC_DEFINE( M_PMC_MFLG, "lDevFlags * malloc",
85 "allocated in agtiapi_GetDevHandle as local mem for * flags" );
86 #ifdef LINUX_PERBI_SUPPORT
87 MALLOC_DEFINE( M_PMC_MSLR, "ag_slr_map_t malloc",
88 "mem allocated in agtiapi_attach for pSLRList" );
89 MALLOC_DEFINE( M_PMC_MTGT, "ag_tgt_map_t malloc",
90 "mem allocated in agtiapi_attach for pWWNList" );
92 MALLOC_DEFINE(TEMP,"tempbuff","buffer for payload");
93 MALLOC_DEFINE(TEMP2, "tempbuff", "buffer for agtiapi_getdevlist");
94 STATIC U32 agtiapi_intx_mode = 0;
95 STATIC U08 ag_Perbi = 0;
96 STATIC U32 agtiapi_polling_mode = 0;
97 STATIC U32 ag_card_good = 0; // * total card initialized
98 STATIC U32 ag_option_flag = 0; // * adjustable parameter flag
99 STATIC U32 agtiapi_1st_time = 1;
100 STATIC U32 ag_timeout_secs = 10; //Made timeout equivalent to linux
102 U32 gTiDebugLevel = 1;
103 S32 ag_encryption_enable = 0;
104 atomic_t outstanding_encrypted_io_count;
106 #define cache_line_size() CACHE_LINE_SIZE
108 #define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
110 #define CPU_TO_LE32(dst, src) \
111 dst.lower = htole32(LOW_32_BITS(src)); \
112 dst.upper = htole32(HIGH_32_BITS(src))
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 )
118 STATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] =
119 { AGTIAPI_PERIPHERAL };
121 #ifdef LINUX_PERBI_SUPPORT
122 // Holding area for target-WWN mapping assignments on the boot line
123 static ag_mapping_t *agMappingList = NULL; // modified by agtiapi_Setup()
126 // * For Debugging Purpose
128 #define AGTIAPI_WWN(name, len) wwnprintk(name, len)
130 #define AGTIAPI_WWN(name, len)
134 #define AGTIAPI_WWNPRINTK(name, len, format, a...) \
135 AGTIAPI_PRINTK(format "name ", a); \
136 AGTIAPI_WWN((unsigned char*)name, len);
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); \
145 #ifdef AGTIAPI_LOCAL_LOCK
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)
157 #define AG_LOCAL_LOCK(lock) if (lock) \
159 #define AG_LOCAL_UNLOCK(lock) if (lock) \
161 #define AG_LOCAL_FLAGS(_flags) unsigned long _flags = 0
165 #define AG_GET_DONE_PCCB(pccb, pmcsc) \
167 AG_LOCAL_LOCK(&pmcsc->doneLock); \
168 pccb = pmcsc->ccbDoneHead; \
171 pmcsc->ccbDoneHead = NULL; \
172 pmcsc->ccbDoneTail = NULL; \
173 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
174 agtiapi_Done(pmcsc, pccb); \
177 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
180 #define AG_GET_DONE_SMP_PCCB(pccb, pmcsc) \
182 AG_LOCAL_LOCK(&pmcsc->doneSMPLock); \
183 pccb = pmcsc->smpDoneHead; \
186 pmcsc->smpDoneHead = NULL; \
187 pmcsc->smpDoneTail = NULL; \
188 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
189 agtiapi_SMPDone(pmcsc, pccb); \
192 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
195 #ifdef AGTIAPI_DUMP_IO_DEBUG
196 #define AG_IO_DUMPCCB(pccb) agtiapi_DumpCCB(pccb)
198 #define AG_IO_DUMPCCB(pccb)
201 #define SCHED_DELAY_JIFFIES 4 /* in seconds */
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)
208 #define AG_HOTPLUG_LOCK_INIT(lock)
209 #define AG_LIST_LOCK(lock)
210 #define AG_LIST_UNLOCK(lock)
213 STATIC void agtiapi_CheckIOTimeout(void *data);
217 static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list
218 static void agtiapi_cam_action( struct cam_sim *, union ccb * );
219 static void agtiapi_cam_poll( struct cam_sim * );
221 // Function prototypes
222 static d_open_t agtiapi_open;
223 static d_close_t agtiapi_close;
224 static d_read_t agtiapi_read;
225 static d_write_t agtiapi_write;
226 static d_ioctl_t agtiapi_CharIoctl;
227 static void agtiapi_async(void *callback_arg, u_int32_t code,
228 struct cam_path *path, void *arg);
229 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth);
231 // Character device entry points
232 static struct cdevsw agtiapi_cdevsw = {
233 .d_version = D_VERSION,
234 .d_open = agtiapi_open,
235 .d_close = agtiapi_close,
236 .d_read = agtiapi_read,
237 .d_write = agtiapi_write,
238 .d_ioctl = agtiapi_CharIoctl,
243 U32 ag_portal_count = 0;
245 // In the cdevsw routines, we find our softc by using the si_drv1 member
246 // of struct cdev. We set this variable to point to our softc in our
247 // attach routine when we create the /dev entry.
249 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
251 struct agtiapi_softc *sc;
252 /* Look up our softc. */
254 AGTIAPI_PRINTK("agtiapi_open\n");
255 AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
259 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
261 struct agtiapi_softc *sc;
264 AGTIAPI_PRINTK("agtiapi_close\n");
265 AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
269 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
271 struct agtiapi_softc *sc;
274 AGTIAPI_PRINTK( "agtiapi_read\n" );
275 AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n",
276 uio->uio_resid, sc->my_dev );
280 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
282 struct agtiapi_softc *sc;
285 AGTIAPI_PRINTK( "agtiapi_write\n" );
286 AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n",
287 uio->uio_resid, sc->my_dev );
291 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
292 tiIOCTLPayload_t *agIOCTLPayload )
294 tdDeviceListPayload_t *pIoctlPayload =
295 (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea;
296 tdDeviceInfoIOCTL_t *pDeviceInfo = NULL;
297 bit8 *pDeviceInfoOrg;
298 tdsaDeviceData_t *pDeviceData = NULL;
299 tiDeviceHandle_t **devList = NULL;
300 tiDeviceHandle_t **devHandleArray = NULL;
301 tiDeviceHandle_t *pDeviceHandle = NULL;
304 bit32 MaxDeviceCount;
305 bit32 ret_val=IOCTL_CALL_INVALID_CODE;
306 ag_portal_data_t *pPortalData;
307 bit8 *pDeviceHandleList = NULL;
308 AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" );
310 pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
311 MaxDeviceCount = pCard->devDiscover;
312 if (MaxDeviceCount > pIoctlPayload->deviceLength )
314 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
315 MaxDeviceCount = pIoctlPayload->deviceLength;
316 ret_val = IOCTL_CALL_FAIL;
318 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
319 memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
321 AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
322 devList = malloc(memNeeded1, TEMP2, M_WAITOK);
325 AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
326 ret_val = IOCTL_CALL_FAIL;
327 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
330 osti_memset(devList, 0, memNeeded1);
331 pPortalData = &pCard->pPortalData[0];
332 pDeviceHandleList = (bit8*)devList;
333 for (total = x = 0; x < pCard->portCount; x++, pPortalData++)
335 count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
336 &pPortalData->portalInfo.tiPortalContext,
337 ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
338 if (count == DISCOVERY_IN_PROGRESS)
340 AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
342 free(devList, TEMP2);
343 ret_val = IOCTL_CALL_FAIL;
344 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
348 pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
349 MaxDeviceCount-= count;
351 if (total > pIoctlPayload->deviceLength)
353 total = pIoctlPayload->deviceLength;
355 // dump device information from device handle list
358 devHandleArray = devList;
359 for (x = 0; x < pCard->devDiscover; x++)
361 pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
362 if (devList[x] != agNULL)
364 pDeviceData = devList [x]->tdData;
366 pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
367 if (pDeviceData != agNULL && pDeviceInfo != agNULL)
369 osti_memcpy( &pDeviceInfo->sasAddressHi,
370 pDeviceData->agDeviceInfo.sasAddressHi,
372 osti_memcpy( &pDeviceInfo->sasAddressLo,
373 pDeviceData->agDeviceInfo.sasAddressLo,
376 pDeviceInfo->sasAddressHi =
377 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
378 pDeviceInfo->sasAddressLo =
379 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
382 pDeviceInfo->deviceType =
383 ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4;
384 pDeviceInfo->linkRate =
385 pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F;
386 pDeviceInfo->phyId = pDeviceData->phyID;
387 pDeviceInfo->ishost = pDeviceData->target_ssp_stp_smp;
388 pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle;
389 if(pDeviceInfo->deviceType == 0x02)
393 tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo);
394 pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi);
395 pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16;
399 pDeviceInfo->sasAddressHi =
400 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
401 pDeviceInfo->sasAddressLo =
402 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
405 AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n",
406 pDeviceInfo->deviceType );
407 AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n",
408 pDeviceInfo->linkRate );
409 AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n",
410 pDeviceInfo->phyId );
411 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n",
412 pDeviceInfo->sasAddressHi );
413 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n",
414 pDeviceInfo->sasAddressHi );
418 AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
419 "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
424 pIoctlPayload->realDeviceCount = count;
425 AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
428 free(devList, TEMP2);
430 if(ret_val != IOCTL_CALL_FAIL)
432 ret_val = IOCTL_CALL_SUCCESS;
434 agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
438 /******************************************************************************
439 agtiapi_getCardInfo()
442 This function retrives the Card information
447 0 - HBA has been detected
449 ******************************************************************************/
450 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
454 CardInfo_t *pCardInfo;
456 pCardInfo = (CardInfo_t *)buffer;
458 pCardInfo->deviceId = pci_get_device(pCard->my_dev);
459 pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ;
460 memcpy( pCardInfo->pciMemBaseSpc,
461 pCard->pCardInfo->pciMemBaseSpc,
462 ((sizeof(U32_64))*PCI_NUMBER_BARS) );
463 pCardInfo->deviceNum = pci_get_slot(pCard->my_dev);
464 pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase;
465 pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow;
466 pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp;
467 pCardInfo->busNum =pci_get_bus(pCard->my_dev);
471 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
473 struct ccb_relsim crs;
474 xpt_setup_ccb(&crs.ccb_h, path, 5);
475 crs.ccb_h.func_code = XPT_REL_SIMQ;
476 crs.ccb_h.flags = CAM_DEV_QFREEZE;
477 crs.release_flags = RELSIM_ADJUST_OPENINGS;
478 crs.openings = QueueDepth;
479 xpt_action((union ccb *)&crs);
480 if(crs.ccb_h.status != CAM_REQ_CMP) {
481 printf("XPT_REL_SIMQ failed\n");
485 agtiapi_async(void *callback_arg, u_int32_t code,
486 struct cam_path *path, void *arg)
488 struct agtiapi_softc *pmsc;
491 pmsc = (struct agtiapi_softc*)callback_arg;
493 case AC_FOUND_DEVICE:
495 struct ccb_getdev *cgd;
496 cgd = (struct ccb_getdev *)arg;
500 TID = cgd->ccb_h.target_id;
501 if (TID >= 0 && TID < maxTargets){
503 TID = INDEX(pmsc, TID);
504 targ = &pmsc->pDevList[TID];
505 agtiapi_adjust_queue_depth(path, targ->qdepth);
514 /******************************************************************************
518 This function handles the ioctl from application layer
523 0 - HBA has been detected
525 ******************************************************************************/
526 static int agtiapi_CharIoctl( struct cdev *dev,
533 datatosend *load; // structure defined in lxcommon.h
534 tiIOCTLPayload_t *pIoctlPayload;
535 struct agtiapi_softc *pCard;
544 tdDeviceListPayload_t *pDeviceList = NULL;
550 load=(datatosend*)data;
551 pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK);
552 AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize );
553 //Copy payload to kernel buffer, on success it returns 0
554 err = copyin(load->data,pIoctlPayload,load->datasize);
557 status = IOCTL_CALL_FAIL;
560 sema_init(&mx,0,"sem");
561 pCard->pIoctlSem =&mx;
562 pCard->up_count = pCard->down_count = 0;
563 if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST )
565 retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
568 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
569 status = IOCTL_CALL_SUCCESS;
573 pIoctlPayload->Status = IOCTL_CALL_FAIL;
574 status = IOCTL_CALL_FAIL;
576 //update new device length
577 pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea;
578 load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount);
579 AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize );
582 else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
584 retValue = agtiapi_getCardInfo( pCard,
585 pIoctlPayload->Length,
586 (pIoctlPayload->FunctionSpecificArea) );
589 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
590 status = IOCTL_CALL_SUCCESS;
594 pIoctlPayload->Status = IOCTL_CALL_FAIL;
595 status = IOCTL_CALL_FAIL;
598 else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
600 if ( pCard->flags & AGTIAPI_PORT_PANIC )
602 strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
606 strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
608 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
609 status = IOCTL_CALL_SUCCESS;
611 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
613 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo);
614 //read port status to see if there is a fatal event
615 if(pCard->flags & AGTIAPI_PORT_PANIC)
617 printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo);
618 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE;
622 AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo);
623 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE;
625 status = IOCTL_CALL_SUCCESS;
627 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
629 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo);
630 //set flags bit status to be a soft reset
631 pCard->flags |= AGTIAPI_SOFT_RESET;
632 //trigger soft reset for the card
633 retValue = agtiapi_ResetCard (pCard, &flags);
635 if(retValue == AGTIAPI_SUCCESS)
637 //clear port panic status
638 pCard->flags &= ~AGTIAPI_PORT_PANIC;
639 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG;
640 status = IOCTL_CALL_SUCCESS;
644 pIoctlPayload->Status = IOCTL_CALL_FAIL;
645 status = IOCTL_CALL_FAIL;
650 status = tiCOMMgntIOCTL( &pCard->tiRoot,
655 if (status == IOCTL_CALL_PENDING)
657 ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
658 status = IOCTL_CALL_SUCCESS;
661 pCard->pIoctlSem = NULL;
664 //copy kernel buffer to userland buffer
665 err=copyout(pIoctlPayload,load->data,load->datasize);
668 status = IOCTL_CALL_FAIL;
671 free(pIoctlPayload,TEMP);
681 /******************************************************************************
685 This function initialize and registere all detected HBAs.
686 The first function being called in driver after agtiapi_probe()
688 device_t dev (IN) - device pointer
691 0 - HBA has been detected
693 ******************************************************************************/
694 static int agtiapi_probe( device_t dev )
698 ag_card_info_t *thisCardInst;
700 thisCard = device_get_unit( dev );
701 if ( thisCard >= AGTIAPI_MAX_CARDS )
703 device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
704 return (ENXIO); // maybe change to different return value?
706 thisCardInst = &agCardInfoList[ thisCard ];
707 retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
709 return (ENXIO); // maybe change to different return value?
710 return( BUS_PROBE_DEFAULT ); // successful probe
714 /******************************************************************************
718 This function initialize and registere all detected HBAs.
719 The first function being called in driver after agtiapi_probe()
721 device_t dev (IN) - device pointer
724 0 - HBA has been detected
726 ******************************************************************************/
727 static int agtiapi_attach( device_t devx )
729 // keeping get_unit call to once
730 int thisCard = device_get_unit( devx );
731 struct agtiapi_softc *pmsc;
732 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
733 ag_resource_info_t *pRscInfo;
736 char buffer [256], *pLastUsedChar;
739 struct ccb_setasync csa;
741 AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard);
742 // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values A %p / %p\n",
743 // thisCardInst->pPCIDev, thisCardInst );
744 AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) );
746 TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS", &ag_timeout_secs );
747 TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel );
748 // printf( "agtiapi_attach: debugLevel %d, timeout %d\n",
749 // gTiDebugLevel, ag_timeout_secs );
750 if ( ag_timeout_secs < 1 )
752 ag_timeout_secs = 1; // set minimum timeout value of 1 second
754 ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
756 // Look up our softc and initialize its fields.
757 pmsc = device_get_softc( devx );
760 /* Get NumberOfPortals */
761 if ((ostiGetTransportParam(
773 ) == tiSuccess) && (lenRecv != 0))
775 if (osti_strncmp(buffer, "0x", 2) == 0)
777 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
781 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
783 if (ag_portal_count > AGTIAPI_MAX_PORTALS)
784 ag_portal_count = AGTIAPI_MAX_PORTALS;
788 ag_portal_count = AGTIAPI_MAX_PORTALS;
790 AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count );
791 // initialize hostdata structure
792 pmsc->flags |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED |
794 pmsc->cardNo = thisCard;
796 pmsc->portCount = ag_portal_count;
797 pmsc->pCardInfo = thisCardInst;
798 pmsc->tiRoot.osData = pmsc;
799 pmsc->pCardInfo->pCard = (void *)pmsc;
800 pmsc->VidDid = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx );
801 pmsc->SimQFrozen = agFALSE;
802 pmsc->devq_flag = agFALSE;
803 pRscInfo = &thisCardInst->tiRscInfo;
805 osti_memset(buffer, 0, 256);
809 if ((ostiGetTransportParam(
821 ) == tiSuccess) && (lenRecv != 0))
823 if (osti_strncmp(buffer, "0x", 2) == 0)
825 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
826 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" );
830 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
831 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" );
838 maxTargets = AGTIAPI_MAX_DEVICE_8H;
839 else if(Is_ADP7H(pmsc))
840 maxTargets = AGTIAPI_MAX_DEVICE_7H;
842 maxTargets = AGTIAPI_MAX_DEVICE;
845 if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
847 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n", maxTargets, AGTIAPI_HW_LIMIT_DEVICE );
848 AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" );
849 maxTargets = AGTIAPI_HW_LIMIT_DEVICE;
851 pmsc->devDiscover = maxTargets ;
853 #ifdef HIALEAH_ENCRYPTION
854 ag_encryption_enable = 1;
855 if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) ==
856 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
859 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
860 printf("agtiapi_attach: Encryption Enabled\n" );
863 // ## for now, skip calls to ostiGetTransportParam(...)
864 // ## for now, skip references to DIF & EDC
866 // Create a /dev entry for this device. The kernel will assign us
867 // a major number automatically. We use the unit number of this
868 // device as the minor number and name the character device
870 pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL,
871 0600, "spcv%u", thisCard );
872 pmsc->my_cdev->si_drv1 = pmsc;
874 mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
875 NULL, MTX_DEF|MTX_RECURSE );
877 struct cam_devq *devq;
879 /* set the maximum number of pending IOs */
880 devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
883 AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
887 struct cam_sim *lsim;
888 lsim = cam_sim_alloc( agtiapi_cam_action,
893 &thisCardInst->pmIOLock,
894 1, // queued per target
895 AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
897 if ( lsim == NULL ) {
898 cam_simq_free( devq );
899 AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
903 pmsc->dev_scan = agFALSE;
904 //one cam sim per scsi bus
905 mtx_lock( &thisCardInst->pmIOLock );
906 if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS )
908 cam_sim_free( lsim, TRUE );
909 mtx_unlock( &thisCardInst->pmIOLock );
910 AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
915 bus = cam_sim_path(pmsc->sim);
916 tid = CAM_TARGET_WILDCARD;
917 lun = CAM_LUN_WILDCARD;
918 ccb = xpt_alloc_ccb_nowait();
921 mtx_unlock( &thisCardInst->pmIOLock );
922 cam_sim_free( lsim, TRUE );
923 cam_simq_free( devq );
926 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
927 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
929 mtx_unlock( &thisCardInst->pmIOLock );
930 cam_sim_free( lsim, TRUE );
931 cam_simq_free( devq );
935 pmsc->path = ccb->ccb_h.path;
936 xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5);
937 csa.ccb_h.func_code = XPT_SASYNC_CB;
938 csa.event_enable = AC_FOUND_DEVICE;
939 csa.callback = agtiapi_async;
940 csa.callback_arg = pmsc;
941 xpt_action((union ccb *)&csa);
942 if (csa.ccb_h.status != CAM_REQ_CMP) {
943 AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" );
946 mtx_unlock( &thisCardInst->pmIOLock );
951 // get TD and lower layer memory requirements
952 tiCOMGetResource( &pmsc->tiRoot,
953 &pRscInfo->tiLoLevelResource,
954 &pRscInfo->tiInitiatorResource,
956 &pRscInfo->tiSharedMem );
958 agtiapi_ScopeDMARes( thisCardInst );
959 AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
960 " 0x%x \n", pmsc->typhn );
962 // initialize card information and get resource ready
963 if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) {
964 AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n",
968 // begin: allocate and initialize card portal info resource
969 ag_portal_data_t *pPortalData;
970 if (pmsc->portCount == 0)
972 pmsc->pPortalData = NULL;
976 pmsc->pPortalData = (ag_portal_data_t *)
977 malloc( sizeof(ag_portal_data_t) * pmsc->portCount,
978 M_PMC_MPRT, M_ZERO | M_WAITOK );
979 if (pmsc->pPortalData == NULL)
981 AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
985 pPortalData = pmsc->pPortalData;
986 for( idx = 0; idx < pmsc->portCount; idx++ ) {
987 pPortalData->pCard = pmsc;
988 pPortalData->portalInfo.portID = idx;
989 pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData;
992 // end: allocate and initialize card portal info resource
994 // begin: enable msix
997 // map to interrupt handler
999 int mesgs = MAX_MSIX_NUM_VECTOR;
1002 void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
1004 agtiapi_IntrHandler0,
1005 agtiapi_IntrHandler1,
1006 agtiapi_IntrHandler2,
1007 agtiapi_IntrHandler3,
1008 agtiapi_IntrHandler4,
1009 agtiapi_IntrHandler5,
1010 agtiapi_IntrHandler6,
1011 agtiapi_IntrHandler7,
1012 agtiapi_IntrHandler8,
1013 agtiapi_IntrHandler9,
1014 agtiapi_IntrHandler10,
1015 agtiapi_IntrHandler11,
1016 agtiapi_IntrHandler12,
1017 agtiapi_IntrHandler13,
1018 agtiapi_IntrHandler14,
1019 agtiapi_IntrHandler15
1023 cnt = pci_msix_count(devx);
1024 AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64
1025 mesgs = MIN(mesgs, cnt);
1026 error = pci_alloc_msix(devx, &mesgs);
1028 printf( "pci_alloc_msix error %d\n", error );
1029 AGTIAPI_PRINTK("error %d\n", error);
1033 for(i=0; i < mesgs; i++) {
1034 pmsc->rscID[i] = i + 1;
1035 pmsc->irq[i] = bus_alloc_resource_any( devx,
1039 if( pmsc->irq[i] == NULL ) {
1040 printf( "RES_IRQ went terribly bad at %d\n", i );
1044 if ( (error = bus_setup_intr( devx, pmsc->irq[i],
1045 INTR_TYPE_CAM | INTR_MPSAFE,
1049 &pmsc->intrcookie[i] )
1051 device_printf( devx, "Failed to register handler" );
1055 pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
1056 pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
1060 ret = agtiapi_InitCardSW(pmsc);
1061 if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
1063 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
1068 pmsc->ccbFreeList = NULL;
1069 pmsc->ccbChainList = NULL;
1070 pmsc->ccbAllocList = NULL;
1072 pmsc->flags |= ( AGTIAPI_INSTALLED );
1074 ret = agtiapi_alloc_requests( pmsc );
1076 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
1081 ret = agtiapi_alloc_ostimem( pmsc );
1082 if (ret != AGTIAPI_SUCCESS)
1084 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
1089 ret = agtiapi_InitCardHW( pmsc );
1092 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
1097 #ifdef HIALEAH_ENCRYPTION
1100 if((agtiapi_SetupEncryption(pmsc)) < 0)
1101 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
1105 pmsc->flags &= ~AGTIAPI_INIT_TIME;
1109 /******************************************************************************
1110 agtiapi_InitCardSW()
1113 Host Bus Adapter Initialization
1115 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1117 AGTIAPI_SUCCESS - success
1120 TBD, need chip register information
1121 ******************************************************************************/
1122 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc )
1124 ag_card_info_t *thisCardInst = pmsc->pCardInfo;
1125 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
1128 // begin: agtiapi_InitCardSW()
1129 // now init some essential locks n agtiapi_InitCardSW
1130 mtx_init( &pmsc->sendLock, "local q send lock", NULL, MTX_DEF );
1131 mtx_init( &pmsc->doneLock, "local q done lock", NULL, MTX_DEF );
1132 mtx_init( &pmsc->sendSMPLock, "local q send lock", NULL, MTX_DEF );
1133 mtx_init( &pmsc->doneSMPLock, "local q done lock", NULL, MTX_DEF );
1134 mtx_init( &pmsc->ccbLock, "ccb list lock", NULL, MTX_DEF );
1135 mtx_init( &pmsc->devListLock, "hotP devListLock", NULL, MTX_DEF );
1136 mtx_init( &pmsc->memLock, "dynamic memory lock", NULL, MTX_DEF );
1137 mtx_init( &pmsc->freezeLock, "sim freeze lock", NULL, MTX_DEF | MTX_RECURSE);
1139 // initialize lower layer resources
1140 //## if (pCard->flags & AGTIAPI_INIT_TIME) {
1141 #ifdef HIALEAH_ENCRYPTION
1142 /* Enable encryption if chip supports it */
1143 if (pci_get_device(pmsc->pCardInfo->pPCIDev) ==
1144 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
1148 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
1150 pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
1153 // For now, up to 16 MSIX vectors are supported
1154 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.
1155 maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors;
1156 AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d",
1157 pmsc->pCardInfo->maxInterruptVectors );
1158 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0;
1159 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0;
1160 pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0;
1162 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n",
1163 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1164 if( tiCOMInit( &pmsc->tiRoot,
1165 &thisCardInst->tiRscInfo.tiLoLevelResource,
1166 &thisCardInst->tiRscInfo.tiInitiatorResource,
1168 &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
1169 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
1170 return AGTIAPI_FAIL;
1173 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
1174 pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
1175 M_ZERO | M_WAITOK );
1177 for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
1180 mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
1183 if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
1184 printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
1185 return AGTIAPI_FAIL;
1187 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
1188 " root %p, dev %p, pmsc %p\n",
1189 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1191 pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
1192 pmsc->freezeSim = agFALSE;
1194 #ifdef HIALEAH_ENCRYPTION
1195 atomic_set(&outstanding_encrypted_io_count, 0);
1197 /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
1198 if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
1199 printf("SetupEncryptionPools failed\n"); */
1201 return AGTIAPI_SUCCESS;
1202 // end: agtiapi_InitCardSW()
1205 /******************************************************************************
1206 agtiapi_InitCardHW()
1209 Host Bus Adapter Initialization
1211 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1213 AGTIAPI_SUCCESS - success
1216 TBD, need chip register information
1217 ******************************************************************************/
1218 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc )
1223 // begin: agtiapi_InitCardHW()
1225 ag_portal_info_t *pPortalInfo = NULL;
1226 ag_portal_data_t *pPortalData;
1228 // ISR is registered, enable chip interrupt.
1229 tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
1230 pmsc->flags |= AGTIAPI_SYS_INTR_ON;
1232 numVal = sizeof(ag_device_t) * pmsc->devDiscover;
1234 (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK );
1235 if( !pmsc->pDevList ) {
1236 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal );
1237 panic( "agtiapi_InitCardHW\n" );
1238 return AGTIAPI_FAIL;
1241 #ifdef LINUX_PERBI_SUPPORT
1242 numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
1244 (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK );
1245 if( !pmsc->pSLRList ) {
1246 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal );
1247 panic( "agtiapi_InitCardHW SLRL\n" );
1248 return AGTIAPI_FAIL;
1251 numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
1253 (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK );
1254 if( !pmsc->pWWNList ) {
1255 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal );
1256 panic( "agtiapi_InitCardHW WWNL\n" );
1257 return AGTIAPI_FAIL;
1260 // Get the WWN_to_target_ID mappings from the
1261 // holding area which contains the input of the
1262 // system configuration file.
1264 agtiapi_GetWWNMappings( pmsc, agMappingList );
1266 agtiapi_GetWWNMappings( pmsc, 0 );
1268 printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
1272 //agtiapi_DelaySec(5);
1277 pmsc->flags &= ~AGTIAPI_CB_DONE;
1278 pPortalData = pmsc->pPortalData;
1282 for (count = 0; count < pmsc->portCount; count++)
1284 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
1286 pPortalInfo = &pPortalData->portalInfo;
1287 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
1288 AGTIAPI_PORT_DISC_READY |
1290 AGTIAPI_DISC_COMPLETE );
1292 for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
1294 AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
1296 pPortalInfo->portID,
1297 &pPortalInfo->tiPortalContext );
1299 if( tiCOMPortStart( &pmsc->tiRoot,
1300 pPortalInfo->portID,
1301 &pPortalInfo->tiPortalContext,
1304 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1305 agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY );
1306 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
1307 AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n",
1311 AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n",
1315 } // end of for loop
1317 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1319 if( loop >= AGTIAPI_LOOP_MAX ) {
1320 return AGTIAPI_FAIL;
1322 tiCOMGetPortInfo( &pmsc->tiRoot,
1323 &pPortalInfo->tiPortalContext,
1324 &pPortalInfo->tiPortInfo );
1328 /* discover target device */
1329 #ifndef HOTPLUG_SUPPORT
1330 agtiapi_DiscoverTgt( pCard );
1334 pmsc->flags |= AGTIAPI_INSTALLED;
1336 if( pmsc->flags & AGTIAPI_INIT_TIME ) {
1337 agtiapi_TITimer( (void *)pmsc );
1338 pmsc->flags |= AGTIAPI_TIMER_ON;
1346 /******************************************************************************
1347 agtiapi_IntrHandlerx_()
1350 Interrupt service routine.
1352 void arg (IN) Pointer to the HBA data structure
1353 bit32 idx (IN) Vector index
1354 ******************************************************************************/
1355 void agtiapi_IntrHandlerx_( void *arg, int index )
1358 struct agtiapi_softc *pCard;
1361 pCard = (struct agtiapi_softc *)arg;
1367 AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
1368 AG_PERF_SPINLOCK(agtiapi_host_lock);
1369 if (pCard->flags & AGTIAPI_SHUT_DOWN)
1372 rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
1376 AG_SPIN_UNLOCK(agtiapi_host_lock);
1377 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1383 tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
1385 /* consume all completed entries, 100 is random number to be big enough */
1386 tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext);
1387 AG_GET_DONE_PCCB(pccb, pCard);
1388 AG_GET_DONE_SMP_PCCB(pccb, pCard);
1392 AG_SPIN_UNLOCK(agtiapi_host_lock);
1393 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1398 /******************************************************************************
1399 agtiapi_IntrHandler0()
1400 Purpose: Interrupt service routine for interrupt vector index 0.
1401 Parameters: void arg (IN) Pointer to the HBA data structure
1402 ******************************************************************************/
1403 void agtiapi_IntrHandler0( void *arg )
1405 agtiapi_IntrHandlerx_( arg, 0 );
1409 /******************************************************************************
1410 agtiapi_IntrHandler1()
1411 Purpose: Interrupt service routine for interrupt vector index 1.
1412 Parameters: void arg (IN) Pointer to the HBA data structure
1413 ******************************************************************************/
1414 void agtiapi_IntrHandler1( void *arg )
1416 agtiapi_IntrHandlerx_( arg, 1 );
1420 /******************************************************************************
1421 agtiapi_IntrHandler2()
1422 Purpose: Interrupt service routine for interrupt vector index 2.
1423 Parameters: void arg (IN) Pointer to the HBA data structure
1424 ******************************************************************************/
1425 void agtiapi_IntrHandler2( void *arg )
1427 agtiapi_IntrHandlerx_( arg, 2 );
1431 /******************************************************************************
1432 agtiapi_IntrHandler3()
1433 Purpose: Interrupt service routine for interrupt vector index 3.
1434 Parameters: void arg (IN) Pointer to the HBA data structure
1435 ******************************************************************************/
1436 void agtiapi_IntrHandler3( void *arg )
1438 agtiapi_IntrHandlerx_( arg, 3 );
1442 /******************************************************************************
1443 agtiapi_IntrHandler4()
1444 Purpose: Interrupt service routine for interrupt vector index 4.
1445 Parameters: void arg (IN) Pointer to the HBA data structure
1446 ******************************************************************************/
1447 void agtiapi_IntrHandler4( void *arg )
1449 agtiapi_IntrHandlerx_( arg, 4 );
1453 /******************************************************************************
1454 agtiapi_IntrHandler5()
1455 Purpose: Interrupt service routine for interrupt vector index 5.
1456 Parameters: void arg (IN) Pointer to the HBA data structure
1457 ******************************************************************************/
1458 void agtiapi_IntrHandler5( void *arg )
1460 agtiapi_IntrHandlerx_( arg, 5 );
1464 /******************************************************************************
1465 agtiapi_IntrHandler6()
1466 Purpose: Interrupt service routine for interrupt vector index 6.
1467 Parameters: void arg (IN) Pointer to the HBA data structure
1468 ******************************************************************************/
1469 void agtiapi_IntrHandler6( void *arg )
1471 agtiapi_IntrHandlerx_( arg, 6 );
1475 /******************************************************************************
1476 agtiapi_IntrHandler7()
1477 Purpose: Interrupt service routine for interrupt vector index 7.
1478 Parameters: void arg (IN) Pointer to the HBA data structure
1479 ******************************************************************************/
1480 void agtiapi_IntrHandler7( void *arg )
1482 agtiapi_IntrHandlerx_( arg, 7 );
1486 /******************************************************************************
1487 agtiapi_IntrHandler8()
1488 Purpose: Interrupt service routine for interrupt vector index 8.
1489 Parameters: void arg (IN) Pointer to the HBA data structure
1490 ******************************************************************************/
1491 void agtiapi_IntrHandler8( void *arg )
1493 agtiapi_IntrHandlerx_( arg, 8 );
1497 /******************************************************************************
1498 agtiapi_IntrHandler9()
1499 Purpose: Interrupt service routine for interrupt vector index 9.
1500 Parameters: void arg (IN) Pointer to the HBA data structure
1501 ******************************************************************************/
1502 void agtiapi_IntrHandler9( void *arg )
1504 agtiapi_IntrHandlerx_( arg, 9 );
1508 /******************************************************************************
1509 agtiapi_IntrHandler10()
1510 Purpose: Interrupt service routine for interrupt vector index 10.
1511 Parameters: void arg (IN) Pointer to the HBA data structure
1512 ******************************************************************************/
1513 void agtiapi_IntrHandler10( void *arg )
1515 agtiapi_IntrHandlerx_( arg, 10 );
1519 /******************************************************************************
1520 agtiapi_IntrHandler11()
1521 Purpose: Interrupt service routine for interrupt vector index 11.
1522 Parameters: void arg (IN) Pointer to the HBA data structure
1523 ******************************************************************************/
1524 void agtiapi_IntrHandler11( void *arg )
1526 agtiapi_IntrHandlerx_( arg, 11 );
1530 /******************************************************************************
1531 agtiapi_IntrHandler12()
1532 Purpose: Interrupt service routine for interrupt vector index 12.
1533 Parameters: void arg (IN) Pointer to the HBA data structure
1534 ******************************************************************************/
1535 void agtiapi_IntrHandler12( void *arg )
1537 agtiapi_IntrHandlerx_( arg, 12 );
1541 /******************************************************************************
1542 agtiapi_IntrHandler13()
1543 Purpose: Interrupt service routine for interrupt vector index 13.
1544 Parameters: void arg (IN) Pointer to the HBA data structure
1545 ******************************************************************************/
1546 void agtiapi_IntrHandler13( void *arg )
1548 agtiapi_IntrHandlerx_( arg, 13 );
1552 /******************************************************************************
1553 agtiapi_IntrHandler14()
1554 Purpose: Interrupt service routine for interrupt vector index 14.
1555 Parameters: void arg (IN) Pointer to the HBA data structure
1556 ******************************************************************************/
1557 void agtiapi_IntrHandler14( void *arg )
1559 agtiapi_IntrHandlerx_( arg, 14 );
1563 /******************************************************************************
1564 agtiapi_IntrHandler15()
1565 Purpose: Interrupt service routine for interrupt vector index 15.
1566 Parameters: void arg (IN) Pointer to the HBA data structure
1567 ******************************************************************************/
1568 void agtiapi_IntrHandler15( void *arg )
1570 agtiapi_IntrHandlerx_( arg, 15 );
1574 static void agtiapi_SglMemoryCB( void *arg,
1575 bus_dma_segment_t *dm_segs,
1580 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
1583 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
1584 panic("agtiapi_SglMemoryCB: error %d\n", error);
1588 *addr = dm_segs[0].ds_addr;
1592 static void agtiapi_MemoryCB( void *arg,
1593 bus_dma_segment_t *dm_segs,
1598 AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
1601 AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
1602 panic("agtiapi_MemoryCB: error %d\n", error);
1606 *addr = dm_segs[0].ds_addr;
1610 /******************************************************************************
1611 agtiapi_alloc_requests()
1614 Allocates resources such as dma tag and timer
1616 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1618 AGTIAPI_SUCCESS - success
1621 ******************************************************************************/
1622 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
1628 nsegs = AGTIAPI_NSEGS;
1629 rsize = AGTIAPI_MAX_DMA_SEGS; // 128
1630 AGTIAPI_PRINTK( "agtiapi_alloc_requests: MAXPHYS 0x%x PAGE_SIZE 0x%x \n",
1631 MAXPHYS, PAGE_SIZE );
1632 AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n",
1633 nsegs, rsize ); // 32, 128
1634 // This is for csio->data_ptr
1635 if( bus_dma_tag_create( agNULL, // parent
1638 BUS_SPACE_MAXADDR, // lowaddr
1639 BUS_SPACE_MAXADDR, // highaddr
1642 BUS_SPACE_MAXSIZE_32BIT, // maxsize
1644 BUS_SPACE_MAXSIZE_32BIT, // maxsegsize
1645 BUS_DMA_ALLOCNOW, // flags
1646 busdma_lock_mutex, // lockfunc
1647 &pmcsc->pCardInfo->pmIOLock, // lockarg
1648 &pmcsc->buffer_dmat ) ) {
1649 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1653 // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
1655 (sizeof(tiSgl_t) * AGTIAPI_NSEGS) *
1656 AGTIAPI_CCB_PER_DEVICE * maxTargets;
1657 AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128
1658 if( bus_dma_tag_create( agNULL, // parent
1661 BUS_SPACE_MAXADDR_32BIT, // lowaddr
1662 BUS_SPACE_MAXADDR, // highaddr
1667 rsize, // maxsegsize
1668 BUS_DMA_ALLOCNOW, // flags
1671 &pmcsc->tisgl_dmat ) ) {
1672 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1676 if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
1677 (void **)&pmcsc->tisgl_mem,
1679 &pmcsc->tisgl_map ) ) {
1680 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
1684 bzero( pmcsc->tisgl_mem, rsize );
1685 bus_dmamap_load( pmcsc->tisgl_dmat,
1689 agtiapi_SglMemoryCB,
1690 &pmcsc->tisgl_busaddr,
1691 BUS_DMA_NOWAIT /* 0 */ );
1693 mtx_init( &pmcsc->OS_timer_lock, "OS timer lock", NULL, MTX_DEF );
1694 mtx_init( &pmcsc->IO_timer_lock, "IO timer lock", NULL, MTX_DEF );
1695 mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF );
1696 callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 );
1697 callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 );
1698 callout_init_mtx( &pmcsc->devRmTimer,
1699 &pmcsc->devRmTimerLock, 0);
1701 next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource.
1702 loLevelOption.usecsPerTick / USEC_PER_TICK;
1703 AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, "
1704 "next_tick 0x%x\n", next_tick );
1705 callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc );
1709 /******************************************************************************
1710 agtiapi_alloc_ostimem()
1713 Allocates memory used later in ostiAllocMemory
1715 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure
1717 AGTIAPI_SUCCESS - success
1720 This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
1721 ******************************************************************************/
1722 int agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
1726 rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
1727 AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
1729 if( bus_dma_tag_create( agNULL, // parent
1732 BUS_SPACE_MAXADDR, // lowaddr
1733 BUS_SPACE_MAXADDR, // highaddr
1736 rsize, // maxsize (size)
1737 1, // number of segments
1738 rsize, // maxsegsize
1742 &pmcsc->osti_dmat ) ) {
1743 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
1744 return AGTIAPI_FAIL;
1748 if( bus_dmamem_alloc( pmcsc->osti_dmat,
1750 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
1751 &pmcsc->osti_mapp ) ) {
1752 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n",
1754 return AGTIAPI_FAIL;
1758 bus_dmamap_load( pmcsc->osti_dmat,
1762 agtiapi_MemoryCB, // try reuse of CB for same goal
1763 &pmcsc->osti_busaddr,
1766 // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
1767 // handy reference when driver is in motion
1769 ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
1770 ag_dma_addr_t *pMem;
1772 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
1773 pMem = &pCardInfo->dynamicMem[idx];
1774 pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize );
1775 pMem->nocache_mem = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize ));
1776 pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx];
1779 pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
1781 return AGTIAPI_SUCCESS;
1785 /******************************************************************************
1786 agtiapi_cam_action()
1789 Parses CAM frames and triggers a corresponding action
1791 struct cam_sim *sim (IN) Pointer to SIM data structure
1792 union ccb * ccb (IN) Pointer to CAM ccb data structure
1795 ******************************************************************************/
1796 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
1798 struct agtiapi_softc *pmcsc;
1799 tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well
1800 tiDeviceInfo_t devInfo;
1801 int pathID, targetID, lunID;
1806 pmcsc = cam_sim_softc( sim );
1807 AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
1809 if (pmcsc == agNULL)
1811 AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
1814 mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
1816 AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
1818 pathID = xpt_path_path_id( ccb->ccb_h.path );
1819 targetID = xpt_path_target_id( ccb->ccb_h.path );
1820 lunID = xpt_path_lun_id( ccb->ccb_h.path );
1822 AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
1823 pathID, targetID, lunID );
1825 switch (ccb->ccb_h.func_code)
1829 struct ccb_pathinq *cpi;
1831 /* See architecure book p180*/
1833 cpi->version_num = 1;
1834 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16;
1835 cpi->target_sprt = 0;
1836 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
1837 cpi->hba_eng_cnt = 0;
1838 cpi->max_target = maxTargets - 1;
1839 cpi->max_lun = AGTIAPI_MAX_LUN;
1840 cpi->maxio = 1024 *1024; /* Max supported I/O size, in bytes. */
1841 cpi->initiator_id = 255;
1842 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1843 strncpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1844 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1845 cpi->unit_number = cam_sim_unit(sim);
1846 cpi->bus_id = cam_sim_bus(sim);
1847 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1848 cpi->base_transfer_speed = 150000;
1849 cpi->transport = XPORT_SAS;
1850 cpi->transport_version = 0;
1851 cpi->protocol = PROTO_SCSI;
1852 cpi->protocol_version = SCSI_REV_SPC3;
1853 cpi->ccb_h.status = CAM_REQ_CMP;
1856 case XPT_GET_TRAN_SETTINGS:
1858 struct ccb_trans_settings *cts;
1859 struct ccb_trans_settings_sas *sas;
1860 struct ccb_trans_settings_scsi *scsi;
1862 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1868 sas = &ccb->cts.xport_specific.sas;
1869 scsi = &cts->proto_specific.scsi;
1871 cts->protocol = PROTO_SCSI;
1872 cts->protocol_version = SCSI_REV_SPC3;
1873 cts->transport = XPORT_SAS;
1874 cts->transport_version = 0;
1876 sas->valid = CTS_SAS_VALID_SPEED;
1878 /* this sets the "MB/s transfers" */
1879 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1881 if (pmcsc->pWWNList != NULL)
1883 TID = INDEX(pmcsc, targetID);
1884 if (TID < maxTargets)
1886 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1892 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1893 switch (devInfo.info.devType_S_Rate & 0xF)
1895 case 0x8: speed = 150000;
1897 case 0x9: speed = 300000;
1899 case 0xA: speed = 600000;
1901 case 0xB: speed = 1200000;
1903 default: speed = 150000;
1907 sas->bitrate = speed;
1908 scsi->valid = CTS_SCSI_VALID_TQ;
1909 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1910 ccb->ccb_h.status = CAM_REQ_CMP;
1915 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1916 if ( SUCCESS == lRetVal )
1918 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1922 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1924 ccb->ccb_h.status = CAM_REQ_CMP;
1929 ccb->ccb_h.status = CAM_REQ_CMP;
1934 ccb->ccb_h.status = CAM_REQ_CMP;
1937 #if __FreeBSD_version >= 900026
1940 agtiapi_QueueSMP( pmcsc, ccb );
1943 #endif /* __FreeBSD_version >= 900026 */
1946 if(pmcsc->dev_scan == agFALSE)
1948 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1951 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1953 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1955 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1960 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1962 agtiapi_QueueCmnd_( pmcsc, ccb );
1967 case XPT_CALC_GEOMETRY:
1969 cam_calc_geometry(&ccb->ccg, 1);
1970 ccb->ccb_h.status = CAM_REQ_CMP;
1976 XPT_SET_TRAN_SETTINGS
1978 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1979 ccb->ccb_h.func_code );
1980 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1988 /******************************************************************************
1992 Get a ccb from free list or allocate a new one
1994 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
1996 Pointer to a ccb structure, or NULL if not available
1998 ******************************************************************************/
1999 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
2003 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2005 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2007 /* get the ccb from the head of the free list */
2008 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2010 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2011 pccb->pccbNext = NULL;
2012 pccb->flags = ACTIVE;
2013 pccb->startTime = 0;
2015 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2019 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2022 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2026 /******************************************************************************
2027 agtiapi_QueueCmnd_()
2030 Calls for sending CCB and excuting on HBA.
2032 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2033 union ccb * ccb (IN) Pointer to CAM ccb data structure
2035 0 - Command is pending to execute
2036 1 - Command returned without further process
2038 ******************************************************************************/
2039 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2041 struct ccb_scsiio *csio = &ccb->csio;
2042 pccb_t pccb = agNULL; // call dequeue
2043 int status = tiSuccess;
2044 U32 Channel = CMND_TO_CHANNEL(ccb);
2045 U32 TID = CMND_TO_TARGET(ccb);
2046 U32 LUN = CMND_TO_LUN(ccb);
2048 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2050 /* no support for CBD > 16 */
2051 if (csio->cdb_len > 16)
2053 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2055 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2056 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2057 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2061 if (TID < 0 || TID >= maxTargets)
2063 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2064 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2065 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2066 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2071 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2074 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2077 TID = INDEX(pmcsc, TID);
2078 targ = &pmcsc->pDevList[TID];
2082 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2084 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2085 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2086 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2090 pccb->pmcsc = pmcsc;
2091 /* initialize Command Control Block (CCB) */
2092 pccb->targetId = TID;
2094 pccb->channel = Channel;
2095 pccb->ccb = ccb; /* for struct scsi_cmnd */
2096 pccb->senseLen = csio->sense_len;
2097 pccb->startTime = ticks;
2098 pccb->pSenseData = (caddr_t) &csio->sense_data;
2099 pccb->tiSuperScsiRequest.flags = 0;
2101 /* each channel is reserved for different addr modes */
2102 pccb->addrMode = agtiapi_AddrModes[Channel];
2104 status = agtiapi_PrepareSGList(pmcsc, pccb);
2105 if (status != tiSuccess)
2107 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2108 agtiapi_FreeCCB(pmcsc, pccb);
2109 if (status == tiReject)
2111 ccb->ccb_h.status = CAM_REQ_INVALID;
2115 ccb->ccb_h.status = CAM_REQ_CMP;
2123 /******************************************************************************
2129 const char *ptitle (IN) A string to be printed
2130 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2133 ******************************************************************************/
2134 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2137 struct ccb_scsiio *csio;
2143 printf( "agtiapi_DumpCDB: no pccb here \n" );
2144 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2150 printf( "agtiapi_DumpCDB: no ccb here \n" );
2151 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2153 pccb, pccb->ccb, pccb->flags, ptitle );
2159 printf( "agtiapi_DumpCDB: no csio here \n" );
2160 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2161 pccb, pccb->ccb, pccb->flags, ptitle );
2164 len = MIN(64, csio->cdb_len);
2165 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2167 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2171 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2174 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2175 " len %d from %s\n",
2183 /******************************************************************************
2184 agtiapi_DoSoftReset()
2189 *data (IN) point to pmcsc (struct agtiapi_softc *)
2192 ******************************************************************************/
2193 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2196 unsigned long flags;
2198 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2199 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2200 ret = agtiapi_ResetCard( pmcsc, &flags );
2201 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2203 if( ret != AGTIAPI_SUCCESS )
2209 /******************************************************************************
2210 agtiapi_CheckIOTimeout()
2213 Timeout function for SCSI IO or TM
2215 *data (IN) point to pCard (ag_card_t *)
2218 ******************************************************************************/
2219 STATIC void agtiapi_CheckIOTimeout(void *data)
2221 U32 status = AGTIAPI_SUCCESS;
2223 struct agtiapi_softc *pmcsc;
2226 pmcsc = (struct agtiapi_softc *)data;
2228 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2230 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2232 pccb = (pccb_t)pmcsc->ccbChainList;
2234 /* if link is down, do nothing */
2235 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2237 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2241 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2242 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2247 /* Walk thorugh the IO Chain linked list to find the pending io */
2248 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2249 while (pccb_curr != NULL)
2251 /* start from 1st ccb in the chain */
2252 pccb_next = pccb_curr->pccbChainNext;
2253 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2254 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2256 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2258 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2259 !(pccb_curr->flags & TIMEDOUT) )
2261 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2262 "function -- flags=%x startTime=%ld tdData = %p\n",
2263 pccb_curr, pccb_curr->flags, pccb->startTime,
2264 pccb_curr->tiIORequest.tdData );
2265 pccb_curr->flags |= TIMEDOUT;
2266 status = agtiapi_StartTM(pmcsc, pccb_curr);
2267 if (status == AGTIAPI_SUCCESS)
2269 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2275 #ifdef AGTIAPI_LOCAL_RESET
2276 /* abort request did not go through */
2277 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2278 /* TODO: call Soft reset here */
2279 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2280 "abort request did not go thru ==> soft reset#7, then "
2281 "restart timer\n" );
2282 agtiapi_DoSoftReset (pmcsc);
2287 pccb_curr = pccb_next;
2290 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2293 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2297 /******************************************************************************
2301 DDI calls for aborting outstanding IO command
2303 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2304 unsigned long flags (IN/out) spinlock flags used in locking from
2307 AGTIAPI_SUCCESS - success
2309 ******************************************************************************/
2311 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2313 ccb_t *pTMccb = NULL;
2314 U32 status = AGTIAPI_SUCCESS;
2315 ag_device_t *pDevice = NULL;
2316 U32 TMstatus = tiSuccess;
2317 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2318 pccb, pccb->flags );
2321 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2322 status = AGTIAPI_SUCCESS;
2325 if (!pccb->tiIORequest.tdData)
2327 /* should not be the case */
2328 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2329 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2330 status = AGTIAPI_FAIL;
2334 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2335 clear pending TM_ABORT_TASK */
2336 /* Else Device State will not be put back to Operational, (refer FW) */
2337 if (pccb->flags & TASK_MANAGEMENT)
2339 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2341 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2343 /* TODO: call Soft reset here */
2344 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2345 "tiINIIOAbort() failed ==> soft reset#8\n" );
2346 agtiapi_DoSoftReset( pCard );
2350 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2352 status = AGTIAPI_SUCCESS;
2358 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2360 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2361 status = AGTIAPI_FAIL;
2364 pTMccb->pmcsc = pCard;
2365 pTMccb->targetId = pccb->targetId;
2366 pTMccb->devHandle = pccb->devHandle;
2367 if (pTMccb->targetId >= pCard->devDiscover)
2369 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2370 status = AGTIAPI_FAIL;
2373 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2375 return AGTIAPI_FAIL;
2377 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2379 return AGTIAPI_FAIL;
2381 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2382 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2384 return AGTIAPI_FAIL;
2387 /* save pending io to issue local abort at Task mgmt CB */
2388 pTMccb->pccbIO = pccb;
2389 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2391 pTMccb, pTMccb->flags, pTMccb->targetId );
2392 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2393 pTMccb->flags |= TASK_MANAGEMENT;
2394 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2397 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2399 &pTMccb->tiIORequest);
2400 if (TMstatus == tiSuccess)
2402 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2405 pTMccb->startTime = ticks;
2406 status = AGTIAPI_SUCCESS;
2408 else if (TMstatus == tiIONoDevice)
2410 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2413 status = AGTIAPI_SUCCESS;
2417 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2420 status = AGTIAPI_FAIL;
2421 agtiapi_FreeTMCCB(pCard, pTMccb);
2423 /* call TM_TARGET_RESET */
2428 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2429 (pccb) ? pccb->flags : -1);
2431 } /* agtiapi_StartTM */
2433 #if __FreeBSD_version > 901000
2434 /******************************************************************************
2435 agtiapi_PrepareSGList()
2438 This function prepares scatter-gather list for the given ccb
2440 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2441 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2447 ******************************************************************************/
2448 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2450 union ccb *ccb = pccb->ccb;
2451 struct ccb_scsiio *csio = &ccb->csio;
2452 struct ccb_hdr *ccbh = &ccb->ccb_h;
2453 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2455 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2456 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2458 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2460 switch((ccbh->flags & CAM_DATA_MASK))
2463 struct bus_dma_segment seg;
2464 case CAM_DATA_VADDR:
2465 /* Virtual address that needs to translated into one or more physical address ranges. */
2467 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2468 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2469 error = bus_dmamap_load( pmcsc->buffer_dmat,
2473 agtiapi_PrepareSGListCB,
2475 BUS_DMA_NOWAIT/* 0 */ );
2476 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2478 if (error == EINPROGRESS)
2480 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2481 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2482 xpt_freeze_simq(pmcsc->sim, 1);
2483 pmcsc->SimQFrozen = agTRUE;
2484 ccbh->status |= CAM_RELEASE_SIMQ;
2487 case CAM_DATA_PADDR:
2488 /* We have been given a pointer to single physical buffer. */
2489 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2490 //struct bus_dma_segment seg;
2491 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2493 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2494 seg.ds_len = csio->dxfer_len;
2495 // * 0xFF to be defined
2496 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2499 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2505 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2510 /******************************************************************************
2511 agtiapi_PrepareSGList()
2514 This function prepares scatter-gather list for the given ccb
2516 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2517 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2523 ******************************************************************************/
2524 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2526 union ccb *ccb = pccb->ccb;
2527 struct ccb_scsiio *csio = &ccb->csio;
2528 struct ccb_hdr *ccbh = &ccb->ccb_h;
2529 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2530 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2531 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2533 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2535 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2537 /* We've been given a pointer to a single buffer. */
2538 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2540 /* Virtual address that needs to translated into one or more physical address ranges. */
2542 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2543 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2544 error = bus_dmamap_load( pmcsc->buffer_dmat,
2548 agtiapi_PrepareSGListCB,
2550 BUS_DMA_NOWAIT/* 0 */ );
2551 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2553 if (error == EINPROGRESS)
2555 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2556 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2557 xpt_freeze_simq(pmcsc->sim, 1);
2558 pmcsc->SimQFrozen = agTRUE;
2559 ccbh->status |= CAM_RELEASE_SIMQ;
2564 /* We have been given a pointer to single physical buffer. */
2565 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2566 struct bus_dma_segment seg;
2567 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2569 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2570 seg.ds_len = csio->dxfer_len;
2571 // * 0xFF to be defined
2572 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2578 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2584 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2590 /******************************************************************************
2591 agtiapi_PrepareSGListCB()
2594 Callback function for bus_dmamap_load()
2595 This fuctions sends IO to LL layer.
2597 void *arg (IN) Pointer to the HBA data structure
2598 bus_dma_segment_t *segs (IN) Pointer to dma segment
2599 int nsegs (IN) number of dma segment
2600 int error (IN) error
2603 ******************************************************************************/
2604 static void agtiapi_PrepareSGListCB( void *arg,
2605 bus_dma_segment_t *segs,
2610 union ccb *ccb = pccb->ccb;
2611 struct ccb_scsiio *csio = &ccb->csio;
2613 struct agtiapi_softc *pmcsc;
2614 tiIniScsiCmnd_t *pScsiCmnd;
2616 bus_dmasync_op_t op;
2619 int io_is_encryptable = 0;
2620 unsigned long long start_lba = 0;
2622 U32 TID = CMND_TO_TARGET(ccb);
2624 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2626 pmcsc = pccb->pmcsc;
2628 if (error != tiSuccess)
2630 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2636 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2637 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2638 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2639 agtiapi_FreeCCB(pmcsc, pccb);
2640 ccb->ccb_h.status = CAM_REQ_CMP;
2646 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2648 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2649 " AGTIAPI_MAX_DMA_SEGS %d\n",
2650 nsegs, AGTIAPI_MAX_DMA_SEGS );
2651 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2652 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2653 agtiapi_FreeCCB(pmcsc, pccb);
2654 ccb->ccb_h.status = CAM_REQ_CMP;
2660 /* fill in IO information */
2661 pccb->dataLen = csio->dxfer_len;
2663 /* start fill in sgl structure */
2664 if (nsegs == 1 && error == 0xAABBCCDD)
2667 /* A single physical buffer */
2668 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2669 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2670 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2671 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2672 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2673 pccb->numSgElements = 1;
2675 else if (nsegs == 0 && error == 0xAAAAAAAA)
2677 /* no data transfer */
2678 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2679 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2681 pccb->numSgElements = 0;
2685 /* virtual/logical buffer */
2688 pccb->dataLen = segs[0].ds_len;
2690 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2691 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2692 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2693 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2694 pccb->numSgElements = nsegs;
2701 for (i = 0; i < nsegs; i++)
2703 pccb->sgList[i].len = htole32(segs[i].ds_len);
2704 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2705 pccb->sgList[i].type = htole32(tiSgl);
2706 pccb->dataLen += segs[i].ds_len;
2709 pccb->numSgElements = nsegs;
2710 /* set up sgl buffer address */
2711 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2712 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2713 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2714 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2715 pccb->numSgElements = nsegs;
2719 /* set data transfer direction */
2720 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2722 op = BUS_DMASYNC_PREWRITE;
2723 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2727 op = BUS_DMASYNC_PREREAD;
2728 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2731 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2733 pScsiCmnd->expDataLength = pccb->dataLen;
2735 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2737 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2741 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2744 CDB = &pScsiCmnd->cdb[0];
2748 case REQUEST_SENSE: /* requires different buffer */
2749 /* This code should not be excercised because SAS support auto sense
2750 For the completeness, vtophys() is still used here.
2752 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2753 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2754 phys_addr = vtophys(&csio->sense_data);
2755 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2756 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2757 pccb->dataLen = pccb->senseLen;
2758 pccb->numSgElements = 1;
2761 /* only using lun 0 for device type detection */
2762 pccb->flags |= AGTIAPI_INQUIRY;
2764 case TEST_UNIT_READY:
2768 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2774 start_lba = ((CDB[1] & 0x1f) << 16) |
2777 #ifdef HIALEAH_ENCRYPTION
2778 io_is_encryptable = 1;
2786 start_lba = (CDB[2] << 24) |
2790 #ifdef HIALEAH_ENCRYPTION
2791 io_is_encryptable = 1;
2797 start_lba = (CDB[2] << 24) |
2802 start_lba |= ((CDB[6] << 24) |
2806 #ifdef HIALEAH_ENCRYPTION
2807 io_is_encryptable = 1;
2814 /* fill device lun based one address mode */
2815 agtiapi_SetLunField(pccb);
2817 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2819 pccb->ccbStatus = tiIOFailed;
2820 pccb->scsiStatus = tiDetailNoLogin;
2821 agtiapi_FreeCCB(pmcsc, pccb);
2822 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2827 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2829 pccb->ccbStatus = tiIOFailed;
2830 pccb->scsiStatus = tiDetailNoLogin;
2831 agtiapi_FreeCCB(pmcsc, pccb);
2832 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2837 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2840 if ((pmcsc->flags & EDC_DATA) &&
2841 (pDev->flags & EDC_DATA))
2846 * Possible command supported -
2847 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2848 * READ_DEFECT_DATA, etc.
2849 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2850 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2852 * Do some data length adjustment and set chip operation instruction.
2860 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2861 #ifdef AGTIAPI_TEST_DIF
2862 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2864 pccb->flags |= EDC_DATA;
2866 #ifdef TEST_VERIFY_AND_FORWARD
2867 pccb->tiSuperScsiRequest.Dif.flags =
2868 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2869 if(pDev->sector_size == 520) {
2870 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2871 } else if(pDev->sector_size == 4104) {
2872 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2875 #ifdef AGTIAPI_TEST_DIF
2876 pccb->tiSuperScsiRequest.Dif.flags =
2877 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2880 #ifdef AGTIAPI_TEST_DIF
2881 switch(pDev->sector_size) {
2883 pccb->tiSuperScsiRequest.Dif.flags |=
2884 ( DIF_BLOCK_SIZE_520 << 16 );
2887 pccb->tiSuperScsiRequest.Dif.flags |=
2888 ( DIF_BLOCK_SIZE_4096 << 16 );
2891 pccb->tiSuperScsiRequest.Dif.flags |=
2892 ( DIF_BLOCK_SIZE_4160 << 16 );
2896 if(pCard->flags & EDC_DATA_CRC)
2897 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2899 /* Turn on upper 4 bits of UVM */
2900 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2903 #ifdef AGTIAPI_TEST_DPL
2904 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2905 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2906 cmnd->result = SCSI_HOST(DID_ERROR);
2909 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2911 #ifdef AGTIAPI_TEST_DIF
2913 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2914 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2916 /* Set LBA in UDT array */
2917 if(CDB[0] == READ_6) {
2918 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2919 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2920 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2921 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2922 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2923 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2924 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2925 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2926 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2927 } else if(CDB[0] == READ_16) {
2928 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2929 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2930 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2931 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2932 /* Note: 32 bits lost */
2941 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2942 pccb->flags |= EDC_DATA;
2943 #ifdef AGTIAPI_TEST_DIF
2944 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2945 pccb->tiSuperScsiRequest.Dif.flags =
2946 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2947 switch(pDev->sector_size) {
2949 pccb->tiSuperScsiRequest.Dif.flags |=
2950 (DIF_BLOCK_SIZE_520 << 16);
2953 pccb->tiSuperScsiRequest.Dif.flags |=
2954 ( DIF_BLOCK_SIZE_4096 << 16 );
2957 pccb->tiSuperScsiRequest.Dif.flags |=
2958 ( DIF_BLOCK_SIZE_4160 << 16 );
2962 /* Turn on upper 4 bits of UUM */
2963 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2965 #ifdef AGTIAPI_TEST_DPL
2966 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2967 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2968 cmnd->result = SCSI_HOST(DID_ERROR);
2971 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2973 #ifdef AGTIAPI_TEST_DIF
2975 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2976 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2978 /* Set LBA in UDT array */
2979 if(CDB[0] == WRITE_6) {
2980 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2981 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2982 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2983 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
2984 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2985 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2986 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2987 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2988 } else if(CDB[0] == WRITE_16) {
2989 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2990 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2991 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2992 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2993 /* Note: 32 bits lost */
2999 #endif /* end of DIF */
3001 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
3003 switch(csio->tag_action)
3005 case MSG_HEAD_OF_Q_TAG:
3006 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3009 pScsiCmnd->taskAttribute = TASK_ACA;
3011 case MSG_ORDERED_Q_TAG:
3012 pScsiCmnd->taskAttribute = TASK_ORDERED;
3014 case MSG_SIMPLE_Q_TAG: /* fall through */
3016 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3021 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3023 /* should be just before start IO */
3024 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3028 * If assigned pDevHandle is not available
3029 * then there is no need to send it to StartIO()
3031 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
3033 pccb->ccbStatus = tiIOFailed;
3034 pccb->scsiStatus = tiDetailNoLogin;
3035 agtiapi_FreeCCB(pmcsc, pccb);
3036 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3041 TID = INDEX(pmcsc, pccb->targetId);
3042 if ((TID >= pmcsc->devDiscover) ||
3043 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3046 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3047 " target %d tid %d/%d card %p ERROR pccb %p\n",
3048 pccb->devHandle, pccb->targetId, TID,
3049 pmcsc->devDiscover, pmcsc, pccb );
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
3059 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3060 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3061 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3063 #ifdef HIALEAH_ENCRYPTION
3064 if(pmcsc->encrypt && io_is_encryptable) {
3065 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3067 io_is_encryptable = 0;
3068 pccb->tiSuperScsiRequest.flags = 0;
3071 // put the request in send queue
3072 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3073 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3074 agtiapi_StartIO(pmcsc);
3078 /******************************************************************************
3082 Send IO request down for processing.
3084 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3087 ******************************************************************************/
3088 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3093 struct ccb_relsim crs;
3095 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3097 AG_LOCAL_LOCK( &pmcsc->sendLock );
3098 pccb = pmcsc->ccbSendHead;
3100 /* if link is down, do nothing */
3101 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3103 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3104 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3109 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3111 TID = INDEX(pmcsc, pccb->targetId);
3112 targ = &pmcsc->pDevList[TID];
3116 /* clear send queue */
3117 pmcsc->ccbSendHead = NULL;
3118 pmcsc->ccbSendTail = NULL;
3119 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3121 /* send all ccbs down */
3127 pccb_next = pccb->pccbNext;
3128 pccb->pccbNext = NULL;
3132 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3136 AG_IO_DUMPCCB( pccb );
3138 if (!pccb->devHandle)
3140 agtiapi_DumpCCB( pccb );
3141 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3145 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3148 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3149 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3151 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3153 if( pccb->devHandle ) {
3154 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3156 pccb->devHandle->osData );
3157 if( pccb->devHandle->osData ) {
3158 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3159 " -- active flag:%d\n",
3161 (pccb->devHandle->osData))->flags & ACTIVE );
3164 pccb->ccbStatus = tiIOFailed;
3165 pccb->scsiStatus = tiDetailNoLogin;
3166 agtiapi_Done( pmcsc, pccb );
3173 status = agtiapi_FastIOTest( pmcsc, pccb );
3175 status = tiINISuperIOStart( &pmcsc->tiRoot,
3178 &pccb->tiSuperScsiRequest,
3179 (void *)&pccb->tdIOReqBody,
3180 tiInterruptContext );
3186 static int squelchCount = 0;
3187 if ( 200000 == squelchCount++ ) // squelch prints
3189 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3191 squelchCount = 0; // reset count
3198 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3201 agtiapi_LogEvent( pmcsc,
3202 IOCTL_EVT_SEV_INFORMATIONAL,
3206 "tiINIIOStart tiDeviceBusy " );
3208 pccb->ccbStatus = tiIOFailed;
3209 pccb->scsiStatus = tiDeviceBusy;
3210 agtiapi_Done(pmcsc, pccb);
3214 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3217 agtiapi_LogEvent( pmcsc,
3218 IOCTL_EVT_SEV_INFORMATIONAL,
3222 "tiINIIOStart tiBusy " );
3225 pccb->ccbStatus = tiIOFailed;
3226 pccb->scsiStatus = tiBusy;
3227 agtiapi_Done(pmcsc, pccb);
3231 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3232 "ERROR\n", pccb->ccb );
3234 agtiapi_LogEvent( pmcsc,
3235 IOCTL_EVT_SEV_INFORMATIONAL,
3239 "tiINIIOStart invalid device handle " );
3242 /* return command back to OS due to no device available */
3243 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3244 pccb->ccbStatus = tiIOFailed;
3245 pccb->scsiStatus = tiDetailNoLogin;
3246 agtiapi_Done(pmcsc, pccb);
3248 /* for short cable pull, we want IO retried - 3-18-2005 */
3249 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3250 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3254 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3257 agtiapi_LogEvent(pmcsc,
3258 IOCTL_EVT_SEV_INFORMATIONAL,
3262 "tiINIIOStart tiError ");
3264 pccb->ccbStatus = tiIOFailed;
3265 pccb->scsiStatus = tiDetailOtherError;
3266 agtiapi_Done(pmcsc, pccb);
3269 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3272 agtiapi_LogEvent(pmcsc,
3273 IOCTL_EVT_SEV_ERROR,
3277 "tiINIIOStart unexpected status ");
3279 pccb->ccbStatus = tiIOFailed;
3280 pccb->scsiStatus = tiDetailOtherError;
3281 agtiapi_Done(pmcsc, pccb);
3287 /* some IO requests might have been completed */
3288 AG_GET_DONE_PCCB(pccb, pmcsc);
3292 /******************************************************************************
3296 Send SMP request down for processing.
3298 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3301 ******************************************************************************/
3302 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3306 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3308 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3309 pccb = pmcsc->smpSendHead;
3311 /* if link is down, do nothing */
3312 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3314 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3315 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3319 /* clear send queue */
3320 pmcsc->smpSendHead = NULL;
3321 pmcsc->smpSendTail = NULL;
3322 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3324 /* send all ccbs down */
3330 pccb_next = pccb->pccbNext;
3331 pccb->pccbNext = NULL;
3335 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3340 if (!pccb->devHandle)
3342 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3346 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3347 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3348 pccb, pccb->retryCount );
3349 status = tiINISMPStart( &pmcsc->tiRoot,
3353 (void *)&pccb->tdIOReqBody,
3354 tiInterruptContext);
3361 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3363 /* pending ccb back to send queue */
3364 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3365 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3368 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3370 pccb->ccbStatus = tiSMPFailed;
3371 agtiapi_SMPDone(pmcsc, pccb);
3374 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3376 pccb->ccbStatus = tiSMPFailed;
3377 agtiapi_SMPDone(pmcsc, pccb);
3383 /* some SMP requests might have been completed */
3384 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3389 #if __FreeBSD_version > 901000
3390 /******************************************************************************
3391 agtiapi_PrepareSMPSGList()
3394 This function prepares scatter-gather list for the given ccb
3396 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3397 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3403 ******************************************************************************/
3404 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3406 /* Pointer to CAM's ccb */
3407 union ccb *ccb = pccb->ccb;
3408 struct ccb_smpio *csmpio = &ccb->smpio;
3409 struct ccb_hdr *ccbh = &ccb->ccb_h;
3411 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3412 switch((ccbh->flags & CAM_DATA_MASK))
3414 case CAM_DATA_PADDR:
3415 case CAM_DATA_SG_PADDR:
3416 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3417 ccb->ccb_h.status = CAM_REQ_INVALID;
3423 * Currently we do not support Multiple SG list
3424 * return error for now
3426 if ( (csmpio->smp_request_sglist_cnt > 1)
3427 || (csmpio->smp_response_sglist_cnt > 1) )
3429 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3430 ccb->ccb_h.status = CAM_REQ_INVALID;
3435 if ( csmpio->smp_request_sglist_cnt != 0 )
3438 * Virtual address that needs to translated into
3439 * one or more physical address ranges.
3442 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3443 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3444 error = bus_dmamap_load( pmcsc->buffer_dmat,
3446 csmpio->smp_request,
3447 csmpio->smp_request_len,
3448 agtiapi_PrepareSMPSGListCB,
3450 BUS_DMA_NOWAIT /* 0 */ );
3452 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3454 if (error == EINPROGRESS)
3457 * So as to maintain ordering,
3458 * freeze the controller queue
3459 * until our mapping is
3462 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3463 xpt_freeze_simq( pmcsc->sim, 1 );
3464 pmcsc->SimQFrozen = agTRUE;
3465 ccbh->status |= CAM_RELEASE_SIMQ;
3468 if( csmpio->smp_response_sglist_cnt != 0 )
3471 * Virtual address that needs to translated into
3472 * one or more physical address ranges.
3475 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3476 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3477 error = bus_dmamap_load( pmcsc->buffer_dmat,
3479 csmpio->smp_response,
3480 csmpio->smp_response_len,
3481 agtiapi_PrepareSMPSGListCB,
3483 BUS_DMA_NOWAIT /* 0 */ );
3485 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3487 if ( error == EINPROGRESS )
3490 * So as to maintain ordering,
3491 * freeze the controller queue
3492 * until our mapping is
3495 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3496 xpt_freeze_simq( pmcsc->sim, 1 );
3497 pmcsc->SimQFrozen = agTRUE;
3498 ccbh->status |= CAM_RELEASE_SIMQ;
3504 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3505 (csmpio->smp_response_sglist_cnt == 0) )
3507 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3508 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3509 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3510 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3512 // 0xFF to be defined
3513 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3515 pccb->tiSMPFrame.flag = 0;
3522 /******************************************************************************
3523 agtiapi_PrepareSMPSGList()
3526 This function prepares scatter-gather list for the given ccb
3528 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3529 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3535 ******************************************************************************/
3536 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3538 /* Pointer to CAM's ccb */
3539 union ccb *ccb = pccb->ccb;
3540 struct ccb_smpio *csmpio = &ccb->smpio;
3541 struct ccb_hdr *ccbh = &ccb->ccb_h;
3543 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3545 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3547 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3548 "not supported\n" );
3549 ccb->ccb_h.status = CAM_REQ_INVALID;
3554 if (ccbh->flags & CAM_SCATTER_VALID)
3557 * Currently we do not support Multiple SG list
3558 * return error for now
3560 if ( (csmpio->smp_request_sglist_cnt > 1)
3561 || (csmpio->smp_response_sglist_cnt > 1) )
3563 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3564 "not supported\n" );
3565 ccb->ccb_h.status = CAM_REQ_INVALID;
3569 if ( csmpio->smp_request_sglist_cnt != 0 )
3572 * Virtual address that needs to translated into
3573 * one or more physical address ranges.
3576 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3577 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3578 error = bus_dmamap_load( pmcsc->buffer_dmat,
3580 csmpio->smp_request,
3581 csmpio->smp_request_len,
3582 agtiapi_PrepareSMPSGListCB,
3584 BUS_DMA_NOWAIT /* 0 */ );
3586 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3588 if (error == EINPROGRESS)
3591 * So as to maintain ordering,
3592 * freeze the controller queue
3593 * until our mapping is
3596 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3597 xpt_freeze_simq( pmcsc->sim, 1 );
3598 pmcsc->SimQFrozen = agTRUE;
3599 ccbh->status |= CAM_RELEASE_SIMQ;
3602 if( csmpio->smp_response_sglist_cnt != 0 )
3605 * Virtual address that needs to translated into
3606 * one or more physical address ranges.
3609 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3610 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3611 error = bus_dmamap_load( pmcsc->buffer_dmat,
3613 csmpio->smp_response,
3614 csmpio->smp_response_len,
3615 agtiapi_PrepareSMPSGListCB,
3617 BUS_DMA_NOWAIT /* 0 */ );
3619 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3621 if ( error == EINPROGRESS )
3624 * So as to maintain ordering,
3625 * freeze the controller queue
3626 * until our mapping is
3629 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3630 xpt_freeze_simq( pmcsc->sim, 1 );
3631 pmcsc->SimQFrozen = agTRUE;
3632 ccbh->status |= CAM_RELEASE_SIMQ;
3638 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3639 (csmpio->smp_response_sglist_cnt == 0) )
3641 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3642 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3643 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3644 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3646 // 0xFF to be defined
3647 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3649 pccb->tiSMPFrame.flag = 0;
3656 /******************************************************************************
3657 agtiapi_PrepareSMPSGListCB()
3660 Callback function for bus_dmamap_load()
3661 This fuctions sends IO to LL layer.
3663 void *arg (IN) Pointer to the HBA data structure
3664 bus_dma_segment_t *segs (IN) Pointer to dma segment
3665 int nsegs (IN) number of dma segment
3666 int error (IN) error
3669 ******************************************************************************/
3670 static void agtiapi_PrepareSMPSGListCB( void *arg,
3671 bus_dma_segment_t *segs,
3676 union ccb *ccb = pccb->ccb;
3677 struct agtiapi_softc *pmcsc;
3678 U32 TID = CMND_TO_TARGET(ccb);
3680 tiDeviceHandle_t *tiExpDevHandle;
3681 tiPortalContext_t *tiExpPortalContext;
3682 ag_portal_info_t *tiExpPortalInfo;
3684 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3686 pmcsc = pccb->pmcsc;
3688 if ( error != tiSuccess )
3690 if (error == 0xAABBCCDD)
3696 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3698 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3699 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3700 agtiapi_FreeCCB( pmcsc, pccb );
3701 ccb->ccb_h.status = CAM_REQ_CMP;
3707 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3709 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3710 "AGTIAPI_MAX_DMA_SEGS %d\n",
3711 nsegs, AGTIAPI_MAX_DMA_SEGS );
3712 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3713 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3714 agtiapi_FreeCCB( pmcsc, pccb );
3715 ccb->ccb_h.status = CAM_REQ_CMP;
3721 * If assigned pDevHandle is not available
3722 * then there is no need to send it to StartIO()
3724 /* TODO: Add check for deviceType */
3725 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3727 agtiapi_FreeCCB( pmcsc, pccb );
3728 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3733 TID = INDEX( pmcsc, pccb->targetId );
3734 if ( (TID >= pmcsc->devDiscover) ||
3735 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3737 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3738 "target %d tid %d/%d "
3739 "card %p ERROR pccb %p\n",
3746 agtiapi_FreeCCB( pmcsc, pccb );
3747 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3752 /* TODO: add indirect handling */
3753 /* set the flag correctly based on Indiret SMP request and responce */
3755 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3756 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3758 pccb->targetId, TID,
3761 tiExpDevHandle = pccb->devHandle;
3762 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3763 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3764 /* Look for the expander associated with the ses device */
3765 status = tiINIGetExpander( &pmcsc->tiRoot,
3770 if ( status != tiSuccess )
3772 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3774 agtiapi_FreeCCB( pmcsc, pccb );
3775 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3781 /* this is expander device */
3782 pccb->devHandle = tiExpDevHandle;
3783 /* put the request in send queue */
3784 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3785 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3787 agtiapi_StartSMP( pmcsc );
3793 /******************************************************************************
3797 Processing completed ccbs
3799 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3800 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3803 ******************************************************************************/
3804 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3806 pccb_t pccb_curr = pccb;
3809 tiIniScsiCmnd_t *cmnd;
3812 AGTIAPI_IO("agtiapi_Done: start\n");
3815 /* start from 1st ccb in the chain */
3816 pccb_next = pccb_curr->pccbNext;
3818 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3820 /* send command back and release the ccb */
3821 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3823 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3825 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3826 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3830 CMND_DMA_UNMAP(pmcsc, ccb);
3832 /* send the request back to the CAM */
3833 ccb = pccb_curr->ccb;
3834 agtiapi_FreeCCB(pmcsc, pccb_curr);
3837 pccb_curr = pccb_next;
3842 /******************************************************************************
3846 Processing completed ccbs
3848 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3849 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3853 ******************************************************************************/
3854 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3856 pccb_t pccb_curr = pccb;
3861 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3865 /* start from 1st ccb in the chain */
3866 pccb_next = pccb_curr->pccbNext;
3868 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3870 CMND_DMA_UNMAP(pmcsc, ccb);
3872 /* send the request back to the CAM */
3873 ccb = pccb_curr->ccb;
3874 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3878 pccb_curr = pccb_next;
3881 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3885 /******************************************************************************
3889 Utility function for dumping in hex
3891 const char *ptitle (IN) A string to be printed
3892 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3893 int len (IN) The lengther of the buffer
3896 ******************************************************************************/
3897 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3900 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3903 AGTIAPI_PRINTK("pbuf is NULL\n");
3906 for (i = 0; i < len; )
3910 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3911 pbuf[i+2], pbuf[i+3] );
3916 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3920 AGTIAPI_PRINTK("\n");
3924 /******************************************************************************
3925 agtiapi_CheckError()
3928 Processes status pertaining to the ccb -- whether it was
3929 completed successfully, aborted, or error encountered.
3931 ag_card_t *pCard (IN) Pointer to HBA data structure
3932 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3934 0 - the command retry is required
3935 1 - the command process is completed
3938 ******************************************************************************/
3939 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3941 ag_device_t *pDevice;
3942 // union ccb * ccb = pccb->ccb;
3950 AGTIAPI_IO("agtiapi_CheckError: start\n");
3953 /* shouldn't be here but just in case we do */
3954 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3955 agtiapi_FreeCCB(pmcsc, pccb);
3961 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3963 if (pmcsc->pWWNList != NULL)
3965 TID = INDEX(pmcsc, pccb->targetId);
3966 if (TID < maxTargets)
3968 pDevice = &pmcsc->pDevList[TID];
3969 if (pDevice != NULL)
3978 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3979 agtiapi_FreeCCB(pmcsc, pccb);
3984 ccb->csio.scsi_status = pccb->scsiStatus;
3986 if(pDevice->CCBCount > 0){
3987 atomic_subtract_int(&pDevice->CCBCount,1);
3989 AG_LOCAL_LOCK(&pmcsc->freezeLock);
3990 if(pmcsc->freezeSim == agTRUE)
3992 pmcsc->freezeSim = agFALSE;
3993 xpt_release_simq(pmcsc->sim, 1);
3995 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
3997 switch (pccb->ccbStatus)
4000 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
4002 if (pccb->scsiStatus == SCSI_STATUS_OK)
4004 ccb->ccb_h.status = CAM_REQ_CMP;
4007 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4009 ccb->ccb_h.status = CAM_REQ_ABORTED;
4013 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4015 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4017 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4023 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4024 /* resid is ignored for this condition */
4025 ccb->csio.resid = 0;
4026 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4029 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4030 ccb->csio.resid = pccb->scsiStatus;
4031 ccb->ccb_h.status = CAM_REQ_CMP;
4032 ccb->csio.scsi_status = SCSI_STATUS_OK;
4036 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4037 pccb, pccb->scsiStatus, pccb->targetId );
4038 if (pccb->scsiStatus == tiDeviceBusy)
4040 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4042 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4043 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4044 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4046 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4047 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4050 else if(pccb->scsiStatus == tiBusy)
4052 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4053 if(pmcsc->freezeSim == agFALSE)
4055 pmcsc->freezeSim = agTRUE;
4056 xpt_freeze_simq(pmcsc->sim, 1);
4058 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4059 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4060 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4062 else if (pccb->scsiStatus == tiDetailNoLogin)
4064 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4065 "tiDetailNoLogin ERROR\n", pccb );
4066 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4068 else if (pccb->scsiStatus == tiDetailNotValid)
4070 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4071 "tiDetailNotValid ERROR\n", pccb );
4072 ccb->ccb_h.status = CAM_REQ_INVALID;
4074 else if (pccb->scsiStatus == tiDetailAbortLogin)
4076 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4077 "tiDetailAbortLogin ERROR\n", pccb );
4078 ccb->ccb_h.status = CAM_REQ_ABORTED;
4080 else if (pccb->scsiStatus == tiDetailAbortReset)
4082 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4083 "tiDetailAbortReset ERROR\n", pccb );
4084 ccb->ccb_h.status = CAM_REQ_ABORTED;
4086 else if (pccb->scsiStatus == tiDetailAborted)
4088 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4089 "tiDetailAborted ERROR\n", pccb );
4090 ccb->ccb_h.status = CAM_REQ_ABORTED;
4092 else if (pccb->scsiStatus == tiDetailOtherError)
4094 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4095 "tiDetailOtherError ERROR\n", pccb );
4096 ccb->ccb_h.status = CAM_REQ_ABORTED;
4100 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4101 pccb, pccb->scsiStatus, pccb->targetId );
4102 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4104 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4105 "tiDetailDifAppTagMismatch\n", pccb );
4106 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4108 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4110 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4111 "tiDetailDifRefTagMismatch\n", pccb );
4112 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4114 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4116 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4117 "tiDetailDifCrcMismatch\n", pccb );
4118 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4121 #ifdef HIALEAH_ENCRYPTION
4122 case tiIOEncryptError:
4123 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4124 pccb, pccb->scsiStatus, pccb->targetId );
4125 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4127 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4128 "tiDetailDekKeyCacheMiss ERROR\n",
4129 __FUNCTION__, pccb );
4130 ccb->ccb_h.status = CAM_REQ_ABORTED;
4131 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4133 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4135 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4136 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4137 ccb->ccb_h.status = CAM_REQ_ABORTED;
4138 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4143 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4144 pccb, pccb->ccbStatus, pccb->targetId );
4145 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4153 /******************************************************************************
4154 agtiapi_SMPCheckError()
4157 Processes status pertaining to the ccb -- whether it was
4158 completed successfully, aborted, or error encountered.
4160 ag_card_t *pCard (IN) Pointer to HBA data structure
4161 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4163 0 - the command retry is required
4164 1 - the command process is completed
4167 ******************************************************************************/
4168 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4170 union ccb * ccb = pccb->ccb;
4172 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4176 /* shouldn't be here but just in case we do */
4177 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4179 agtiapi_FreeSMPCCB(pmcsc, pccb);
4183 switch (pccb->ccbStatus)
4186 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4189 ccb->ccb_h.status = CAM_REQ_CMP;
4192 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4195 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4198 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4203 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4212 /******************************************************************************
4213 agtiapi_HandleEncryptedIOFailure():
4220 ******************************************************************************/
4221 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4224 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4228 /******************************************************************************
4234 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4235 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4239 ******************************************************************************/
4240 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4243 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4244 pccb->ccbStatus = 0;
4245 pccb->scsiStatus = 0;
4246 pccb->startTime = ticks;
4248 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4249 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4250 pccb->retryCount, pccb->flags );
4252 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4253 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4258 /******************************************************************************
4262 Dump CCB for debuging
4264 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4267 ******************************************************************************/
4268 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4270 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4275 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4280 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4281 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4282 pccb->numSgElements);
4283 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4286 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4287 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4288 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4289 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4290 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4291 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4292 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4293 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4294 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4295 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4296 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4297 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4298 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4299 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4300 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4302 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4303 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4304 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4305 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4306 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4307 pccb->tiSuperScsiRequest.agSgl1.upper,
4308 pccb->tiSuperScsiRequest.agSgl1.lower,
4309 pccb->tiSuperScsiRequest.agSgl1.len,
4310 pccb->tiSuperScsiRequest.agSgl1.type);
4313 /******************************************************************************
4314 agtiapi_eh_HostReset()
4317 A new error handler of Host Reset command.
4319 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4324 ******************************************************************************/
4325 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4327 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4332 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4333 return tiInvalidHandle;
4337 agtiapi_LogEvent( pmcsc,
4338 IOCTL_EVT_SEV_INFORMATIONAL,
4342 "agtiapi_eh_HostReset! " );
4345 return agtiapi_DoSoftReset( pmcsc );
4349 int agtiapi_eh_DeviceReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4351 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4356 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4357 return tiInvalidHandle;
4359 return agtiapi_DoSoftReset( pmcsc );
4361 /******************************************************************************
4365 Put ccb in ccb queue at the tail
4367 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4368 pccb_t *phead (IN) Double pointer to ccb queue head
4369 pccb_t *ptail (IN) Double pointer to ccb queue tail
4370 ccb_t *pccb (IN) Poiner to a ccb to be queued
4373 Put the ccb to the tail of queue
4374 ******************************************************************************/
4375 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4378 #ifdef AGTIAPI_LOCAL_LOCK
4383 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4384 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4385 if (phead == NULL || ptail == NULL)
4387 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4389 pccb->pccbNext = NULL;
4390 AG_LOCAL_LOCK( mutex );
4393 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4398 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4400 (*ptail)->pccbNext = pccb;
4403 AG_LOCAL_UNLOCK( mutex );
4408 /******************************************************************************
4419 ******************************************************************************/
4420 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4422 pccb_t pccb = agNULL; /* call dequeue */
4423 int status = tiSuccess;
4424 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4426 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4429 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4431 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4432 ccb->ccb_h.status = CAM_REQ_CMP;
4436 pccb->pmcsc = pmcsc;
4438 /* initialize Command Control Block (CCB) */
4439 pccb->targetId = targetID;
4440 pccb->ccb = ccb; /* for struct scsi_cmnd */
4442 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4444 if (status != tiSuccess)
4446 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4447 agtiapi_FreeCCB(pmcsc, pccb);
4448 if (status == tiReject)
4450 ccb->ccb_h.status = CAM_REQ_INVALID;
4454 ccb->ccb_h.status = CAM_REQ_CMP;
4463 /******************************************************************************
4464 agtiapi_SetLunField()
4467 Set LUN field based on different address mode
4469 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4472 ******************************************************************************/
4473 void agtiapi_SetLunField(ccb_t *pccb)
4477 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4479 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4481 switch (pccb->addrMode)
4483 case AGTIAPI_PERIPHERAL:
4485 *pchar = (U08)pccb->lun;
4487 case AGTIAPI_VOLUME_SET:
4488 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4489 (U08)((pccb->lun >> 8) & 0x3F);
4490 *pchar = (U08)pccb->lun;
4492 case AGTIAPI_LUN_ADDR:
4493 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4495 *pchar = (U08)pccb->lun;
4503 /*****************************************************************************
4507 Free a ccb and put it back to ccbFreeList.
4509 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4510 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4514 *****************************************************************************/
4515 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4517 union ccb *ccb = pccb->ccb;
4518 bus_dmasync_op_t op;
4520 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4521 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4523 #ifdef AGTIAPI_TEST_EPL
4524 tiEncrypt_t *encrypt;
4527 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4529 if (pccb->sgList != agNULL)
4531 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4535 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4538 /* set data transfer direction */
4539 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4541 op = BUS_DMASYNC_POSTWRITE;
4545 op = BUS_DMASYNC_POSTREAD;
4548 if (pccb->numSgElements == 0)
4551 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4553 else if (pccb->numSgElements == 1)
4555 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4556 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4557 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4558 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4562 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4563 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4564 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4565 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4568 #ifdef AGTIAPI_TEST_DPL
4569 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4571 memset( (char *) pccb->dplPtr,
4573 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4574 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4575 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4576 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4580 #ifdef AGTIAPI_TEST_EPL
4581 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4582 if (encrypt->enableEncryptionPerLA == TRUE) {
4583 encrypt->enableEncryptionPerLA = FALSE;
4584 encrypt->EncryptionPerLAAddrLo = 0;
4585 encrypt->EncryptionPerLAAddrHi = 0;
4589 #ifdef ENABLE_SATA_DIF
4590 if (pccb->holePtr && pccb->dmaHandleHole)
4591 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4594 pccb->dmaHandleHole );
4596 pccb->dmaHandleHole = 0;
4600 pccb->retryCount = 0;
4601 pccb->ccbStatus = 0;
4602 pccb->scsiStatus = 0;
4603 pccb->startTime = 0;
4604 pccb->dmaHandle = 0;
4605 pccb->numSgElements = 0;
4606 pccb->tiIORequest.tdData = 0;
4607 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4609 #ifdef HIALEAH_ENCRYPTION
4611 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4616 pccb->pccbIO = NULL;
4617 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4618 pmcsc->ccbFreeList = (caddr_t *)pccb;
4622 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4627 /******************************************************************************
4631 Flush all in processed ccbs.
4633 ag_card_t *pCard (IN) Pointer to HBA data structure
4634 U32 flag (IN) Flag to call back
4637 ******************************************************************************/
4638 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4643 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4644 for( pccb = (pccb_t)pCard->ccbChainList;
4646 pccb = pccb->pccbChainNext ) {
4647 if( pccb->flags == 0 )
4649 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4653 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4655 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4656 agtiapi_FreeTMCCB( pCard, pccb );
4660 if ( pccb->flags & TAG_SMP )
4662 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4663 agtiapi_FreeSMPCCB( pCard, pccb );
4667 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4668 agtiapi_FreeCCB( pCard, pccb );
4671 CMND_DMA_UNMAP( pCard, ccb );
4672 if( flag == AGTIAPI_CALLBACK ) {
4673 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4681 /*****************************************************************************
4682 agtiapi_FreeSMPCCB()
4685 Free a ccb and put it back to ccbFreeList.
4687 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4688 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4692 *****************************************************************************/
4693 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4695 union ccb *ccb = pccb->ccb;
4696 bus_dmasync_op_t op;
4698 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4699 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4701 /* set data transfer direction */
4702 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4704 op = BUS_DMASYNC_POSTWRITE;
4708 op = BUS_DMASYNC_POSTREAD;
4711 if (pccb->numSgElements == 0)
4714 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4716 else if (pccb->numSgElements == 1)
4718 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4719 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4720 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4721 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4725 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4726 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4727 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4728 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4731 /*dma api cleanning*/
4733 pccb->retryCount = 0;
4734 pccb->ccbStatus = 0;
4735 pccb->startTime = 0;
4736 pccb->dmaHandle = 0;
4737 pccb->numSgElements = 0;
4738 pccb->tiIORequest.tdData = 0;
4739 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4743 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4744 pmcsc->ccbFreeList = (caddr_t *)pccb;
4748 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4753 /*****************************************************************************
4757 Free a ccb and put it back to ccbFreeList.
4759 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4760 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4764 *****************************************************************************/
4765 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4767 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4768 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4770 pccb->retryCount = 0;
4771 pccb->ccbStatus = 0;
4772 pccb->scsiStatus = 0;
4773 pccb->startTime = 0;
4774 pccb->dmaHandle = 0;
4775 pccb->numSgElements = 0;
4776 pccb->tiIORequest.tdData = 0;
4777 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4780 pccb->pccbIO = NULL;
4781 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4782 pmcsc->ccbFreeList = (caddr_t *)pccb;
4784 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4787 /******************************************************************************
4788 agtiapi_CheckAllVectors():
4794 Currently, not used.
4795 ******************************************************************************/
4796 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4798 #ifdef SPC_MSIX_INTR
4799 if (!agtiapi_intx_mode)
4803 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4804 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4805 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4808 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4809 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4811 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4812 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4818 /******************************************************************************
4822 Check call back function returned event for process completion
4824 struct agtiapi_softc *pCard Pointer to card data structure
4825 U32 milisec (IN) Waiting time for expected event
4826 U32 flag (IN) Flag of the event to check
4827 U32 *pStatus (IN) Pointer to status of the card or port to check
4829 AGTIAPI_SUCCESS - event comes as expected
4830 AGTIAPI_FAIL - event not coming
4833 ******************************************************************************/
4834 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4837 volatile U32 *pStatus )
4839 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4840 initiatorOption.usecsPerTick / 1000;
4841 S32 i = milisec/msecsPerTick;
4842 AG_GLOBAL_ARG( _flags );
4844 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4845 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4851 if (*pStatus & TASK_MANAGEMENT)
4853 if (*pStatus & AGTIAPI_CB_DONE)
4855 if( flag == 0 || *pStatus & flag )
4856 return AGTIAPI_SUCCESS;
4858 return AGTIAPI_FAIL;
4861 else if (pCard->flags & AGTIAPI_CB_DONE)
4863 if( flag == 0 || *pStatus & flag )
4864 return AGTIAPI_SUCCESS;
4866 return AGTIAPI_FAIL;
4869 agtiapi_DelayMSec( msecsPerTick );
4871 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4872 tiCOMTimerTick( &pCard->tiRoot );
4874 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4875 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4880 if( *pStatus & TASK_MANAGEMENT )
4881 *pStatus |= TASK_TIMEOUT;
4883 return AGTIAPI_FAIL;
4887 /******************************************************************************
4888 agtiapi_DiscoverTgt()
4891 Discover available devices
4893 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4896 ******************************************************************************/
4897 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4900 ag_portal_data_t *pPortalData;
4903 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4904 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4905 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4907 pPortalData = pCard->pPortalData;
4908 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4910 pCard->flags &= ~AGTIAPI_CB_DONE;
4911 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4913 if (pCard->flags & AGTIAPI_INIT_TIME)
4915 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4916 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4918 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4920 pPortalData, count );
4922 * There is no need to spend time on discovering device
4923 * if port is not ready to do so.
4932 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4934 AGTIAPI_INIT_DELAY(1000);
4936 pCard->flags &= ~AGTIAPI_CB_DONE;
4937 if (tiINIDiscoverTargets(&pCard->tiRoot,
4938 &pPortalData->portalInfo.tiPortalContext,
4939 FORCE_PERSISTENT_ASSIGN_MASK)
4941 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4944 * Should wait till discovery completion to start
4945 * next portal. However, lower layer have issue on
4946 * multi-portal case under Linux.
4950 pPortalData = pCard->pPortalData;
4951 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4953 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4955 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4956 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4958 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4959 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4962 PORTAL_STATUS(pPortalData) );
4964 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4965 "completed, status 0x%x\n",
4966 pPortalData, PORTAL_STATUS(pPortalData) );
4969 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4976 * Calling to get device handle should be done per portal based
4977 * and better right after discovery is done. However, lower iscsi
4978 * layer may not returns discovery complete in correct sequence or we
4979 * ran out time. We get device handle for all portals together
4980 * after discovery is done or timed out.
4982 pPortalData = pCard->pPortalData;
4983 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4986 * We try to get device handle no matter
4987 * if discovery is completed or not.
4989 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
4993 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
4995 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
4997 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
5000 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
5001 (pCard->tgtCount > 0))
5002 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
5003 AGTIAPI_PORT_LINK_UP );
5013 /******************************************************************************
5017 Prepares CCB including DMA map.
5019 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5020 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5022 U32 max_ccb (IN) count
5026 ******************************************************************************/
5027 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5041 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5042 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5043 nsegs = AGTIAPI_NSEGS;
5044 sgl_sz = sizeof(tiSgl_t) * nsegs;
5045 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5046 "%lu, max_ccb %d\n",
5053 ccb_sz = (AGTIAPI_CCB_SIZE + cache_line_size() - 1) & ~(cache_line_size() -1);
5054 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5056 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5058 memset((void *)hdr, 0, size);
5059 hdr->next = pCard->ccbAllocList;
5060 pCard->ccbAllocList = hdr;
5062 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5064 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5066 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5068 pccb->tiIORequest.osData = (void *)pccb;
5071 * Initially put all the ccbs on the free list
5072 * in addition to chainlist.
5073 * ccbChainList is a list of all available ccbs
5074 * (free/active everything)
5076 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5077 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5079 pCard->ccbChainList = (caddr_t *)pccb;
5080 pCard->ccbFreeList = (caddr_t *)pccb;
5083 #ifdef AGTIAPI_ALIGN_CHECK
5085 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5086 if (pccb->devHandle & 0x63)
5087 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5088 if (&pccb->lun & 0x63)
5089 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5090 if (&pccb->targetId & 0x63)
5091 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5092 if (&pccb->ccbStatus & 0x63)
5093 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5094 if (&pccb->scsiStatus & 0x63)
5095 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5096 if (&pccb->dataLen & 0x63)
5097 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5098 if (&pccb->senseLen & 0x63)
5099 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5100 if (&pccb->numSgElements & 0x63)
5101 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5102 if (&pccb->retryCount & 0x63)
5103 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5104 if (&pccb->flags & 0x63)
5105 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5106 if (&pccb->pSenseData & 0x63)
5107 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5108 if (&pccb->sgList[0] & 0x63)
5109 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5110 if (&pccb->pccbNext & 0x63)
5111 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5112 if (&pccb->pccbChainNext & 0x63)
5113 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5114 if (&pccb->cmd & 0x63)
5115 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5116 if( &pccb->startTime & 0x63 )
5117 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5118 if (&pccb->tiIORequest & 0x63)
5119 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5120 if (&pccb->tdIOReqBody & 0x63)
5121 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5122 if (&pccb->tiSuperScsiRequest & 0x63)
5123 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5124 &pccb->tiSuperScsiRequest );
5126 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5129 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5132 /* assigns tiSgl_t memory to pccb */
5133 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5134 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5136 pccb->pccbIO = NULL;
5137 pccb->startTime = 0;
5140 #ifdef AGTIAPI_ALIGN_CHECK
5141 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5146 /******************************************************************************
5150 Create and initialize per card based CCB pool.
5152 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5153 int tgtCount (IN) Count
5155 Total number of ccb allocated
5157 ******************************************************************************/
5158 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5161 U32 max_ccb, size, ccb_sz, hdr_sz;
5162 int no_allocs = 0, i;
5165 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5166 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5167 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5169 #ifndef HOTPLUG_SUPPORT
5170 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5173 if (tgtCount > AGSA_MAX_INBOUND_Q)
5174 tgtCount = AGSA_MAX_INBOUND_Q;
5177 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5178 ccb_sz = ( (AGTIAPI_CCB_SIZE + cache_line_size() - 1) &
5179 ~(cache_line_size() -1) );
5180 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5181 size = ccb_sz * max_ccb + hdr_sz;
5183 for (i = 0; i < (1 << no_allocs); i++)
5185 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5188 panic( "agtiapi_InitCCBs: bug!!!\n" );
5192 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5201 #ifdef LINUX_PERBI_SUPPORT
5202 /******************************************************************************
5203 agtiapi_GetWWNMappings()
5206 Get the mappings from target IDs to WWNs, if any.
5207 Store them in the WWN_list array, indexed by target ID.
5208 Leave the devListIndex field blank; this will be filled-in later.
5210 ag_card_t *pCard (IN) Pointer to HBA data structure
5211 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5213 Note: The boot command line parameters are used to load the
5214 mapping information, which is contained in the system
5216 ******************************************************************************/
5217 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5218 ag_mapping_t *pMapList )
5222 ag_tgt_map_t *pWWNList;
5223 ag_slr_map_t *pSLRList;
5224 ag_device_t *pDevList;
5227 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5229 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5231 pWWNList = pCard->pWWNList;
5232 pSLRList = pCard->pSLRList;
5233 pDevList = pCard->pDevList;
5234 pCard->numTgtHardMapped = 0;
5235 devDisc = pCard->devDiscover;
5237 pWWNList[devDisc-1].devListIndex = maxTargets;
5238 pSLRList[devDisc-1].localeNameLen = -2;
5239 pSLRList[devDisc-1].remoteNameLen = -2;
5240 pDevList[devDisc-1].targetId = maxTargets;
5243 * Get the mappings from holding area which contains
5244 * the input of the system file and store them
5245 * in the WWN_list array, indexed by target ID.
5247 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5248 pWWNList[lIdx].flags = 0;
5249 pWWNList[lIdx].devListIndex = maxTargets;
5250 pSLRList[lIdx].localeNameLen = -1;
5251 pSLRList[lIdx].remoteNameLen = -1;
5254 // this is where we would propagate values fed to pMapList
5256 } /* agtiapi_GetWWNMappings */
5261 /******************************************************************************
5262 agtiapi_FindWWNListNext()
5264 finds first available new (unused) wwn list entry
5267 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5268 int lstMax Number of entries in WWNList
5270 index into WWNList indicating available entry space;
5271 if available entry space is not found, return negative value
5272 ******************************************************************************/
5273 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5277 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5279 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5280 pWWNList[lLstIdx].targetLen == 0 )
5282 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5284 pWWNList[lLstIdx].devListIndex,
5285 pWWNList[lLstIdx].targetLen,
5286 pWWNList[lLstIdx].portId,
5295 /******************************************************************************
5296 agtiapi_GetDevHandle()
5299 Get device handle. Handles will be placed in the
5300 devlist array with same order as TargetList provided and
5301 will be mapped to a scsi target id and registered to OS later.
5303 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5304 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5305 U32 eType (IN) Port event
5306 U32 eStatus (IN) Port event status
5308 Number of device handle slot present
5310 The sequence of device handle will match the sequence of taregt list
5311 ******************************************************************************/
5312 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5313 ag_portal_info_t *pPortalInfo,
5317 ag_device_t *pDevice;
5318 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5319 tiDeviceHandle_t **agDev;
5320 int devIdx, szdv, devTotal, cmpsetRtn;
5321 int lDevIndex = 0, lRunScanFlag = FALSE;
5323 tiPortInfo_t portInfT;
5324 ag_device_t lTmpDevice;
5325 ag_tgt_map_t *pWWNList;
5326 ag_slr_map_t *pSLRList;
5331 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5332 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5333 pCard->devDiscover, pCard->tgtCount );
5334 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5335 AGTIAPI_INIT_DELAY( 1000 );
5337 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5338 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5341 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5345 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5346 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5347 if (lDevFlags == NULL)
5349 free((caddr_t)agDev, M_PMC_MDEV);
5350 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5354 pWWNList = pCard->pWWNList;
5355 pSLRList = pCard->pSLRList;
5357 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5358 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5360 // get device handles
5361 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5362 &pPortalInfo->tiPortalContext,
5363 (tiDeviceHandle_t **)agDev,
5364 pCard->devDiscover );
5366 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5367 "status %u card %p pCard->devDiscover %d devTotal %d "
5368 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5369 "AGTIAPI_INIT_TIME %x\n",
5370 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5371 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5372 pPortalInfo->devPrev,
5373 pCard->flags & AGTIAPI_INIT_TIME );
5375 // reset devTotal from any previous runs of this
5376 pPortalInfo->devPrev = devTotal;
5377 pPortalInfo->devTotal = devTotal;
5379 AG_LIST_LOCK( &pCard->devListLock );
5381 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5382 &pPortalInfo->tiPortalContext,
5386 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5390 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5391 if (szdv > pCard->devDiscover)
5393 szdv = pCard->devDiscover;
5396 // reconstructing dev list via comparison of wwn
5398 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5400 if ( agDev[devIdx] != 0 )
5402 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5403 // devIdx, agDev[devIdx] );
5405 // pack temp device structure for tiINIGetDeviceInfo call
5406 pDevice = &lTmpDevice;
5407 pDevice->devType = DIRECT_DEVICE;
5408 pDevice->pCard = (void *)pCard;
5409 pDevice->flags = ACTIVE;
5410 pDevice->pPortalInfo = pPortalInfo;
5411 pDevice->pDevHandle = agDev[devIdx];
5412 pDevice->qbusy = agFALSE;
5414 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5415 // devIdx, pCard->devDiscover, agDev[devIdx] );
5417 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5418 &pDevice->devInfo );
5420 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5421 // sizeof(pDevice->targetName),
5422 // pDevice->devInfo.osAddress1,
5423 // pDevice->devInfo.osAddress2 );
5426 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5428 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5430 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5431 pDevice->targetLen > 0 &&
5432 portInfT.localNameLen > 0 &&
5433 portInfT.remoteNameLen > 0 &&
5434 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5435 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5436 ( portInfT.localNameLen ==
5437 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5438 ( portInfT.remoteNameLen ==
5439 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5440 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5441 pDevice->targetLen ) == 0 &&
5442 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5444 portInfT.localNameLen ) == 0 &&
5445 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5446 portInfT.remoteName,
5447 portInfT.remoteNameLen ) == 0 )
5449 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5450 lDevIndex, devIdx, pPortalInfo->portID );
5452 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5453 ( pPortalInfo->pDevList[lDevIndex] ==
5454 &pCard->pDevList[lDevIndex] ) ) // active
5457 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5458 lDevIndex, devTotal, pPortalInfo->portID );
5459 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5460 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5461 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5462 if ( lReadRm ) // cleared timeout, now remove count for timer
5464 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5466 lDevIndex, pPortalInfo->portID );
5467 atomic_subtract_16( &pCard->rmChkCt, 1 );
5468 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5471 callout_stop( &pCard->devRmTimer );
5477 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5478 lDevIndex, // reactivate now
5479 devTotal, pPortalInfo->portID );
5481 // pDevice going fresh
5482 lRunScanFlag = TRUE; // scan and clear outstanding removals
5484 // pCard->tgtCount++; ##
5485 pDevice->targetId = lDevIndex;
5486 pDevice->portalId = pPortalInfo->portID;
5488 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5489 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5490 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5492 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5493 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5494 AG_LIST_UNLOCK( &pCard->devListLock );
5495 free((caddr_t)lDevFlags, M_PMC_MFLG);
5496 free((caddr_t)agDev, M_PMC_MDEV);
5499 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5500 if ( 0 == lDevFlags[devIdx] )
5502 pPortalInfo->devTotal++;
5503 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5504 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5508 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5509 "status inspect %d %d %d\n",
5510 lDevFlags[devIdx], devIdx, lDevIndex );
5511 pPortalInfo->devTotal++;
5512 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5513 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5519 // end: match this wwn with previous wwn list
5521 // we have an agDev entry, but no pWWNList target for it
5522 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5523 { // flag dev handle not accounted for yet
5524 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5525 // later, get an empty pDevice and map this agDev.
5526 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5527 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5532 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5536 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5537 // "devLstIdx/flags/(WWNL)portId ... \n" );
5538 // review device list for further action needed
5539 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5541 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5543 int lNextDyad; // find next available dyad entry
5545 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5546 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5547 lRunScanFlag = TRUE; // scan and clear outstanding removals
5548 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5550 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5551 pSLRList[lNextDyad].remoteNameLen < 0 )
5555 if ( lNextDyad == pCard->devDiscover )
5557 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5558 AG_LIST_UNLOCK( &pCard->devListLock );
5559 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5560 free( (caddr_t)agDev, M_PMC_MDEV );
5563 // index of new entry
5564 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5565 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5566 lDevIndex, devTotal, pPortalInfo->portID );
5567 if ( 0 > lDevIndex )
5569 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5573 pDevice = &pCard->pDevList[lDevIndex];
5575 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5577 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5579 pDevice->pCard = (void *)pCard;
5580 pDevice->devType = DIRECT_DEVICE;
5582 // begin to populate new WWNList entry
5583 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5584 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5586 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5587 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5588 pWWNList[lDevIndex].devListIndex = lDevIndex;
5589 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5591 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5592 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5593 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5594 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5595 // end of populating new WWNList entry
5597 pDevice->targetId = lDevIndex;
5599 pDevice->flags = ACTIVE;
5600 pDevice->CCBCount = 0;
5601 pDevice->pDevHandle = agDev[devIdx];
5602 agDev[devIdx]->osData = (void*)pDevice;
5604 pDevice->pPortalInfo = pPortalInfo;
5605 pDevice->portalId = pPortalInfo->portID;
5606 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5607 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5610 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5611 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5613 pDevice = &pCard->pDevList[devIdx];
5614 //pDevice->flags &= ~ACTIVE;
5615 if ( ( pDevice->pDevHandle != NULL ||
5616 pPortalInfo->pDevList[devIdx] != NULL ) )
5618 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5620 if (FALSE == lRunScanFlag)
5623 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5624 devIdx, devTotal, pPortalInfo->portID );
5625 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5626 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5627 if ( 0 == cmpsetRtn )
5629 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5634 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5637 // else ... scan coming soon enough anyway, ignore timer for dropout
5640 } // end of for ( devIdx = 0; ...
5642 AG_LIST_UNLOCK( &pCard->devListLock );
5644 free((caddr_t)lDevFlags, M_PMC_MFLG);
5645 free((caddr_t)agDev, M_PMC_MDEV);
5647 if ( TRUE == lRunScanFlag )
5648 agtiapi_clrRmScan( pCard );
5651 } // end agtiapi_GetDevHandle
5653 /******************************************************************************
5659 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5662 ******************************************************************************/
5663 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5666 int bus, tid, lun, card_no;
5669 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5671 bus = cam_sim_path(pmcsc->sim);
5673 tid = CAM_TARGET_WILDCARD;
5674 lun = CAM_LUN_WILDCARD;
5676 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5677 ccb = xpt_alloc_ccb_nowait();
5680 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5683 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5684 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5686 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5691 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5692 pmcsc->dev_scan = agTRUE;
5697 /******************************************************************************
5698 agtiapi_DeQueueCCB()
5701 Remove a ccb from a queue
5703 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5704 pccb_t *phead (IN) Pointer to a head of ccb queue
5705 ccb_t *pccd (IN) Pointer to the ccb to be processed
5707 AGTIAPI_SUCCESS - the ccb is removed from queue
5708 AGTIAPI_FAIL - the ccb is not found from queue
5710 ******************************************************************************/
5712 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5713 #ifdef AGTIAPI_LOCAL_LOCK
5719 U32 status = AGTIAPI_FAIL;
5721 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5723 if (pccb == NULL || *phead == NULL)
5725 return AGTIAPI_FAIL;
5728 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5729 AG_LOCAL_LOCK(lock);
5733 *phead = (*phead)->pccbNext;
5739 pccb->pccbNext = NULL;
5740 status = AGTIAPI_SUCCESS;
5745 while (pccb_curr->pccbNext != NULL)
5747 if (pccb_curr->pccbNext == pccb)
5749 pccb_curr->pccbNext = pccb->pccbNext;
5750 pccb->pccbNext = NULL;
5756 pccb->pccbNext = NULL;
5757 status = AGTIAPI_SUCCESS;
5760 pccb_curr = pccb_curr->pccbNext;
5763 AG_LOCAL_UNLOCK(lock);
5769 STATIC void wwnprintk( unsigned char *name, int len )
5773 for (i = 0; i < len; i++, name++)
5774 AGTIAPI_PRINTK("%02x", *name);
5775 AGTIAPI_PRINTK("\n");
5778 * SAS and SATA behind expander has 8 byte long unique address.
5779 * However, direct connect SATA device use 512 byte unique device id.
5780 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5781 * address of memory that holding ID.
5783 STATIC int wwncpy( ag_device_t *pDevice )
5787 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5788 pDevice->devInfo.osAddress2)
5790 memcpy(pDevice->targetName,
5791 pDevice->devInfo.remoteName,
5792 pDevice->devInfo.osAddress1);
5793 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5794 pDevice->devInfo.remoteAddress,
5795 pDevice->devInfo.osAddress2);
5796 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5797 pDevice->devInfo.osAddress2;
5798 rc = pDevice->targetLen;
5802 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5803 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5810 /******************************************************************************
5811 agtiapi_ReleaseCCBs()
5814 Free all allocated CCB memories for the Host Adapter.
5816 struct agtiapi_softc *pCard (IN) Pointer to HBA data stucture
5819 ******************************************************************************/
5820 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5827 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5829 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5833 #ifdef AGTIAPI_TEST_DPL
5834 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5835 pccb = pccb->pccbChainNext)
5837 if(pccb->dplPtr && pccb->dplDma)
5838 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5842 #ifdef AGTIAPI_TEST_EPL
5843 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5844 pccb = pccb->pccbChainNext)
5846 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5848 pCard->epl_ctx_pool,
5855 while ((hdr = pCard->ccbAllocList) != NULL)
5857 pCard->ccbAllocList = hdr->next;
5858 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5859 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5860 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5862 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5864 free(hdr, M_PMC_MCCB);
5866 pCard->ccbAllocList = NULL;
5872 /******************************************************************************
5876 Timer tick for tisa common layer
5878 void *data (IN) Pointer to the HBA data structure
5881 ******************************************************************************/
5882 STATIC void agtiapi_TITimer( void *data )
5886 struct agtiapi_softc *pCard;
5888 pCard = (struct agtiapi_softc *)data;
5890 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5891 AG_GLOBAL_ARG( flags );
5893 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5894 loLevelOption.usecsPerTick / USEC_PER_TICK;
5896 if( next_tick == 0 ) /* no timer required */
5898 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5899 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5901 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5903 //add for polling mode
5905 if( agtiapi_polling_mode )
5906 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5908 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5910 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5914 /******************************************************************************
5918 Clears device list entries scheduled for timeout and calls scan
5920 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5921 ******************************************************************************/
5922 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5924 ag_tgt_map_t *pWWNList;
5925 ag_portal_info_t *pPortalInfo;
5926 ag_portal_data_t *pPortalData;
5931 pWWNList = pCard->pWWNList;
5933 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5935 AG_LIST_LOCK( &pCard->devListLock );
5937 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5939 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5942 break; // trim to who cares
5945 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5948 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5949 pCard->pDevList[lIdx].pDevHandle = NULL;
5951 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5952 pPortalInfo = &pPortalData->portalInfo;
5953 pPortalInfo->pDevList[lIdx] = NULL;
5954 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5955 lIdx, pWWNList[lIdx].portId );
5956 atomic_subtract_16( &pCard->rmChkCt, 1 );
5959 AG_LIST_UNLOCK( &pCard->devListLock );
5961 agtiapi_scan( pCard );
5965 /******************************************************************************
5966 agtiapi_devRmCheck()
5969 Timer tick to check for timeout on missing targets
5970 Removes device list entry when timeout is reached
5972 void *data (IN) Pointer to the HBA data structure
5973 ******************************************************************************/
5974 STATIC void agtiapi_devRmCheck( void *data )
5976 struct agtiapi_softc *pCard;
5977 ag_tgt_map_t *pWWNList;
5978 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
5982 pCard = ( struct agtiapi_softc * )data;
5985 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
5989 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
5993 callout_deactivate( &pCard->devRmTimer );
5995 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5997 return; // implicit timer clear
6000 pWWNList = pCard->pWWNList;
6002 AG_LIST_LOCK( &pCard->devListLock );
6003 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6006 if ( callout_pending(&pCard->devRmTimer) == FALSE )
6008 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
6012 AG_LIST_UNLOCK( &pCard->devListLock );
6016 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
6018 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6021 break; // if handled somewhere else, get out
6024 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6027 if ( 1 == lReadRm ) // timed out
6028 { // no decrement of devRemoved as way to leave a clrRmScan marker
6029 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6030 break; // ... so bail out
6034 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6035 lIdx, lReadRm, lReadCt );
6036 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6039 if ( 0 == cmpsetRtn )
6041 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6047 AG_LIST_UNLOCK( &pCard->devListLock );
6049 if ( TRUE == lRunScanFlag )
6050 agtiapi_clrRmScan( pCard );
6054 AG_LIST_UNLOCK( &pCard->devListLock );
6061 static void agtiapi_cam_poll( struct cam_sim *asim )
6066 /*****************************************************************************
6070 Hard or soft reset on the controller and resend any
6071 outstanding requests if needed.
6073 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6074 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6076 AGTIAPI_SUCCESS - reset successful
6077 AGTIAPI_FAIL - reset failed
6079 *****************************************************************************/
6080 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6082 ag_device_t *pDevice;
6086 ag_portal_info_t *pPortalInfo;
6087 ag_portal_data_t *pPortalData;
6091 if( pCard->flags & AGTIAPI_RESET ) {
6092 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6093 return AGTIAPI_FAIL;
6096 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6097 pCard->resetCount );
6099 agtiapi_LogEvent( pCard,
6100 IOCTL_EVT_SEV_INFORMATIONAL,
6104 "Reset initiator time = %d!",
6105 pCard->resetCount + 1 );
6108 pCard->flags |= AGTIAPI_RESET;
6109 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6110 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6111 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6113 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6115 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6117 if( pCard->flags & AGTIAPI_SOFT_RESET )
6119 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6120 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6124 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6127 lFlagVal = AGTIAPI_RESET_SUCCESS;
6128 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6129 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6130 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6132 if( ret == AGTIAPI_FAIL )
6134 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6144 if ( AGTIAPI_FAIL == ret )
6146 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6151 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6155 if( AGTIAPI_FAIL == ret )
6157 printf( "agtiapi_ResetCard: reset ERROR\n" );
6158 pCard->flags &= ~AGTIAPI_INSTALLED;
6159 return AGTIAPI_FAIL;
6162 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6164 // disable all devices
6165 pDevice = pCard->pDevList;
6166 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6168 /* if ( pDevice->flags & ACTIVE )
6170 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6172 pDevice->flags &= ~ACTIVE;
6175 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6176 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6177 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6179 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6181 if( !pCard->pDevList ) { // try to get a little sanity here
6182 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6184 return AGTIAPI_FAIL;
6187 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6188 pCard->tgtCount, pCard->portCount );
6189 pCard->tgtCount = 0;
6193 pCard->flags &= ~AGTIAPI_CB_DONE;
6195 pPortalData = pCard->pPortalData;
6197 for( count = 0; count < pCard->portCount; count++ ) {
6198 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6199 pPortalInfo = &pPortalData->portalInfo;
6200 pPortalInfo->portStatus = 0;
6201 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6202 AGTIAPI_PORT_DISC_READY |
6204 AGTIAPI_DISC_COMPLETE );
6207 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6208 if (szdv > pCard->devDiscover)
6210 szdv = pCard->devDiscover;
6213 for( lIdx = 0, loop = 0;
6214 lIdx < szdv && loop < pPortalInfo->devTotal;
6217 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6221 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6222 // don't erase more as the device is scheduled for removal on DPC
6224 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6225 pDevice, pPortalInfo->pDevList, lIdx );
6226 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6229 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6230 { // we reconstruct dev list later in get dev handle
6231 pPortalInfo->pDevList[lIdx] = NULL;
6234 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6236 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6239 pPortalInfo->portID,
6240 &pPortalInfo->tiPortalContext );
6242 if( tiCOMPortStart( &pCard->tiRoot,
6243 pPortalInfo->portID,
6244 &pPortalInfo->tiPortalContext,
6248 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6249 pPortalInfo->portID );
6253 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6254 pPortalInfo->portID );
6258 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6259 tiCOMGetPortInfo( &pCard->tiRoot,
6260 &pPortalInfo->tiPortalContext,
6261 &pPortalInfo->tiPortInfo );
6264 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6267 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6269 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6271 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6272 "!AGTIAPI_INSTALLED \n" );
6273 return AGTIAPI_FAIL;
6276 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6279 agtiapi_LogEvent( pCard,
6280 IOCTL_EVT_SEV_INFORMATIONAL,
6284 "Reset initiator total device = %d!",
6287 pCard->resetCount++;
6289 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6290 // clear send & done queue
6291 AG_LOCAL_LOCK( &pCard->sendLock );
6292 pCard->ccbSendHead = NULL;
6293 pCard->ccbSendTail = NULL;
6294 AG_LOCAL_UNLOCK( &pCard->sendLock );
6296 AG_LOCAL_LOCK( &pCard->doneLock );
6297 pCard->ccbDoneHead = NULL;
6298 pCard->ccbDoneTail = NULL;
6299 AG_LOCAL_UNLOCK( &pCard->doneLock );
6301 // clear smp queues also
6302 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6303 pCard->smpSendHead = NULL;
6304 pCard->smpSendTail = NULL;
6305 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6307 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6308 pCard->smpDoneHead = NULL;
6309 pCard->smpDoneTail = NULL;
6310 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6312 // finished with all reset stuff, now start things back up
6313 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6314 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6315 pCard->flags |= AGTIAPI_HAD_RESET;
6316 pCard->flags &= ~AGTIAPI_RESET; // ##
6317 agtiapi_StartIO( pCard );
6318 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6319 return AGTIAPI_SUCCESS;
6320 } // agtiapi_ResetCard
6323 /******************************************************************************
6324 agtiapi_ReleaseHBA()
6327 Releases all resources previously acquired to support
6328 a specific Host Adapter, including the I/O Address range,
6329 and unregisters the agtiapi Host Adapter.
6331 device_t dev (IN) - device pointer
6333 always return 0 - success
6335 ******************************************************************************/
6336 int agtiapi_ReleaseHBA( device_t dev )
6339 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6341 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6342 struct ccb_setasync csa;
6343 struct agtiapi_softc *pCard;
6344 pCard = device_get_softc( dev );
6345 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6346 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6348 AG_GLOBAL_ARG(flags);
6350 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6352 if (thisCardInst != pCardInfo)
6354 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6358 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6366 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6367 pCard->flags |= AGTIAPI_SHUT_DOWN;
6371 if (pCard->flags & AGTIAPI_TIMER_ON)
6373 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6374 callout_drain( &pCard->OS_timer );
6375 callout_drain( &pCard->devRmTimer );
6376 callout_drain(&pCard->IO_timer);
6377 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6378 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6381 #ifdef HIALEAH_ENCRYPTION
6382 //Release encryption table memory - Fix it
6383 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6384 //agtiapi_CleanupEncryption(pCard);
6388 * Shutdown the channel so that chip gets frozen
6389 * and it does not do any more pci-bus accesses.
6391 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6393 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6394 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6395 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6397 if (pCard->flags & AGTIAPI_INSTALLED)
6399 tiCOMShutDown( &pCard->tiRoot );
6400 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6404 * first release IRQ, so that we do not get any more interrupts
6407 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6409 if (!agtiapi_intx_mode)
6412 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6414 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6416 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6417 bus_release_resource( dev,
6423 pci_release_msi(dev);
6425 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6430 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6431 tasklet_kill(&pCard->tasklet_dpc[i]);
6433 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6436 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6437 if( pCard->osti_busaddr != 0 ) {
6438 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6440 if( pCard->osti_mem != NULL ) {
6441 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6443 if( pCard->osti_dmat != NULL ) {
6444 bus_dma_tag_destroy( pCard->osti_dmat );
6447 /* unmap the mapped PCI memory */
6448 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6449 agtiapi_ReleasePCIMem(thisCardInst);
6451 /* release all ccbs */
6452 if (pCard->ccbTotal)
6454 //calls bus_dmamap_destroy() for all pccbs
6455 agtiapi_ReleaseCCBs(pCard);
6456 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6459 #ifdef HIALEAH_ENCRYPTION
6460 /*release encryption resources - Fix it*/
6463 /*Check that all IO's are completed */
6464 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6466 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6468 //agtiapi_CleanupEncryptionPools(pCard);
6473 /* release device list */
6474 if( pCard->pDevList ) {
6475 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6476 pCard->pDevList = NULL;
6477 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6479 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6480 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6481 if( pCard->pWWNList ) {
6482 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6483 pCard->pWWNList = NULL;
6484 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6486 if( pCard->pSLRList ) {
6487 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6488 pCard->pSLRList = NULL;
6489 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6493 if (pCard->pPortalData)
6495 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6496 pCard->pPortalData = NULL;
6497 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6499 //calls contigfree() or free()
6500 agtiapi_MemFree(pCardInfo);
6501 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6503 #ifdef HOTPLUG_SUPPORT
6504 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6506 // agtiapi_FreeDevWorkList(pCard);
6507 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6512 * TBD, scsi_unregister may release wrong host data structure
6513 * which cause NULL pointer shows up.
6515 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6517 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6520 #ifdef AGTIAPI_LOCAL_LOCK
6525 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6527 for( i = 0; i < maxLocks; i++ )
6529 mtx_destroy(&pCard->STLock[i]);
6531 free(pCard->STLock, M_PMC_MSTL);
6532 pCard->STLock = NULL;
6539 /* reset agtiapi_1st_time if this is the only card */
6540 if (!ag_card_good && !agtiapi_1st_time)
6542 agtiapi_1st_time = 1;
6545 /* for tiSgl_t memeory */
6546 if (pCard->tisgl_busaddr != 0)
6548 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6550 if (pCard->tisgl_mem != NULL)
6552 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6554 if (pCard->tisgl_dmat != NULL)
6556 bus_dma_tag_destroy(pCard->tisgl_dmat);
6559 if (pCard->buffer_dmat != agNULL)
6561 bus_dma_tag_destroy(pCard->buffer_dmat);
6564 if (pCard->sim != NULL)
6566 mtx_lock(&thisCardInst->pmIOLock);
6567 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6568 csa.ccb_h.func_code = XPT_SASYNC_CB;
6569 csa.event_enable = 0;
6570 csa.callback = agtiapi_async;
6571 csa.callback_arg = pCard;
6572 xpt_action((union ccb *)&csa);
6573 xpt_free_path(pCard->path);
6574 // if (pCard->ccbTotal == 0)
6575 if (pCard->ccbTotal <= thisCard)
6578 no link up so that simq has not been released.
6579 In order to remove cam, we call this.
6581 xpt_release_simq(pCard->sim, 1);
6583 xpt_bus_deregister(cam_sim_path(pCard->sim));
6584 cam_sim_free(pCard->sim, FALSE);
6585 mtx_unlock(&thisCardInst->pmIOLock);
6587 if (pCard->devq != NULL)
6589 cam_simq_free(pCard->devq);
6593 mtx_destroy( &thisCardInst->pmIOLock );
6594 mtx_destroy( &pCard->sendLock );
6595 mtx_destroy( &pCard->doneLock );
6596 mtx_destroy( &pCard->sendSMPLock );
6597 mtx_destroy( &pCard->doneSMPLock );
6598 mtx_destroy( &pCard->ccbLock );
6599 mtx_destroy( &pCard->devListLock );
6600 mtx_destroy( &pCard->OS_timer_lock );
6601 mtx_destroy( &pCard->devRmTimerLock );
6602 mtx_destroy( &pCard->memLock );
6603 mtx_destroy( &pCard->freezeLock );
6605 destroy_dev( pCard->my_cdev );
6606 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6611 // Called during system shutdown after sync
6612 static int agtiapi_shutdown( device_t dev )
6614 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6618 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6620 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6624 static int agtiapi_resume( device_t dev ) // Device resume routine.
6626 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6630 static device_method_t agtiapi_methods[] = { // Device interface
6631 DEVMETHOD( device_probe, agtiapi_probe ),
6632 DEVMETHOD( device_attach, agtiapi_attach ),
6633 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6634 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6635 DEVMETHOD( device_suspend, agtiapi_suspend ),
6636 DEVMETHOD( device_resume, agtiapi_resume ),
6640 static devclass_t pmspcv_devclass;
6642 static driver_t pmspcv_driver = {
6645 sizeof( struct agtiapi_softc )
6648 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6649 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6650 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6652 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6653 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6654 #include <dev/pms/freebsd/driver/common/lxutil.c>
6655 #include <dev/pms/freebsd/driver/common/lxencrypt.c>