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 unsigned char cardMap[AGTIAPI_MAX_CARDS] = { 0, 0, 0, 0 };
218 static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list
219 static void agtiapi_cam_action( struct cam_sim *, union ccb * );
220 static void agtiapi_cam_poll( struct cam_sim * );
222 // Function prototypes
223 static d_open_t agtiapi_open;
224 static d_close_t agtiapi_close;
225 static d_read_t agtiapi_read;
226 static d_write_t agtiapi_write;
227 static d_ioctl_t agtiapi_CharIoctl;
228 static void agtiapi_async(void *callback_arg, u_int32_t code,
229 struct cam_path *path, void *arg);
230 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth);
232 // Character device entry points
233 static struct cdevsw agtiapi_cdevsw = {
234 .d_version = D_VERSION,
235 .d_open = agtiapi_open,
236 .d_close = agtiapi_close,
237 .d_read = agtiapi_read,
238 .d_write = agtiapi_write,
239 .d_ioctl = agtiapi_CharIoctl,
244 U32 ag_portal_count = 0;
246 // In the cdevsw routines, we find our softc by using the si_drv1 member
247 // of struct cdev. We set this variable to point to our softc in our
248 // attach routine when we create the /dev entry.
250 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
252 struct agtiapi_softc *sc;
253 /* Look up our softc. */
255 AGTIAPI_PRINTK("agtiapi_open\n");
256 AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
260 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
262 struct agtiapi_softc *sc;
265 AGTIAPI_PRINTK("agtiapi_close\n");
266 AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
270 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
272 struct agtiapi_softc *sc;
275 AGTIAPI_PRINTK( "agtiapi_read\n" );
276 AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n",
277 uio->uio_resid, sc->my_dev );
281 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
283 struct agtiapi_softc *sc;
286 AGTIAPI_PRINTK( "agtiapi_write\n" );
287 AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n",
288 uio->uio_resid, sc->my_dev );
292 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
293 tiIOCTLPayload_t *agIOCTLPayload )
295 tdDeviceListPayload_t *pIoctlPayload =
296 (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea;
297 tdDeviceInfoIOCTL_t *pDeviceInfo = NULL;
298 bit8 *pDeviceInfoOrg;
299 tdsaDeviceData_t *pDeviceData = NULL;
300 tiDeviceHandle_t **devList = NULL;
301 tiDeviceHandle_t **devHandleArray = NULL;
302 tiDeviceHandle_t *pDeviceHandle = NULL;
305 bit32 MaxDeviceCount;
306 bit32 ret_val=IOCTL_CALL_INVALID_CODE;
307 ag_portal_data_t *pPortalData;
308 bit8 *pDeviceHandleList = NULL;
309 AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" );
311 pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
312 MaxDeviceCount = pCard->devDiscover;
313 if (MaxDeviceCount > pIoctlPayload->deviceLength )
315 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
316 MaxDeviceCount = pIoctlPayload->deviceLength;
317 ret_val = IOCTL_CALL_FAIL;
319 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
320 memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
322 AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
323 devList = malloc(memNeeded1, TEMP2, M_WAITOK);
326 AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
327 ret_val = IOCTL_CALL_FAIL;
328 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
331 osti_memset(devList, 0, memNeeded1);
332 pPortalData = &pCard->pPortalData[0];
333 pDeviceHandleList = (bit8*)devList;
334 for (total = x = 0; x < pCard->portCount; x++, pPortalData++)
336 count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
337 &pPortalData->portalInfo.tiPortalContext,
338 ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
339 if (count == DISCOVERY_IN_PROGRESS)
341 AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
343 free(devList, TEMP2);
344 ret_val = IOCTL_CALL_FAIL;
345 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
349 pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
350 MaxDeviceCount-= count;
352 if (total > pIoctlPayload->deviceLength)
354 total = pIoctlPayload->deviceLength;
356 // dump device information from device handle list
359 devHandleArray = devList;
360 for (x = 0; x < pCard->devDiscover; x++)
362 pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
363 if (devList[x] != agNULL)
365 pDeviceData = devList [x]->tdData;
367 pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
368 if (pDeviceData != agNULL && pDeviceInfo != agNULL)
370 osti_memcpy( &pDeviceInfo->sasAddressHi,
371 pDeviceData->agDeviceInfo.sasAddressHi,
373 osti_memcpy( &pDeviceInfo->sasAddressLo,
374 pDeviceData->agDeviceInfo.sasAddressLo,
377 pDeviceInfo->sasAddressHi =
378 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
379 pDeviceInfo->sasAddressLo =
380 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
383 pDeviceInfo->deviceType =
384 ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4;
385 pDeviceInfo->linkRate =
386 pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F;
387 pDeviceInfo->phyId = pDeviceData->phyID;
388 pDeviceInfo->ishost = pDeviceData->target_ssp_stp_smp;
389 pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle;
390 if(pDeviceInfo->deviceType == 0x02)
394 tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo);
395 pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi);
396 pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16;
400 pDeviceInfo->sasAddressHi =
401 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
402 pDeviceInfo->sasAddressLo =
403 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
406 AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n",
407 pDeviceInfo->deviceType );
408 AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n",
409 pDeviceInfo->linkRate );
410 AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n",
411 pDeviceInfo->phyId );
412 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n",
413 pDeviceInfo->sasAddressHi );
414 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n",
415 pDeviceInfo->sasAddressHi );
419 AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
420 "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
425 pIoctlPayload->realDeviceCount = count;
426 AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
429 free(devList, TEMP2);
431 if(ret_val != IOCTL_CALL_FAIL)
433 ret_val = IOCTL_CALL_SUCCESS;
435 agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
439 /******************************************************************************
440 agtiapi_getCardInfo()
443 This function retrives the Card information
448 0 - HBA has been detected
450 ******************************************************************************/
451 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
455 CardInfo_t *pCardInfo;
457 pCardInfo = (CardInfo_t *)buffer;
459 pCardInfo->deviceId = pci_get_device(pCard->my_dev);
460 pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ;
461 memcpy( pCardInfo->pciMemBaseSpc,
462 pCard->pCardInfo->pciMemBaseSpc,
463 ((sizeof(U32_64))*PCI_NUMBER_BARS) );
464 pCardInfo->deviceNum = pci_get_slot(pCard->my_dev);
465 pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase;
466 pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow;
467 pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp;
468 pCardInfo->busNum =pci_get_bus(pCard->my_dev);
472 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
474 struct ccb_relsim crs;
475 xpt_setup_ccb(&crs.ccb_h, path, 5);
476 crs.ccb_h.func_code = XPT_REL_SIMQ;
477 crs.ccb_h.flags = CAM_DEV_QFREEZE;
478 crs.release_flags = RELSIM_ADJUST_OPENINGS;
479 crs.openings = QueueDepth;
480 xpt_action((union ccb *)&crs);
481 if(crs.ccb_h.status != CAM_REQ_CMP) {
482 printf("XPT_REL_SIMQ failed\n");
486 agtiapi_async(void *callback_arg, u_int32_t code,
487 struct cam_path *path, void *arg)
489 struct agtiapi_softc *pmsc;
492 pmsc = (struct agtiapi_softc*)callback_arg;
494 case AC_FOUND_DEVICE:
496 struct ccb_getdev *cgd;
497 cgd = (struct ccb_getdev *)arg;
501 TID = cgd->ccb_h.target_id;
502 if (TID >= 0 && TID < maxTargets){
504 TID = INDEX(pmsc, TID);
505 targ = &pmsc->pDevList[TID];
506 agtiapi_adjust_queue_depth(path, targ->qdepth);
515 /******************************************************************************
519 This function handles the ioctl from application layer
524 0 - HBA has been detected
526 ******************************************************************************/
527 static int agtiapi_CharIoctl( struct cdev *dev,
534 datatosend *load; // structure defined in lxcommon.h
535 tiIOCTLPayload_t *pIoctlPayload;
536 struct agtiapi_softc *pCard;
545 tdDeviceListPayload_t *pDeviceList = NULL;
551 load=(datatosend*)data;
552 pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK);
553 AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize );
554 //Copy payload to kernel buffer, on success it returns 0
555 err = copyin(load->data,pIoctlPayload,load->datasize);
558 status = IOCTL_CALL_FAIL;
561 sema_init(&mx,0,"sem");
562 pCard->pIoctlSem =&mx;
563 pCard->up_count = pCard->down_count = 0;
564 if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST )
566 retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
569 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
570 status = IOCTL_CALL_SUCCESS;
574 pIoctlPayload->Status = IOCTL_CALL_FAIL;
575 status = IOCTL_CALL_FAIL;
577 //update new device length
578 pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea;
579 load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount);
580 AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize );
583 else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
585 retValue = agtiapi_getCardInfo( pCard,
586 pIoctlPayload->Length,
587 (pIoctlPayload->FunctionSpecificArea) );
590 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
591 status = IOCTL_CALL_SUCCESS;
595 pIoctlPayload->Status = IOCTL_CALL_FAIL;
596 status = IOCTL_CALL_FAIL;
599 else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
601 if ( pCard->flags & AGTIAPI_PORT_PANIC )
603 strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
607 strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
609 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
610 status = IOCTL_CALL_SUCCESS;
612 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
614 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo);
615 //read port status to see if there is a fatal event
616 if(pCard->flags & AGTIAPI_PORT_PANIC)
618 printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo);
619 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE;
623 AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo);
624 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE;
626 status = IOCTL_CALL_SUCCESS;
628 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
630 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo);
631 //set flags bit status to be a soft reset
632 pCard->flags |= AGTIAPI_SOFT_RESET;
633 //trigger soft reset for the card
634 retValue = agtiapi_ResetCard (pCard, &flags);
636 if(retValue == AGTIAPI_SUCCESS)
638 //clear port panic status
639 pCard->flags &= ~AGTIAPI_PORT_PANIC;
640 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG;
641 status = IOCTL_CALL_SUCCESS;
645 pIoctlPayload->Status = IOCTL_CALL_FAIL;
646 status = IOCTL_CALL_FAIL;
651 status = tiCOMMgntIOCTL( &pCard->tiRoot,
656 if (status == IOCTL_CALL_PENDING)
658 ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
659 status = IOCTL_CALL_SUCCESS;
662 pCard->pIoctlSem = NULL;
665 //copy kernel buffer to userland buffer
666 err=copyout(pIoctlPayload,load->data,load->datasize);
669 status = IOCTL_CALL_FAIL;
672 free(pIoctlPayload,TEMP);
682 /******************************************************************************
686 This function initialize and registere all detected HBAs.
687 The first function being called in driver after agtiapi_probe()
689 device_t dev (IN) - device pointer
692 0 - HBA has been detected
694 ******************************************************************************/
695 static int agtiapi_probe( device_t dev )
699 if ( pci_get_vendor(dev) == PCI_VENDOR_ID_PMC_SIERRA ||
700 pci_get_vendor(dev) == PCI_VENDOR_ID_HIALEAH )
702 int thisCard = device_get_unit( dev );
703 // AGTIAPI_PRINTK("agtiapi_probe: thisCard %d\n", thisCard);
704 if( thisCard >= AGTIAPI_MAX_CARDS)
706 device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
707 return (ENXIO); // maybe change to different return value?
709 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
710 retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
713 if( retVal == 2 ) return 0; // another thread ran probe on this card
715 "agtiapi_probe: PCI DEVICE NOT SUPPORTED by this driver!!"
716 "Vendor ID : 0x%x Device ID : 0x%x\n",
717 pci_get_vendor(dev), pci_get_device( dev ) );
718 return (ENXIO); // maybe change to different return value?
721 // AGTIAPI_PRINTK( "agtiapi_ProbeCard: returned with pointer values "
723 // thisCardInst->pPCIDev, thisCardInst );
724 cardMap[thisCard] = 11; // record this card is present
725 return( BUS_PROBE_DEFAULT ); // successful probe
732 /******************************************************************************
736 This function initialize and registere all detected HBAs.
737 The first function being called in driver after agtiapi_probe()
739 device_t dev (IN) - device pointer
742 0 - HBA has been detected
744 ******************************************************************************/
745 static int agtiapi_attach( device_t devx )
747 // keeping get_unit call to once
748 int thisCard = device_get_unit( devx );
749 struct agtiapi_softc *pmsc;
750 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
751 ag_resource_info_t *pRscInfo;
754 char buffer [256], *pLastUsedChar;
757 struct ccb_setasync csa;
759 AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard);
760 // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values A %p / %p\n",
761 // thisCardInst->pPCIDev, thisCardInst );
762 AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) );
764 TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS", &ag_timeout_secs );
765 TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel );
766 // printf( "agtiapi_attach: debugLevel %d, timeout %d\n",
767 // gTiDebugLevel, ag_timeout_secs );
768 if ( ag_timeout_secs < 1 )
770 ag_timeout_secs = 1; // set minimum timeout value of 1 second
772 ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
774 // Look up our softc and initialize its fields.
775 pmsc = device_get_softc( devx );
778 /* Get NumberOfPortals */
779 if ((ostiGetTransportParam(
791 ) == tiSuccess) && (lenRecv != 0))
793 if (osti_strncmp(buffer, "0x", 2) == 0)
795 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
799 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
801 if (ag_portal_count > AGTIAPI_MAX_PORTALS)
802 ag_portal_count = AGTIAPI_MAX_PORTALS;
806 ag_portal_count = AGTIAPI_MAX_PORTALS;
808 AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count );
809 // initialize hostdata structure
810 pmsc->flags |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED |
812 pmsc->cardNo = thisCard;
814 pmsc->portCount = ag_portal_count;
815 pmsc->pCardInfo = thisCardInst;
816 pmsc->tiRoot.osData = pmsc;
817 pmsc->pCardInfo->pCard = (void *)pmsc;
818 pmsc->VidDid = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx );
819 pmsc->SimQFrozen = agFALSE;
820 pmsc->devq_flag = agFALSE;
821 pRscInfo = &thisCardInst->tiRscInfo;
823 osti_memset(buffer, 0, 256);
827 if ((ostiGetTransportParam(
839 ) == tiSuccess) && (lenRecv != 0))
841 if (osti_strncmp(buffer, "0x", 2) == 0)
843 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
844 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" );
848 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
849 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" );
856 maxTargets = AGTIAPI_MAX_DEVICE_8H;
857 else if(Is_ADP7H(pmsc))
858 maxTargets = AGTIAPI_MAX_DEVICE_7H;
860 maxTargets = AGTIAPI_MAX_DEVICE;
863 if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
865 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n", maxTargets, AGTIAPI_HW_LIMIT_DEVICE );
866 AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" );
867 maxTargets = AGTIAPI_HW_LIMIT_DEVICE;
869 pmsc->devDiscover = maxTargets ;
871 #ifdef HIALEAH_ENCRYPTION
872 ag_encryption_enable = 1;
873 if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) ==
874 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
877 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
878 printf("agtiapi_attach: Encryption Enabled\n" );
881 // ## for now, skip calls to ostiGetTransportParam(...)
882 // ## for now, skip references to DIF & EDC
884 // Create a /dev entry for this device. The kernel will assign us
885 // a major number automatically. We use the unit number of this
886 // device as the minor number and name the character device
888 pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL,
889 0600, "spcv%u", thisCard );
890 pmsc->my_cdev->si_drv1 = pmsc;
892 mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
893 NULL, MTX_DEF|MTX_RECURSE );
895 struct cam_devq *devq;
897 /* set the maximum number of pending IOs */
898 devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
901 AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
905 struct cam_sim *lsim;
906 lsim = cam_sim_alloc( agtiapi_cam_action,
911 &thisCardInst->pmIOLock,
912 1, // queued per target
913 AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
915 if ( lsim == NULL ) {
916 cam_simq_free( devq );
917 AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
921 pmsc->dev_scan = agFALSE;
922 //one cam sim per scsi bus
923 mtx_lock( &thisCardInst->pmIOLock );
924 if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS )
926 cam_sim_free( lsim, TRUE );
927 mtx_unlock( &thisCardInst->pmIOLock );
928 AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
933 bus = cam_sim_path(pmsc->sim);
934 tid = CAM_TARGET_WILDCARD;
935 lun = CAM_LUN_WILDCARD;
936 ccb = xpt_alloc_ccb_nowait();
939 mtx_unlock( &thisCardInst->pmIOLock );
940 cam_sim_free( lsim, TRUE );
941 cam_simq_free( devq );
944 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
945 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
947 mtx_unlock( &thisCardInst->pmIOLock );
948 cam_sim_free( lsim, TRUE );
949 cam_simq_free( devq );
953 pmsc->path = ccb->ccb_h.path;
954 xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5);
955 csa.ccb_h.func_code = XPT_SASYNC_CB;
956 csa.event_enable = AC_FOUND_DEVICE;
957 csa.callback = agtiapi_async;
958 csa.callback_arg = pmsc;
959 xpt_action((union ccb *)&csa);
960 if (csa.ccb_h.status != CAM_REQ_CMP) {
961 AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" );
964 mtx_unlock( &thisCardInst->pmIOLock );
969 // get TD and lower layer memory requirements
970 tiCOMGetResource( &pmsc->tiRoot,
971 &pRscInfo->tiLoLevelResource,
972 &pRscInfo->tiInitiatorResource,
974 &pRscInfo->tiSharedMem );
976 agtiapi_ScopeDMARes( thisCardInst );
977 AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
978 " 0x%x \n", pmsc->typhn );
980 // initialize card information and get resource ready
981 if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) {
982 AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n",
986 // begin: allocate and initialize card portal info resource
987 ag_portal_data_t *pPortalData;
988 if (pmsc->portCount == 0)
990 pmsc->pPortalData = NULL;
994 pmsc->pPortalData = (ag_portal_data_t *)
995 malloc( sizeof(ag_portal_data_t) * pmsc->portCount,
996 M_PMC_MPRT, M_ZERO | M_WAITOK );
997 if (pmsc->pPortalData == NULL)
999 AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
1003 pPortalData = pmsc->pPortalData;
1004 for( idx = 0; idx < pmsc->portCount; idx++ ) {
1005 pPortalData->pCard = pmsc;
1006 pPortalData->portalInfo.portID = idx;
1007 pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData;
1010 // end: allocate and initialize card portal info resource
1012 // begin: enable msix
1015 // map to interrupt handler
1017 int mesgs = MAX_MSIX_NUM_VECTOR;
1020 void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
1022 agtiapi_IntrHandler0,
1023 agtiapi_IntrHandler1,
1024 agtiapi_IntrHandler2,
1025 agtiapi_IntrHandler3,
1026 agtiapi_IntrHandler4,
1027 agtiapi_IntrHandler5,
1028 agtiapi_IntrHandler6,
1029 agtiapi_IntrHandler7,
1030 agtiapi_IntrHandler8,
1031 agtiapi_IntrHandler9,
1032 agtiapi_IntrHandler10,
1033 agtiapi_IntrHandler11,
1034 agtiapi_IntrHandler12,
1035 agtiapi_IntrHandler13,
1036 agtiapi_IntrHandler14,
1037 agtiapi_IntrHandler15
1041 cnt = pci_msix_count(devx);
1042 AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64
1043 mesgs = MIN(mesgs, cnt);
1044 error = pci_alloc_msix(devx, &mesgs);
1046 printf( "pci_alloc_msix error %d\n", error );
1047 AGTIAPI_PRINTK("error %d\n", error);
1051 for(i=0; i < mesgs; i++) {
1052 pmsc->rscID[i] = i + 1;
1053 pmsc->irq[i] = bus_alloc_resource_any( devx,
1057 if( pmsc->irq[i] == NULL ) {
1058 printf( "RES_IRQ went terribly bad at %d\n", i );
1062 if ( (error = bus_setup_intr( devx, pmsc->irq[i],
1063 INTR_TYPE_CAM | INTR_MPSAFE,
1067 &pmsc->intrcookie[i] )
1069 device_printf( devx, "Failed to register handler" );
1073 pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
1074 pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
1078 ret = agtiapi_InitCardSW(pmsc);
1079 if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
1081 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
1086 pmsc->ccbFreeList = NULL;
1087 pmsc->ccbChainList = NULL;
1088 pmsc->ccbAllocList = NULL;
1090 pmsc->flags |= ( AGTIAPI_INSTALLED );
1092 ret = agtiapi_alloc_requests( pmsc );
1094 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
1099 ret = agtiapi_alloc_ostimem( pmsc );
1100 if (ret != AGTIAPI_SUCCESS)
1102 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
1107 ret = agtiapi_InitCardHW( pmsc );
1110 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
1115 #ifdef HIALEAH_ENCRYPTION
1118 if((agtiapi_SetupEncryption(pmsc)) < 0)
1119 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
1123 pmsc->flags &= ~AGTIAPI_INIT_TIME;
1127 /******************************************************************************
1128 agtiapi_InitCardSW()
1131 Host Bus Adapter Initialization
1133 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1135 AGTIAPI_SUCCESS - success
1138 TBD, need chip register information
1139 ******************************************************************************/
1140 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc )
1142 ag_card_info_t *thisCardInst = pmsc->pCardInfo;
1143 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
1146 // begin: agtiapi_InitCardSW()
1147 // now init some essential locks n agtiapi_InitCardSW
1148 mtx_init( &pmsc->sendLock, "local q send lock", NULL, MTX_DEF );
1149 mtx_init( &pmsc->doneLock, "local q done lock", NULL, MTX_DEF );
1150 mtx_init( &pmsc->sendSMPLock, "local q send lock", NULL, MTX_DEF );
1151 mtx_init( &pmsc->doneSMPLock, "local q done lock", NULL, MTX_DEF );
1152 mtx_init( &pmsc->ccbLock, "ccb list lock", NULL, MTX_DEF );
1153 mtx_init( &pmsc->devListLock, "hotP devListLock", NULL, MTX_DEF );
1154 mtx_init( &pmsc->memLock, "dynamic memory lock", NULL, MTX_DEF );
1155 mtx_init( &pmsc->freezeLock, "sim freeze lock", NULL, MTX_DEF | MTX_RECURSE);
1157 // initialize lower layer resources
1158 //## if (pCard->flags & AGTIAPI_INIT_TIME) {
1159 #ifdef HIALEAH_ENCRYPTION
1160 /* Enable encryption if chip supports it */
1161 if (pci_get_device(pmsc->pCardInfo->pPCIDev) ==
1162 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
1166 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
1168 pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
1171 // For now, up to 16 MSIX vectors are supported
1172 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.
1173 maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors;
1174 AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d",
1175 pmsc->pCardInfo->maxInterruptVectors );
1176 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0;
1177 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0;
1178 pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0;
1180 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n",
1181 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1182 if( tiCOMInit( &pmsc->tiRoot,
1183 &thisCardInst->tiRscInfo.tiLoLevelResource,
1184 &thisCardInst->tiRscInfo.tiInitiatorResource,
1186 &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
1187 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
1188 return AGTIAPI_FAIL;
1191 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
1192 pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
1193 M_ZERO | M_WAITOK );
1195 for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
1198 mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
1201 if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
1202 printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
1203 return AGTIAPI_FAIL;
1205 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
1206 " root %p, dev %p, pmsc %p\n",
1207 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1209 pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
1210 pmsc->freezeSim = agFALSE;
1212 #ifdef HIALEAH_ENCRYPTION
1213 atomic_set(&outstanding_encrypted_io_count, 0);
1215 /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
1216 if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
1217 printf("SetupEncryptionPools failed\n"); */
1219 return AGTIAPI_SUCCESS;
1220 // end: agtiapi_InitCardSW()
1223 /******************************************************************************
1224 agtiapi_InitCardHW()
1227 Host Bus Adapter Initialization
1229 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1231 AGTIAPI_SUCCESS - success
1234 TBD, need chip register information
1235 ******************************************************************************/
1236 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc )
1241 // begin: agtiapi_InitCardHW()
1243 ag_portal_info_t *pPortalInfo = NULL;
1244 ag_portal_data_t *pPortalData;
1246 // ISR is registered, enable chip interrupt.
1247 tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
1248 pmsc->flags |= AGTIAPI_SYS_INTR_ON;
1250 numVal = sizeof(ag_device_t) * pmsc->devDiscover;
1252 (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK );
1253 if( !pmsc->pDevList ) {
1254 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal );
1255 panic( "agtiapi_InitCardHW\n" );
1256 return AGTIAPI_FAIL;
1259 #ifdef LINUX_PERBI_SUPPORT
1260 numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
1262 (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK );
1263 if( !pmsc->pSLRList ) {
1264 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal );
1265 panic( "agtiapi_InitCardHW SLRL\n" );
1266 return AGTIAPI_FAIL;
1269 numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
1271 (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK );
1272 if( !pmsc->pWWNList ) {
1273 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal );
1274 panic( "agtiapi_InitCardHW WWNL\n" );
1275 return AGTIAPI_FAIL;
1278 // Get the WWN_to_target_ID mappings from the
1279 // holding area which contains the input of the
1280 // system configuration file.
1282 agtiapi_GetWWNMappings( pmsc, agMappingList );
1284 agtiapi_GetWWNMappings( pmsc, 0 );
1286 printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
1290 //agtiapi_DelaySec(5);
1295 pmsc->flags &= ~AGTIAPI_CB_DONE;
1296 pPortalData = pmsc->pPortalData;
1300 for (count = 0; count < pmsc->portCount; count++)
1302 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
1304 pPortalInfo = &pPortalData->portalInfo;
1305 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
1306 AGTIAPI_PORT_DISC_READY |
1308 AGTIAPI_DISC_COMPLETE );
1310 for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
1312 AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
1314 pPortalInfo->portID,
1315 &pPortalInfo->tiPortalContext );
1317 if( tiCOMPortStart( &pmsc->tiRoot,
1318 pPortalInfo->portID,
1319 &pPortalInfo->tiPortalContext,
1322 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1323 agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY );
1324 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
1325 AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n",
1329 AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n",
1333 } // end of for loop
1335 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1337 if( loop >= AGTIAPI_LOOP_MAX ) {
1338 return AGTIAPI_FAIL;
1340 tiCOMGetPortInfo( &pmsc->tiRoot,
1341 &pPortalInfo->tiPortalContext,
1342 &pPortalInfo->tiPortInfo );
1346 /* discover target device */
1347 #ifndef HOTPLUG_SUPPORT
1348 agtiapi_DiscoverTgt( pCard );
1352 pmsc->flags |= AGTIAPI_INSTALLED;
1354 if( pmsc->flags & AGTIAPI_INIT_TIME ) {
1355 agtiapi_TITimer( (void *)pmsc );
1356 pmsc->flags |= AGTIAPI_TIMER_ON;
1364 /******************************************************************************
1365 agtiapi_IntrHandlerx_()
1368 Interrupt service routine.
1370 void arg (IN) Pointer to the HBA data structure
1371 bit32 idx (IN) Vector index
1372 ******************************************************************************/
1373 void agtiapi_IntrHandlerx_( void *arg, int index )
1376 struct agtiapi_softc *pCard;
1379 pCard = (struct agtiapi_softc *)arg;
1385 AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
1386 AG_PERF_SPINLOCK(agtiapi_host_lock);
1387 if (pCard->flags & AGTIAPI_SHUT_DOWN)
1390 rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
1394 AG_SPIN_UNLOCK(agtiapi_host_lock);
1395 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1401 tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
1403 /* consume all completed entries, 100 is random number to be big enough */
1404 tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext);
1405 AG_GET_DONE_PCCB(pccb, pCard);
1406 AG_GET_DONE_SMP_PCCB(pccb, pCard);
1410 AG_SPIN_UNLOCK(agtiapi_host_lock);
1411 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1416 /******************************************************************************
1417 agtiapi_IntrHandler0()
1418 Purpose: Interrupt service routine for interrupt vector index 0.
1419 Parameters: void arg (IN) Pointer to the HBA data structure
1420 ******************************************************************************/
1421 void agtiapi_IntrHandler0( void *arg )
1423 agtiapi_IntrHandlerx_( arg, 0 );
1427 /******************************************************************************
1428 agtiapi_IntrHandler1()
1429 Purpose: Interrupt service routine for interrupt vector index 1.
1430 Parameters: void arg (IN) Pointer to the HBA data structure
1431 ******************************************************************************/
1432 void agtiapi_IntrHandler1( void *arg )
1434 agtiapi_IntrHandlerx_( arg, 1 );
1438 /******************************************************************************
1439 agtiapi_IntrHandler2()
1440 Purpose: Interrupt service routine for interrupt vector index 2.
1441 Parameters: void arg (IN) Pointer to the HBA data structure
1442 ******************************************************************************/
1443 void agtiapi_IntrHandler2( void *arg )
1445 agtiapi_IntrHandlerx_( arg, 2 );
1449 /******************************************************************************
1450 agtiapi_IntrHandler3()
1451 Purpose: Interrupt service routine for interrupt vector index 3.
1452 Parameters: void arg (IN) Pointer to the HBA data structure
1453 ******************************************************************************/
1454 void agtiapi_IntrHandler3( void *arg )
1456 agtiapi_IntrHandlerx_( arg, 3 );
1460 /******************************************************************************
1461 agtiapi_IntrHandler4()
1462 Purpose: Interrupt service routine for interrupt vector index 4.
1463 Parameters: void arg (IN) Pointer to the HBA data structure
1464 ******************************************************************************/
1465 void agtiapi_IntrHandler4( void *arg )
1467 agtiapi_IntrHandlerx_( arg, 4 );
1471 /******************************************************************************
1472 agtiapi_IntrHandler5()
1473 Purpose: Interrupt service routine for interrupt vector index 5.
1474 Parameters: void arg (IN) Pointer to the HBA data structure
1475 ******************************************************************************/
1476 void agtiapi_IntrHandler5( void *arg )
1478 agtiapi_IntrHandlerx_( arg, 5 );
1482 /******************************************************************************
1483 agtiapi_IntrHandler6()
1484 Purpose: Interrupt service routine for interrupt vector index 6.
1485 Parameters: void arg (IN) Pointer to the HBA data structure
1486 ******************************************************************************/
1487 void agtiapi_IntrHandler6( void *arg )
1489 agtiapi_IntrHandlerx_( arg, 6 );
1493 /******************************************************************************
1494 agtiapi_IntrHandler7()
1495 Purpose: Interrupt service routine for interrupt vector index 7.
1496 Parameters: void arg (IN) Pointer to the HBA data structure
1497 ******************************************************************************/
1498 void agtiapi_IntrHandler7( void *arg )
1500 agtiapi_IntrHandlerx_( arg, 7 );
1504 /******************************************************************************
1505 agtiapi_IntrHandler8()
1506 Purpose: Interrupt service routine for interrupt vector index 8.
1507 Parameters: void arg (IN) Pointer to the HBA data structure
1508 ******************************************************************************/
1509 void agtiapi_IntrHandler8( void *arg )
1511 agtiapi_IntrHandlerx_( arg, 8 );
1515 /******************************************************************************
1516 agtiapi_IntrHandler9()
1517 Purpose: Interrupt service routine for interrupt vector index 9.
1518 Parameters: void arg (IN) Pointer to the HBA data structure
1519 ******************************************************************************/
1520 void agtiapi_IntrHandler9( void *arg )
1522 agtiapi_IntrHandlerx_( arg, 9 );
1526 /******************************************************************************
1527 agtiapi_IntrHandler10()
1528 Purpose: Interrupt service routine for interrupt vector index 10.
1529 Parameters: void arg (IN) Pointer to the HBA data structure
1530 ******************************************************************************/
1531 void agtiapi_IntrHandler10( void *arg )
1533 agtiapi_IntrHandlerx_( arg, 10 );
1537 /******************************************************************************
1538 agtiapi_IntrHandler11()
1539 Purpose: Interrupt service routine for interrupt vector index 11.
1540 Parameters: void arg (IN) Pointer to the HBA data structure
1541 ******************************************************************************/
1542 void agtiapi_IntrHandler11( void *arg )
1544 agtiapi_IntrHandlerx_( arg, 11 );
1548 /******************************************************************************
1549 agtiapi_IntrHandler12()
1550 Purpose: Interrupt service routine for interrupt vector index 12.
1551 Parameters: void arg (IN) Pointer to the HBA data structure
1552 ******************************************************************************/
1553 void agtiapi_IntrHandler12( void *arg )
1555 agtiapi_IntrHandlerx_( arg, 12 );
1559 /******************************************************************************
1560 agtiapi_IntrHandler13()
1561 Purpose: Interrupt service routine for interrupt vector index 13.
1562 Parameters: void arg (IN) Pointer to the HBA data structure
1563 ******************************************************************************/
1564 void agtiapi_IntrHandler13( void *arg )
1566 agtiapi_IntrHandlerx_( arg, 13 );
1570 /******************************************************************************
1571 agtiapi_IntrHandler14()
1572 Purpose: Interrupt service routine for interrupt vector index 14.
1573 Parameters: void arg (IN) Pointer to the HBA data structure
1574 ******************************************************************************/
1575 void agtiapi_IntrHandler14( void *arg )
1577 agtiapi_IntrHandlerx_( arg, 14 );
1581 /******************************************************************************
1582 agtiapi_IntrHandler15()
1583 Purpose: Interrupt service routine for interrupt vector index 15.
1584 Parameters: void arg (IN) Pointer to the HBA data structure
1585 ******************************************************************************/
1586 void agtiapi_IntrHandler15( void *arg )
1588 agtiapi_IntrHandlerx_( arg, 15 );
1592 static void agtiapi_SglMemoryCB( void *arg,
1593 bus_dma_segment_t *dm_segs,
1598 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
1601 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
1602 panic("agtiapi_SglMemoryCB: error %d\n", error);
1606 *addr = dm_segs[0].ds_addr;
1610 static void agtiapi_MemoryCB( void *arg,
1611 bus_dma_segment_t *dm_segs,
1616 AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
1619 AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
1620 panic("agtiapi_MemoryCB: error %d\n", error);
1624 *addr = dm_segs[0].ds_addr;
1628 /******************************************************************************
1629 agtiapi_alloc_requests()
1632 Allocates resources such as dma tag and timer
1634 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1636 AGTIAPI_SUCCESS - success
1639 ******************************************************************************/
1640 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
1646 nsegs = AGTIAPI_NSEGS;
1647 rsize = AGTIAPI_MAX_DMA_SEGS; // 128
1648 AGTIAPI_PRINTK( "agtiapi_alloc_requests: MAXPHYS 0x%x PAGE_SIZE 0x%x \n",
1649 MAXPHYS, PAGE_SIZE );
1650 AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n",
1651 nsegs, rsize ); // 32, 128
1652 // This is for csio->data_ptr
1653 if( bus_dma_tag_create( agNULL, // parent
1656 BUS_SPACE_MAXADDR, // lowaddr
1657 BUS_SPACE_MAXADDR, // highaddr
1660 BUS_SPACE_MAXSIZE_32BIT, // maxsize
1662 BUS_SPACE_MAXSIZE_32BIT, // maxsegsize
1663 BUS_DMA_ALLOCNOW, // flags
1664 busdma_lock_mutex, // lockfunc
1665 &pmcsc->pCardInfo->pmIOLock, // lockarg
1666 &pmcsc->buffer_dmat ) ) {
1667 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1671 // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
1673 (sizeof(tiSgl_t) * AGTIAPI_NSEGS) *
1674 AGTIAPI_CCB_PER_DEVICE * maxTargets;
1675 AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128
1676 if( bus_dma_tag_create( agNULL, // parent
1679 BUS_SPACE_MAXADDR_32BIT, // lowaddr
1680 BUS_SPACE_MAXADDR, // highaddr
1685 rsize, // maxsegsize
1686 BUS_DMA_ALLOCNOW, // flags
1689 &pmcsc->tisgl_dmat ) ) {
1690 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1694 if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
1695 (void **)&pmcsc->tisgl_mem,
1697 &pmcsc->tisgl_map ) ) {
1698 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
1702 bzero( pmcsc->tisgl_mem, rsize );
1703 bus_dmamap_load( pmcsc->tisgl_dmat,
1707 agtiapi_SglMemoryCB,
1708 &pmcsc->tisgl_busaddr,
1709 BUS_DMA_NOWAIT /* 0 */ );
1711 mtx_init( &pmcsc->OS_timer_lock, "OS timer lock", NULL, MTX_DEF );
1712 mtx_init( &pmcsc->IO_timer_lock, "IO timer lock", NULL, MTX_DEF );
1713 mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF );
1714 callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 );
1715 callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 );
1716 callout_init_mtx( &pmcsc->devRmTimer,
1717 &pmcsc->devRmTimerLock, 0);
1719 next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource.
1720 loLevelOption.usecsPerTick / USEC_PER_TICK;
1721 AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, "
1722 "next_tick 0x%x\n", next_tick );
1723 callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc );
1727 /******************************************************************************
1728 agtiapi_alloc_ostimem()
1731 Allocates memory used later in ostiAllocMemory
1733 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure
1735 AGTIAPI_SUCCESS - success
1738 This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
1739 ******************************************************************************/
1740 int agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
1744 rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
1745 AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
1747 if( bus_dma_tag_create( agNULL, // parent
1750 BUS_SPACE_MAXADDR, // lowaddr
1751 BUS_SPACE_MAXADDR, // highaddr
1754 rsize, // maxsize (size)
1755 1, // number of segments
1756 rsize, // maxsegsize
1760 &pmcsc->osti_dmat ) ) {
1761 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
1762 return AGTIAPI_FAIL;
1766 if( bus_dmamem_alloc( pmcsc->osti_dmat,
1768 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
1769 &pmcsc->osti_mapp ) ) {
1770 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n",
1772 return AGTIAPI_FAIL;
1776 bus_dmamap_load( pmcsc->osti_dmat,
1780 agtiapi_MemoryCB, // try reuse of CB for same goal
1781 &pmcsc->osti_busaddr,
1784 // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
1785 // handy reference when driver is in motion
1787 ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
1788 ag_dma_addr_t *pMem;
1790 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
1791 pMem = &pCardInfo->dynamicMem[idx];
1792 pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize );
1793 pMem->nocache_mem = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize ));
1794 pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx];
1797 pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
1799 return AGTIAPI_SUCCESS;
1803 /******************************************************************************
1804 agtiapi_cam_action()
1807 Parses CAM frames and triggers a corresponding action
1809 struct cam_sim *sim (IN) Pointer to SIM data structure
1810 union ccb * ccb (IN) Pointer to CAM ccb data structure
1813 ******************************************************************************/
1814 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
1816 struct agtiapi_softc *pmcsc;
1817 tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well
1818 tiDeviceInfo_t devInfo;
1819 int pathID, targetID, lunID;
1824 pmcsc = cam_sim_softc( sim );
1825 AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
1827 if (pmcsc == agNULL)
1829 AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
1832 mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
1834 AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
1836 pathID = xpt_path_path_id( ccb->ccb_h.path );
1837 targetID = xpt_path_target_id( ccb->ccb_h.path );
1838 lunID = xpt_path_lun_id( ccb->ccb_h.path );
1840 AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
1841 pathID, targetID, lunID );
1843 switch (ccb->ccb_h.func_code)
1847 struct ccb_pathinq *cpi;
1849 /* See architecure book p180*/
1851 cpi->version_num = 1;
1852 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16;
1853 cpi->target_sprt = 0;
1854 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
1855 cpi->hba_eng_cnt = 0;
1856 cpi->max_target = maxTargets - 1;
1857 cpi->max_lun = AGTIAPI_MAX_LUN;
1858 cpi->maxio = 1024 *1024; /* Max supported I/O size, in bytes. */
1859 cpi->initiator_id = 255;
1860 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1861 strncpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1862 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1863 cpi->unit_number = cam_sim_unit(sim);
1864 cpi->bus_id = cam_sim_bus(sim);
1865 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1866 cpi->base_transfer_speed = 150000;
1867 cpi->transport = XPORT_SAS;
1868 cpi->transport_version = 0;
1869 cpi->protocol = PROTO_SCSI;
1870 cpi->protocol_version = SCSI_REV_SPC3;
1871 cpi->ccb_h.status = CAM_REQ_CMP;
1874 case XPT_GET_TRAN_SETTINGS:
1876 struct ccb_trans_settings *cts;
1877 struct ccb_trans_settings_sas *sas;
1878 struct ccb_trans_settings_scsi *scsi;
1880 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1886 sas = &ccb->cts.xport_specific.sas;
1887 scsi = &cts->proto_specific.scsi;
1889 cts->protocol = PROTO_SCSI;
1890 cts->protocol_version = SCSI_REV_SPC3;
1891 cts->transport = XPORT_SAS;
1892 cts->transport_version = 0;
1894 sas->valid = CTS_SAS_VALID_SPEED;
1896 /* this sets the "MB/s transfers" */
1897 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1899 if (pmcsc->pWWNList != NULL)
1901 TID = INDEX(pmcsc, targetID);
1902 if (TID < maxTargets)
1904 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1910 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1911 switch (devInfo.info.devType_S_Rate & 0xF)
1913 case 0x8: speed = 150000;
1915 case 0x9: speed = 300000;
1917 case 0xA: speed = 600000;
1919 case 0xB: speed = 1200000;
1921 default: speed = 150000;
1925 sas->bitrate = speed;
1926 scsi->valid = CTS_SCSI_VALID_TQ;
1927 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1928 ccb->ccb_h.status = CAM_REQ_CMP;
1933 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1934 if ( SUCCESS == lRetVal )
1936 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1940 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1942 ccb->ccb_h.status = CAM_REQ_CMP;
1947 ccb->ccb_h.status = CAM_REQ_CMP;
1952 ccb->ccb_h.status = CAM_REQ_CMP;
1955 #if __FreeBSD_version >= 900026
1958 agtiapi_QueueSMP( pmcsc, ccb );
1961 #endif /* __FreeBSD_version >= 900026 */
1964 if(pmcsc->dev_scan == agFALSE)
1966 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1969 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1971 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1973 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1978 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1980 agtiapi_QueueCmnd_( pmcsc, ccb );
1985 case XPT_CALC_GEOMETRY:
1987 cam_calc_geometry(&ccb->ccg, 1);
1988 ccb->ccb_h.status = CAM_REQ_CMP;
1994 XPT_SET_TRAN_SETTINGS
1996 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1997 ccb->ccb_h.func_code );
1998 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2006 /******************************************************************************
2010 Get a ccb from free list or allocate a new one
2012 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
2014 Pointer to a ccb structure, or NULL if not available
2016 ******************************************************************************/
2017 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
2021 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2023 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2025 /* get the ccb from the head of the free list */
2026 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2028 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2029 pccb->pccbNext = NULL;
2030 pccb->flags = ACTIVE;
2031 pccb->startTime = 0;
2033 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2037 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2040 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2044 /******************************************************************************
2045 agtiapi_QueueCmnd_()
2048 Calls for sending CCB and excuting on HBA.
2050 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2051 union ccb * ccb (IN) Pointer to CAM ccb data structure
2053 0 - Command is pending to execute
2054 1 - Command returned without further process
2056 ******************************************************************************/
2057 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2059 struct ccb_scsiio *csio = &ccb->csio;
2060 pccb_t pccb = agNULL; // call dequeue
2061 int status = tiSuccess;
2062 U32 Channel = CMND_TO_CHANNEL(ccb);
2063 U32 TID = CMND_TO_TARGET(ccb);
2064 U32 LUN = CMND_TO_LUN(ccb);
2066 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2068 /* no support for CBD > 16 */
2069 if (csio->cdb_len > 16)
2071 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2073 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2074 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2075 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2079 if (TID < 0 || TID >= maxTargets)
2081 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2082 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2083 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2084 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2089 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2092 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2095 TID = INDEX(pmcsc, TID);
2096 targ = &pmcsc->pDevList[TID];
2100 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2102 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2103 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2104 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2108 pccb->pmcsc = pmcsc;
2109 /* initialize Command Control Block (CCB) */
2110 pccb->targetId = TID;
2112 pccb->channel = Channel;
2113 pccb->ccb = ccb; /* for struct scsi_cmnd */
2114 pccb->senseLen = csio->sense_len;
2115 pccb->startTime = ticks;
2116 pccb->pSenseData = (caddr_t) &csio->sense_data;
2117 pccb->tiSuperScsiRequest.flags = 0;
2119 /* each channel is reserved for different addr modes */
2120 pccb->addrMode = agtiapi_AddrModes[Channel];
2122 status = agtiapi_PrepareSGList(pmcsc, pccb);
2123 if (status != tiSuccess)
2125 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2126 agtiapi_FreeCCB(pmcsc, pccb);
2127 if (status == tiReject)
2129 ccb->ccb_h.status = CAM_REQ_INVALID;
2133 ccb->ccb_h.status = CAM_REQ_CMP;
2141 /******************************************************************************
2147 const char *ptitle (IN) A string to be printed
2148 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2151 ******************************************************************************/
2152 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2155 struct ccb_scsiio *csio;
2161 printf( "agtiapi_DumpCDB: no pccb here \n" );
2162 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2168 printf( "agtiapi_DumpCDB: no ccb here \n" );
2169 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2171 pccb, pccb->ccb, pccb->flags, ptitle );
2177 printf( "agtiapi_DumpCDB: no csio here \n" );
2178 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2179 pccb, pccb->ccb, pccb->flags, ptitle );
2182 len = MIN(64, csio->cdb_len);
2183 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2185 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2189 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2192 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2193 " len %d from %s\n",
2201 /******************************************************************************
2202 agtiapi_DoSoftReset()
2207 *data (IN) point to pmcsc (struct agtiapi_softc *)
2210 ******************************************************************************/
2211 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2214 unsigned long flags;
2216 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2217 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2218 ret = agtiapi_ResetCard( pmcsc, &flags );
2219 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2221 if( ret != AGTIAPI_SUCCESS )
2227 /******************************************************************************
2228 agtiapi_CheckIOTimeout()
2231 Timeout function for SCSI IO or TM
2233 *data (IN) point to pCard (ag_card_t *)
2236 ******************************************************************************/
2237 STATIC void agtiapi_CheckIOTimeout(void *data)
2239 U32 status = AGTIAPI_SUCCESS;
2241 struct agtiapi_softc *pmcsc;
2244 pmcsc = (struct agtiapi_softc *)data;
2246 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2248 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2250 pccb = (pccb_t)pmcsc->ccbChainList;
2252 /* if link is down, do nothing */
2253 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2255 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2259 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2260 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2265 /* Walk thorugh the IO Chain linked list to find the pending io */
2266 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2267 while (pccb_curr != NULL)
2269 /* start from 1st ccb in the chain */
2270 pccb_next = pccb_curr->pccbChainNext;
2271 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2272 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2274 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2276 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2277 !(pccb_curr->flags & TIMEDOUT) )
2279 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2280 "function -- flags=%x startTime=%ld tdData = %p\n",
2281 pccb_curr, pccb_curr->flags, pccb->startTime,
2282 pccb_curr->tiIORequest.tdData );
2283 pccb_curr->flags |= TIMEDOUT;
2284 status = agtiapi_StartTM(pmcsc, pccb_curr);
2285 if (status == AGTIAPI_SUCCESS)
2287 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2293 #ifdef AGTIAPI_LOCAL_RESET
2294 /* abort request did not go through */
2295 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2296 /* TODO: call Soft reset here */
2297 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2298 "abort request did not go thru ==> soft reset#7, then "
2299 "restart timer\n" );
2300 agtiapi_DoSoftReset (pmcsc);
2305 pccb_curr = pccb_next;
2308 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2311 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2315 /******************************************************************************
2319 DDI calls for aborting outstanding IO command
2321 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2322 unsigned long flags (IN/out) spinlock flags used in locking from
2325 AGTIAPI_SUCCESS - success
2327 ******************************************************************************/
2329 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2331 ccb_t *pTMccb = NULL;
2332 U32 status = AGTIAPI_SUCCESS;
2333 ag_device_t *pDevice = NULL;
2334 U32 TMstatus = tiSuccess;
2335 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2336 pccb, pccb->flags );
2339 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2340 status = AGTIAPI_SUCCESS;
2343 if (!pccb->tiIORequest.tdData)
2345 /* should not be the case */
2346 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2347 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2348 status = AGTIAPI_FAIL;
2352 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2353 clear pending TM_ABORT_TASK */
2354 /* Else Device State will not be put back to Operational, (refer FW) */
2355 if (pccb->flags & TASK_MANAGEMENT)
2357 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2359 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2361 /* TODO: call Soft reset here */
2362 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2363 "tiINIIOAbort() failed ==> soft reset#8\n" );
2364 agtiapi_DoSoftReset( pCard );
2368 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2370 status = AGTIAPI_SUCCESS;
2376 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2378 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2379 status = AGTIAPI_FAIL;
2382 pTMccb->pmcsc = pCard;
2383 pTMccb->targetId = pccb->targetId;
2384 pTMccb->devHandle = pccb->devHandle;
2385 if (pTMccb->targetId >= pCard->devDiscover)
2387 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2388 status = AGTIAPI_FAIL;
2391 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2393 return AGTIAPI_FAIL;
2395 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2397 return AGTIAPI_FAIL;
2399 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2400 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2402 return AGTIAPI_FAIL;
2405 /* save pending io to issue local abort at Task mgmt CB */
2406 pTMccb->pccbIO = pccb;
2407 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2409 pTMccb, pTMccb->flags, pTMccb->targetId );
2410 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2411 pTMccb->flags |= TASK_MANAGEMENT;
2412 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2415 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2417 &pTMccb->tiIORequest);
2418 if (TMstatus == tiSuccess)
2420 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2423 pTMccb->startTime = ticks;
2424 status = AGTIAPI_SUCCESS;
2426 else if (TMstatus == tiIONoDevice)
2428 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2431 status = AGTIAPI_SUCCESS;
2435 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2438 status = AGTIAPI_FAIL;
2439 agtiapi_FreeTMCCB(pCard, pTMccb);
2441 /* call TM_TARGET_RESET */
2446 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2447 (pccb) ? pccb->flags : -1);
2449 } /* agtiapi_StartTM */
2451 #if __FreeBSD_version > 901000
2452 /******************************************************************************
2453 agtiapi_PrepareSGList()
2456 This function prepares scatter-gather list for the given ccb
2458 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2459 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2465 ******************************************************************************/
2466 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2468 union ccb *ccb = pccb->ccb;
2469 struct ccb_scsiio *csio = &ccb->csio;
2470 struct ccb_hdr *ccbh = &ccb->ccb_h;
2471 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2473 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2474 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2476 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2478 switch((ccbh->flags & CAM_DATA_MASK))
2481 struct bus_dma_segment seg;
2482 case CAM_DATA_VADDR:
2483 /* Virtual address that needs to translated into one or more physical address ranges. */
2485 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2486 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2487 error = bus_dmamap_load( pmcsc->buffer_dmat,
2491 agtiapi_PrepareSGListCB,
2493 BUS_DMA_NOWAIT/* 0 */ );
2494 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2496 if (error == EINPROGRESS)
2498 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2499 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2500 xpt_freeze_simq(pmcsc->sim, 1);
2501 pmcsc->SimQFrozen = agTRUE;
2502 ccbh->status |= CAM_RELEASE_SIMQ;
2505 case CAM_DATA_PADDR:
2506 /* We have been given a pointer to single physical buffer. */
2507 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2508 //struct bus_dma_segment seg;
2509 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2511 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2512 seg.ds_len = csio->dxfer_len;
2513 // * 0xFF to be defined
2514 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2517 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2523 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2528 /******************************************************************************
2529 agtiapi_PrepareSGList()
2532 This function prepares scatter-gather list for the given ccb
2534 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2535 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2541 ******************************************************************************/
2542 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2544 union ccb *ccb = pccb->ccb;
2545 struct ccb_scsiio *csio = &ccb->csio;
2546 struct ccb_hdr *ccbh = &ccb->ccb_h;
2547 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2548 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2549 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2551 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2553 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2555 /* We've been given a pointer to a single buffer. */
2556 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2558 /* Virtual address that needs to translated into one or more physical address ranges. */
2560 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2561 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2562 error = bus_dmamap_load( pmcsc->buffer_dmat,
2566 agtiapi_PrepareSGListCB,
2568 BUS_DMA_NOWAIT/* 0 */ );
2569 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2571 if (error == EINPROGRESS)
2573 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2574 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2575 xpt_freeze_simq(pmcsc->sim, 1);
2576 pmcsc->SimQFrozen = agTRUE;
2577 ccbh->status |= CAM_RELEASE_SIMQ;
2582 /* We have been given a pointer to single physical buffer. */
2583 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2584 struct bus_dma_segment seg;
2585 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2587 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2588 seg.ds_len = csio->dxfer_len;
2589 // * 0xFF to be defined
2590 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2596 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2602 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2608 /******************************************************************************
2609 agtiapi_PrepareSGListCB()
2612 Callback function for bus_dmamap_load()
2613 This fuctions sends IO to LL layer.
2615 void *arg (IN) Pointer to the HBA data structure
2616 bus_dma_segment_t *segs (IN) Pointer to dma segment
2617 int nsegs (IN) number of dma segment
2618 int error (IN) error
2621 ******************************************************************************/
2622 static void agtiapi_PrepareSGListCB( void *arg,
2623 bus_dma_segment_t *segs,
2628 union ccb *ccb = pccb->ccb;
2629 struct ccb_scsiio *csio = &ccb->csio;
2631 struct agtiapi_softc *pmcsc;
2632 tiIniScsiCmnd_t *pScsiCmnd;
2634 bus_dmasync_op_t op;
2637 int io_is_encryptable = 0;
2638 unsigned long long start_lba = 0;
2640 U32 TID = CMND_TO_TARGET(ccb);
2642 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2644 pmcsc = pccb->pmcsc;
2646 if (error != tiSuccess)
2648 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2654 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2655 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2656 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2657 agtiapi_FreeCCB(pmcsc, pccb);
2658 ccb->ccb_h.status = CAM_REQ_CMP;
2664 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2666 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2667 " AGTIAPI_MAX_DMA_SEGS %d\n",
2668 nsegs, AGTIAPI_MAX_DMA_SEGS );
2669 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2670 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2671 agtiapi_FreeCCB(pmcsc, pccb);
2672 ccb->ccb_h.status = CAM_REQ_CMP;
2678 /* fill in IO information */
2679 pccb->dataLen = csio->dxfer_len;
2681 /* start fill in sgl structure */
2682 if (nsegs == 1 && error == 0xAABBCCDD)
2685 /* A single physical buffer */
2686 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2687 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2688 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2689 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2690 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2691 pccb->numSgElements = 1;
2693 else if (nsegs == 0 && error == 0xAAAAAAAA)
2695 /* no data transfer */
2696 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2697 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2699 pccb->numSgElements = 0;
2703 /* virtual/logical buffer */
2706 pccb->dataLen = segs[0].ds_len;
2708 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2709 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2710 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2711 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2712 pccb->numSgElements = nsegs;
2719 for (i = 0; i < nsegs; i++)
2721 pccb->sgList[i].len = htole32(segs[i].ds_len);
2722 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2723 pccb->sgList[i].type = htole32(tiSgl);
2724 pccb->dataLen += segs[i].ds_len;
2727 pccb->numSgElements = nsegs;
2728 /* set up sgl buffer address */
2729 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2730 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2731 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2732 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2733 pccb->numSgElements = nsegs;
2737 /* set data transfer direction */
2738 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2740 op = BUS_DMASYNC_PREWRITE;
2741 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2745 op = BUS_DMASYNC_PREREAD;
2746 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2749 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2751 pScsiCmnd->expDataLength = pccb->dataLen;
2753 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2755 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2759 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2762 CDB = &pScsiCmnd->cdb[0];
2766 case REQUEST_SENSE: /* requires different buffer */
2767 /* This code should not be excercised because SAS support auto sense
2768 For the completeness, vtophys() is still used here.
2770 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2771 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2772 phys_addr = vtophys(&csio->sense_data);
2773 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2774 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2775 pccb->dataLen = pccb->senseLen;
2776 pccb->numSgElements = 1;
2779 /* only using lun 0 for device type detection */
2780 pccb->flags |= AGTIAPI_INQUIRY;
2782 case TEST_UNIT_READY:
2786 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2792 start_lba = ((CDB[1] & 0x1f) << 16) |
2795 #ifdef HIALEAH_ENCRYPTION
2796 io_is_encryptable = 1;
2804 start_lba = (CDB[2] << 24) |
2808 #ifdef HIALEAH_ENCRYPTION
2809 io_is_encryptable = 1;
2815 start_lba = (CDB[2] << 24) |
2820 start_lba |= ((CDB[6] << 24) |
2824 #ifdef HIALEAH_ENCRYPTION
2825 io_is_encryptable = 1;
2832 /* fill device lun based one address mode */
2833 agtiapi_SetLunField(pccb);
2835 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2837 pccb->ccbStatus = tiIOFailed;
2838 pccb->scsiStatus = tiDetailNoLogin;
2839 agtiapi_FreeCCB(pmcsc, pccb);
2840 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2845 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2847 pccb->ccbStatus = tiIOFailed;
2848 pccb->scsiStatus = tiDetailNoLogin;
2849 agtiapi_FreeCCB(pmcsc, pccb);
2850 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2855 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2858 if ((pmcsc->flags & EDC_DATA) &&
2859 (pDev->flags & EDC_DATA))
2864 * Possible command supported -
2865 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2866 * READ_DEFECT_DATA, etc.
2867 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2868 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2870 * Do some data length adjustment and set chip operation instruction.
2878 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2879 #ifdef AGTIAPI_TEST_DIF
2880 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2882 pccb->flags |= EDC_DATA;
2884 #ifdef TEST_VERIFY_AND_FORWARD
2885 pccb->tiSuperScsiRequest.Dif.flags =
2886 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2887 if(pDev->sector_size == 520) {
2888 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2889 } else if(pDev->sector_size == 4104) {
2890 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2893 #ifdef AGTIAPI_TEST_DIF
2894 pccb->tiSuperScsiRequest.Dif.flags =
2895 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2898 #ifdef AGTIAPI_TEST_DIF
2899 switch(pDev->sector_size) {
2901 pccb->tiSuperScsiRequest.Dif.flags |=
2902 ( DIF_BLOCK_SIZE_520 << 16 );
2905 pccb->tiSuperScsiRequest.Dif.flags |=
2906 ( DIF_BLOCK_SIZE_4096 << 16 );
2909 pccb->tiSuperScsiRequest.Dif.flags |=
2910 ( DIF_BLOCK_SIZE_4160 << 16 );
2914 if(pCard->flags & EDC_DATA_CRC)
2915 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2917 /* Turn on upper 4 bits of UVM */
2918 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2921 #ifdef AGTIAPI_TEST_DPL
2922 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2923 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2924 cmnd->result = SCSI_HOST(DID_ERROR);
2927 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2929 #ifdef AGTIAPI_TEST_DIF
2931 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2932 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2934 /* Set LBA in UDT array */
2935 if(CDB[0] == READ_6) {
2936 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2937 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2938 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2939 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2940 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2941 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2942 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2943 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2944 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2945 } else if(CDB[0] == READ_16) {
2946 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2947 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2948 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2949 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2950 /* Note: 32 bits lost */
2959 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2960 pccb->flags |= EDC_DATA;
2961 #ifdef AGTIAPI_TEST_DIF
2962 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2963 pccb->tiSuperScsiRequest.Dif.flags =
2964 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2965 switch(pDev->sector_size) {
2967 pccb->tiSuperScsiRequest.Dif.flags |=
2968 (DIF_BLOCK_SIZE_520 << 16);
2971 pccb->tiSuperScsiRequest.Dif.flags |=
2972 ( DIF_BLOCK_SIZE_4096 << 16 );
2975 pccb->tiSuperScsiRequest.Dif.flags |=
2976 ( DIF_BLOCK_SIZE_4160 << 16 );
2980 /* Turn on upper 4 bits of UUM */
2981 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2983 #ifdef AGTIAPI_TEST_DPL
2984 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2985 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2986 cmnd->result = SCSI_HOST(DID_ERROR);
2989 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2991 #ifdef AGTIAPI_TEST_DIF
2993 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2994 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2996 /* Set LBA in UDT array */
2997 if(CDB[0] == WRITE_6) {
2998 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2999 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
3000 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
3001 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
3002 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
3003 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
3004 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
3005 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
3006 } else if(CDB[0] == WRITE_16) {
3007 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
3008 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
3009 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
3010 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
3011 /* Note: 32 bits lost */
3017 #endif /* end of DIF */
3019 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
3021 switch(csio->tag_action)
3023 case MSG_HEAD_OF_Q_TAG:
3024 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3027 pScsiCmnd->taskAttribute = TASK_ACA;
3029 case MSG_ORDERED_Q_TAG:
3030 pScsiCmnd->taskAttribute = TASK_ORDERED;
3032 case MSG_SIMPLE_Q_TAG: /* fall through */
3034 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3039 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3041 /* should be just before start IO */
3042 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3046 * If assigned pDevHandle is not available
3047 * then there is no need to send it to StartIO()
3049 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
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 TID = INDEX(pmcsc, pccb->targetId);
3060 if ((TID >= pmcsc->devDiscover) ||
3061 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3064 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3065 " target %d tid %d/%d card %p ERROR pccb %p\n",
3066 pccb->devHandle, pccb->targetId, TID,
3067 pmcsc->devDiscover, pmcsc, pccb );
3069 pccb->ccbStatus = tiIOFailed;
3070 pccb->scsiStatus = tiDetailNoLogin;
3071 agtiapi_FreeCCB(pmcsc, pccb);
3072 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3077 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3078 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3079 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3081 #ifdef HIALEAH_ENCRYPTION
3082 if(pmcsc->encrypt && io_is_encryptable) {
3083 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3085 io_is_encryptable = 0;
3086 pccb->tiSuperScsiRequest.flags = 0;
3089 // put the request in send queue
3090 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3091 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3092 agtiapi_StartIO(pmcsc);
3096 /******************************************************************************
3100 Send IO request down for processing.
3102 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3105 ******************************************************************************/
3106 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3111 struct ccb_relsim crs;
3113 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3115 AG_LOCAL_LOCK( &pmcsc->sendLock );
3116 pccb = pmcsc->ccbSendHead;
3118 /* if link is down, do nothing */
3119 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3121 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3122 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3127 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3129 TID = INDEX(pmcsc, pccb->targetId);
3130 targ = &pmcsc->pDevList[TID];
3134 /* clear send queue */
3135 pmcsc->ccbSendHead = NULL;
3136 pmcsc->ccbSendTail = NULL;
3137 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3139 /* send all ccbs down */
3145 pccb_next = pccb->pccbNext;
3146 pccb->pccbNext = NULL;
3150 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3154 AG_IO_DUMPCCB( pccb );
3156 if (!pccb->devHandle)
3158 agtiapi_DumpCCB( pccb );
3159 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3163 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3166 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3167 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3169 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3171 if( pccb->devHandle ) {
3172 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3174 pccb->devHandle->osData );
3175 if( pccb->devHandle->osData ) {
3176 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3177 " -- active flag:%d\n",
3179 (pccb->devHandle->osData))->flags & ACTIVE );
3182 pccb->ccbStatus = tiIOFailed;
3183 pccb->scsiStatus = tiDetailNoLogin;
3184 agtiapi_Done( pmcsc, pccb );
3191 status = agtiapi_FastIOTest( pmcsc, pccb );
3193 status = tiINISuperIOStart( &pmcsc->tiRoot,
3196 &pccb->tiSuperScsiRequest,
3197 (void *)&pccb->tdIOReqBody,
3198 tiInterruptContext );
3204 static int squelchCount = 0;
3205 if ( 200000 == squelchCount++ ) // squelch prints
3207 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3209 squelchCount = 0; // reset count
3216 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3219 agtiapi_LogEvent( pmcsc,
3220 IOCTL_EVT_SEV_INFORMATIONAL,
3224 "tiINIIOStart tiDeviceBusy " );
3226 pccb->ccbStatus = tiIOFailed;
3227 pccb->scsiStatus = tiDeviceBusy;
3228 agtiapi_Done(pmcsc, pccb);
3232 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3235 agtiapi_LogEvent( pmcsc,
3236 IOCTL_EVT_SEV_INFORMATIONAL,
3240 "tiINIIOStart tiBusy " );
3243 pccb->ccbStatus = tiIOFailed;
3244 pccb->scsiStatus = tiBusy;
3245 agtiapi_Done(pmcsc, pccb);
3249 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3250 "ERROR\n", pccb->ccb );
3252 agtiapi_LogEvent( pmcsc,
3253 IOCTL_EVT_SEV_INFORMATIONAL,
3257 "tiINIIOStart invalid device handle " );
3260 /* return command back to OS due to no device available */
3261 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3262 pccb->ccbStatus = tiIOFailed;
3263 pccb->scsiStatus = tiDetailNoLogin;
3264 agtiapi_Done(pmcsc, pccb);
3266 /* for short cable pull, we want IO retried - 3-18-2005 */
3267 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3268 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3272 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3275 agtiapi_LogEvent(pmcsc,
3276 IOCTL_EVT_SEV_INFORMATIONAL,
3280 "tiINIIOStart tiError ");
3282 pccb->ccbStatus = tiIOFailed;
3283 pccb->scsiStatus = tiDetailOtherError;
3284 agtiapi_Done(pmcsc, pccb);
3287 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3290 agtiapi_LogEvent(pmcsc,
3291 IOCTL_EVT_SEV_ERROR,
3295 "tiINIIOStart unexpected status ");
3297 pccb->ccbStatus = tiIOFailed;
3298 pccb->scsiStatus = tiDetailOtherError;
3299 agtiapi_Done(pmcsc, pccb);
3305 /* some IO requests might have been completed */
3306 AG_GET_DONE_PCCB(pccb, pmcsc);
3310 /******************************************************************************
3314 Send SMP request down for processing.
3316 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3319 ******************************************************************************/
3320 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3324 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3326 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3327 pccb = pmcsc->smpSendHead;
3329 /* if link is down, do nothing */
3330 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3332 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3333 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3337 /* clear send queue */
3338 pmcsc->smpSendHead = NULL;
3339 pmcsc->smpSendTail = NULL;
3340 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3342 /* send all ccbs down */
3348 pccb_next = pccb->pccbNext;
3349 pccb->pccbNext = NULL;
3353 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3358 if (!pccb->devHandle)
3360 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3364 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3365 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3366 pccb, pccb->retryCount );
3367 status = tiINISMPStart( &pmcsc->tiRoot,
3371 (void *)&pccb->tdIOReqBody,
3372 tiInterruptContext);
3379 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3381 /* pending ccb back to send queue */
3382 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3383 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3386 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3388 pccb->ccbStatus = tiSMPFailed;
3389 agtiapi_SMPDone(pmcsc, pccb);
3392 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3394 pccb->ccbStatus = tiSMPFailed;
3395 agtiapi_SMPDone(pmcsc, pccb);
3401 /* some SMP requests might have been completed */
3402 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3407 #if __FreeBSD_version > 901000
3408 /******************************************************************************
3409 agtiapi_PrepareSMPSGList()
3412 This function prepares scatter-gather list for the given ccb
3414 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3415 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3421 ******************************************************************************/
3422 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3424 /* Pointer to CAM's ccb */
3425 union ccb *ccb = pccb->ccb;
3426 struct ccb_smpio *csmpio = &ccb->smpio;
3427 struct ccb_hdr *ccbh = &ccb->ccb_h;
3429 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3430 switch((ccbh->flags & CAM_DATA_MASK))
3432 case CAM_DATA_PADDR:
3433 case CAM_DATA_SG_PADDR:
3434 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3435 ccb->ccb_h.status = CAM_REQ_INVALID;
3441 * Currently we do not support Multiple SG list
3442 * return error for now
3444 if ( (csmpio->smp_request_sglist_cnt > 1)
3445 || (csmpio->smp_response_sglist_cnt > 1) )
3447 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3448 ccb->ccb_h.status = CAM_REQ_INVALID;
3453 if ( csmpio->smp_request_sglist_cnt != 0 )
3456 * Virtual address that needs to translated into
3457 * one or more physical address ranges.
3460 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3461 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3462 error = bus_dmamap_load( pmcsc->buffer_dmat,
3464 csmpio->smp_request,
3465 csmpio->smp_request_len,
3466 agtiapi_PrepareSMPSGListCB,
3468 BUS_DMA_NOWAIT /* 0 */ );
3470 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3472 if (error == EINPROGRESS)
3475 * So as to maintain ordering,
3476 * freeze the controller queue
3477 * until our mapping is
3480 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3481 xpt_freeze_simq( pmcsc->sim, 1 );
3482 pmcsc->SimQFrozen = agTRUE;
3483 ccbh->status |= CAM_RELEASE_SIMQ;
3486 if( csmpio->smp_response_sglist_cnt != 0 )
3489 * Virtual address that needs to translated into
3490 * one or more physical address ranges.
3493 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3494 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3495 error = bus_dmamap_load( pmcsc->buffer_dmat,
3497 csmpio->smp_response,
3498 csmpio->smp_response_len,
3499 agtiapi_PrepareSMPSGListCB,
3501 BUS_DMA_NOWAIT /* 0 */ );
3503 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3505 if ( error == EINPROGRESS )
3508 * So as to maintain ordering,
3509 * freeze the controller queue
3510 * until our mapping is
3513 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3514 xpt_freeze_simq( pmcsc->sim, 1 );
3515 pmcsc->SimQFrozen = agTRUE;
3516 ccbh->status |= CAM_RELEASE_SIMQ;
3522 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3523 (csmpio->smp_response_sglist_cnt == 0) )
3525 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3526 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3527 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3528 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3530 // 0xFF to be defined
3531 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3533 pccb->tiSMPFrame.flag = 0;
3540 /******************************************************************************
3541 agtiapi_PrepareSMPSGList()
3544 This function prepares scatter-gather list for the given ccb
3546 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3547 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3553 ******************************************************************************/
3554 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3556 /* Pointer to CAM's ccb */
3557 union ccb *ccb = pccb->ccb;
3558 struct ccb_smpio *csmpio = &ccb->smpio;
3559 struct ccb_hdr *ccbh = &ccb->ccb_h;
3561 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3563 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3565 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3566 "not supported\n" );
3567 ccb->ccb_h.status = CAM_REQ_INVALID;
3572 if (ccbh->flags & CAM_SCATTER_VALID)
3575 * Currently we do not support Multiple SG list
3576 * return error for now
3578 if ( (csmpio->smp_request_sglist_cnt > 1)
3579 || (csmpio->smp_response_sglist_cnt > 1) )
3581 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3582 "not supported\n" );
3583 ccb->ccb_h.status = CAM_REQ_INVALID;
3587 if ( csmpio->smp_request_sglist_cnt != 0 )
3590 * Virtual address that needs to translated into
3591 * one or more physical address ranges.
3594 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3595 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3596 error = bus_dmamap_load( pmcsc->buffer_dmat,
3598 csmpio->smp_request,
3599 csmpio->smp_request_len,
3600 agtiapi_PrepareSMPSGListCB,
3602 BUS_DMA_NOWAIT /* 0 */ );
3604 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3606 if (error == EINPROGRESS)
3609 * So as to maintain ordering,
3610 * freeze the controller queue
3611 * until our mapping is
3614 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3615 xpt_freeze_simq( pmcsc->sim, 1 );
3616 pmcsc->SimQFrozen = agTRUE;
3617 ccbh->status |= CAM_RELEASE_SIMQ;
3620 if( csmpio->smp_response_sglist_cnt != 0 )
3623 * Virtual address that needs to translated into
3624 * one or more physical address ranges.
3627 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3628 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3629 error = bus_dmamap_load( pmcsc->buffer_dmat,
3631 csmpio->smp_response,
3632 csmpio->smp_response_len,
3633 agtiapi_PrepareSMPSGListCB,
3635 BUS_DMA_NOWAIT /* 0 */ );
3637 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3639 if ( error == EINPROGRESS )
3642 * So as to maintain ordering,
3643 * freeze the controller queue
3644 * until our mapping is
3647 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3648 xpt_freeze_simq( pmcsc->sim, 1 );
3649 pmcsc->SimQFrozen = agTRUE;
3650 ccbh->status |= CAM_RELEASE_SIMQ;
3656 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3657 (csmpio->smp_response_sglist_cnt == 0) )
3659 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3660 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3661 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3662 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3664 // 0xFF to be defined
3665 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3667 pccb->tiSMPFrame.flag = 0;
3674 /******************************************************************************
3675 agtiapi_PrepareSMPSGListCB()
3678 Callback function for bus_dmamap_load()
3679 This fuctions sends IO to LL layer.
3681 void *arg (IN) Pointer to the HBA data structure
3682 bus_dma_segment_t *segs (IN) Pointer to dma segment
3683 int nsegs (IN) number of dma segment
3684 int error (IN) error
3687 ******************************************************************************/
3688 static void agtiapi_PrepareSMPSGListCB( void *arg,
3689 bus_dma_segment_t *segs,
3694 union ccb *ccb = pccb->ccb;
3695 struct agtiapi_softc *pmcsc;
3696 U32 TID = CMND_TO_TARGET(ccb);
3698 tiDeviceHandle_t *tiExpDevHandle;
3699 tiPortalContext_t *tiExpPortalContext;
3700 ag_portal_info_t *tiExpPortalInfo;
3702 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3704 pmcsc = pccb->pmcsc;
3706 if ( error != tiSuccess )
3708 if (error == 0xAABBCCDD)
3714 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3716 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3717 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3718 agtiapi_FreeCCB( pmcsc, pccb );
3719 ccb->ccb_h.status = CAM_REQ_CMP;
3725 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3727 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3728 "AGTIAPI_MAX_DMA_SEGS %d\n",
3729 nsegs, AGTIAPI_MAX_DMA_SEGS );
3730 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3731 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3732 agtiapi_FreeCCB( pmcsc, pccb );
3733 ccb->ccb_h.status = CAM_REQ_CMP;
3739 * If assigned pDevHandle is not available
3740 * then there is no need to send it to StartIO()
3742 /* TODO: Add check for deviceType */
3743 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3745 agtiapi_FreeCCB( pmcsc, pccb );
3746 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3751 TID = INDEX( pmcsc, pccb->targetId );
3752 if ( (TID >= pmcsc->devDiscover) ||
3753 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3755 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3756 "target %d tid %d/%d "
3757 "card %p ERROR pccb %p\n",
3764 agtiapi_FreeCCB( pmcsc, pccb );
3765 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3770 /* TODO: add indirect handling */
3771 /* set the flag correctly based on Indiret SMP request and responce */
3773 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3774 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3776 pccb->targetId, TID,
3779 tiExpDevHandle = pccb->devHandle;
3780 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3781 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3782 /* Look for the expander associated with the ses device */
3783 status = tiINIGetExpander( &pmcsc->tiRoot,
3788 if ( status != tiSuccess )
3790 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3792 agtiapi_FreeCCB( pmcsc, pccb );
3793 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3799 /* this is expander device */
3800 pccb->devHandle = tiExpDevHandle;
3801 /* put the request in send queue */
3802 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3803 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3805 agtiapi_StartSMP( pmcsc );
3811 /******************************************************************************
3815 Processing completed ccbs
3817 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3818 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3821 ******************************************************************************/
3822 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3824 pccb_t pccb_curr = pccb;
3827 tiIniScsiCmnd_t *cmnd;
3830 AGTIAPI_IO("agtiapi_Done: start\n");
3833 /* start from 1st ccb in the chain */
3834 pccb_next = pccb_curr->pccbNext;
3836 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3838 /* send command back and release the ccb */
3839 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3841 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3843 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3844 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3848 CMND_DMA_UNMAP(pmcsc, ccb);
3850 /* send the request back to the CAM */
3851 ccb = pccb_curr->ccb;
3852 agtiapi_FreeCCB(pmcsc, pccb_curr);
3855 pccb_curr = pccb_next;
3860 /******************************************************************************
3864 Processing completed ccbs
3866 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3867 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3871 ******************************************************************************/
3872 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3874 pccb_t pccb_curr = pccb;
3879 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3883 /* start from 1st ccb in the chain */
3884 pccb_next = pccb_curr->pccbNext;
3886 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3888 CMND_DMA_UNMAP(pmcsc, ccb);
3890 /* send the request back to the CAM */
3891 ccb = pccb_curr->ccb;
3892 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3896 pccb_curr = pccb_next;
3899 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3903 /******************************************************************************
3907 Utility function for dumping in hex
3909 const char *ptitle (IN) A string to be printed
3910 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3911 int len (IN) The lengther of the buffer
3914 ******************************************************************************/
3915 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3918 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3921 AGTIAPI_PRINTK("pbuf is NULL\n");
3924 for (i = 0; i < len; )
3928 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3929 pbuf[i+2], pbuf[i+3] );
3934 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3938 AGTIAPI_PRINTK("\n");
3942 /******************************************************************************
3943 agtiapi_CheckError()
3946 Processes status pertaining to the ccb -- whether it was
3947 completed successfully, aborted, or error encountered.
3949 ag_card_t *pCard (IN) Pointer to HBA data structure
3950 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3952 0 - the command retry is required
3953 1 - the command process is completed
3956 ******************************************************************************/
3957 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3959 ag_device_t *pDevice;
3960 // union ccb * ccb = pccb->ccb;
3968 AGTIAPI_IO("agtiapi_CheckError: start\n");
3971 /* shouldn't be here but just in case we do */
3972 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3973 agtiapi_FreeCCB(pmcsc, pccb);
3979 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3981 if (pmcsc->pWWNList != NULL)
3983 TID = INDEX(pmcsc, pccb->targetId);
3984 if (TID < maxTargets)
3986 pDevice = &pmcsc->pDevList[TID];
3987 if (pDevice != NULL)
3996 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3997 agtiapi_FreeCCB(pmcsc, pccb);
4002 ccb->csio.scsi_status = pccb->scsiStatus;
4004 if(pDevice->CCBCount > 0){
4005 atomic_subtract_int(&pDevice->CCBCount,1);
4007 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4008 if(pmcsc->freezeSim == agTRUE)
4010 pmcsc->freezeSim = agFALSE;
4011 xpt_release_simq(pmcsc->sim, 1);
4013 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4015 switch (pccb->ccbStatus)
4018 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
4020 if (pccb->scsiStatus == SCSI_STATUS_OK)
4022 ccb->ccb_h.status = CAM_REQ_CMP;
4025 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4027 ccb->ccb_h.status = CAM_REQ_ABORTED;
4031 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4033 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4035 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4041 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4042 /* resid is ignored for this condition */
4043 ccb->csio.resid = 0;
4044 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4047 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4048 ccb->csio.resid = pccb->scsiStatus;
4049 ccb->ccb_h.status = CAM_REQ_CMP;
4050 ccb->csio.scsi_status = SCSI_STATUS_OK;
4054 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4055 pccb, pccb->scsiStatus, pccb->targetId );
4056 if (pccb->scsiStatus == tiDeviceBusy)
4058 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4060 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4061 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4062 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4064 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4065 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4068 else if(pccb->scsiStatus == tiBusy)
4070 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4071 if(pmcsc->freezeSim == agFALSE)
4073 pmcsc->freezeSim = agTRUE;
4074 xpt_freeze_simq(pmcsc->sim, 1);
4076 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4077 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4078 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4080 else if (pccb->scsiStatus == tiDetailNoLogin)
4082 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4083 "tiDetailNoLogin ERROR\n", pccb );
4084 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4086 else if (pccb->scsiStatus == tiDetailNotValid)
4088 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4089 "tiDetailNotValid ERROR\n", pccb );
4090 ccb->ccb_h.status = CAM_REQ_INVALID;
4092 else if (pccb->scsiStatus == tiDetailAbortLogin)
4094 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4095 "tiDetailAbortLogin ERROR\n", pccb );
4096 ccb->ccb_h.status = CAM_REQ_ABORTED;
4098 else if (pccb->scsiStatus == tiDetailAbortReset)
4100 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4101 "tiDetailAbortReset ERROR\n", pccb );
4102 ccb->ccb_h.status = CAM_REQ_ABORTED;
4104 else if (pccb->scsiStatus == tiDetailAborted)
4106 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4107 "tiDetailAborted ERROR\n", pccb );
4108 ccb->ccb_h.status = CAM_REQ_ABORTED;
4110 else if (pccb->scsiStatus == tiDetailOtherError)
4112 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4113 "tiDetailOtherError ERROR\n", pccb );
4114 ccb->ccb_h.status = CAM_REQ_ABORTED;
4118 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4119 pccb, pccb->scsiStatus, pccb->targetId );
4120 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4122 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4123 "tiDetailDifAppTagMismatch\n", pccb );
4124 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4126 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4128 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4129 "tiDetailDifRefTagMismatch\n", pccb );
4130 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4132 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4134 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4135 "tiDetailDifCrcMismatch\n", pccb );
4136 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4139 #ifdef HIALEAH_ENCRYPTION
4140 case tiIOEncryptError:
4141 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4142 pccb, pccb->scsiStatus, pccb->targetId );
4143 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4145 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4146 "tiDetailDekKeyCacheMiss ERROR\n",
4147 __FUNCTION__, pccb );
4148 ccb->ccb_h.status = CAM_REQ_ABORTED;
4149 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4151 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4153 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4154 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4155 ccb->ccb_h.status = CAM_REQ_ABORTED;
4156 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4161 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4162 pccb, pccb->ccbStatus, pccb->targetId );
4163 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4171 /******************************************************************************
4172 agtiapi_SMPCheckError()
4175 Processes status pertaining to the ccb -- whether it was
4176 completed successfully, aborted, or error encountered.
4178 ag_card_t *pCard (IN) Pointer to HBA data structure
4179 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4181 0 - the command retry is required
4182 1 - the command process is completed
4185 ******************************************************************************/
4186 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4188 union ccb * ccb = pccb->ccb;
4190 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4194 /* shouldn't be here but just in case we do */
4195 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4197 agtiapi_FreeSMPCCB(pmcsc, pccb);
4201 switch (pccb->ccbStatus)
4204 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4207 ccb->ccb_h.status = CAM_REQ_CMP;
4210 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4213 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4216 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4221 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4230 /******************************************************************************
4231 agtiapi_HandleEncryptedIOFailure():
4238 ******************************************************************************/
4239 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4242 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4246 /******************************************************************************
4252 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4253 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4257 ******************************************************************************/
4258 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4261 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4262 pccb->ccbStatus = 0;
4263 pccb->scsiStatus = 0;
4264 pccb->startTime = ticks;
4266 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4267 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4268 pccb->retryCount, pccb->flags );
4270 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4271 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4276 /******************************************************************************
4280 Dump CCB for debuging
4282 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4285 ******************************************************************************/
4286 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4288 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4293 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4298 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4299 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4300 pccb->numSgElements);
4301 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4304 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4305 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4306 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4307 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4308 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4309 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4310 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4311 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4312 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4313 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4314 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4315 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4316 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4317 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4318 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4320 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4321 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4322 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4323 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4324 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4325 pccb->tiSuperScsiRequest.agSgl1.upper,
4326 pccb->tiSuperScsiRequest.agSgl1.lower,
4327 pccb->tiSuperScsiRequest.agSgl1.len,
4328 pccb->tiSuperScsiRequest.agSgl1.type);
4331 /******************************************************************************
4332 agtiapi_eh_HostReset()
4335 A new error handler of Host Reset command.
4337 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4342 ******************************************************************************/
4343 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4345 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4350 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4351 return tiInvalidHandle;
4355 agtiapi_LogEvent( pmcsc,
4356 IOCTL_EVT_SEV_INFORMATIONAL,
4360 "agtiapi_eh_HostReset! " );
4363 return agtiapi_DoSoftReset( pmcsc );
4367 int agtiapi_eh_DeviceReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4369 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4374 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4375 return tiInvalidHandle;
4377 return agtiapi_DoSoftReset( pmcsc );
4379 /******************************************************************************
4383 Put ccb in ccb queue at the tail
4385 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4386 pccb_t *phead (IN) Double pointer to ccb queue head
4387 pccb_t *ptail (IN) Double pointer to ccb queue tail
4388 ccb_t *pccb (IN) Poiner to a ccb to be queued
4391 Put the ccb to the tail of queue
4392 ******************************************************************************/
4393 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4396 #ifdef AGTIAPI_LOCAL_LOCK
4401 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4402 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4403 if (phead == NULL || ptail == NULL)
4405 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4407 pccb->pccbNext = NULL;
4408 AG_LOCAL_LOCK( mutex );
4411 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4416 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4418 (*ptail)->pccbNext = pccb;
4421 AG_LOCAL_UNLOCK( mutex );
4426 /******************************************************************************
4437 ******************************************************************************/
4438 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4440 pccb_t pccb = agNULL; /* call dequeue */
4441 int status = tiSuccess;
4442 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4444 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4447 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4449 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4450 ccb->ccb_h.status = CAM_REQ_CMP;
4454 pccb->pmcsc = pmcsc;
4456 /* initialize Command Control Block (CCB) */
4457 pccb->targetId = targetID;
4458 pccb->ccb = ccb; /* for struct scsi_cmnd */
4460 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4462 if (status != tiSuccess)
4464 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4465 agtiapi_FreeCCB(pmcsc, pccb);
4466 if (status == tiReject)
4468 ccb->ccb_h.status = CAM_REQ_INVALID;
4472 ccb->ccb_h.status = CAM_REQ_CMP;
4481 /******************************************************************************
4482 agtiapi_SetLunField()
4485 Set LUN field based on different address mode
4487 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4490 ******************************************************************************/
4491 void agtiapi_SetLunField(ccb_t *pccb)
4495 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4497 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4499 switch (pccb->addrMode)
4501 case AGTIAPI_PERIPHERAL:
4503 *pchar = (U08)pccb->lun;
4505 case AGTIAPI_VOLUME_SET:
4506 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4507 (U08)((pccb->lun >> 8) & 0x3F);
4508 *pchar = (U08)pccb->lun;
4510 case AGTIAPI_LUN_ADDR:
4511 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4513 *pchar = (U08)pccb->lun;
4521 /*****************************************************************************
4525 Free a ccb and put it back to ccbFreeList.
4527 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4528 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4532 *****************************************************************************/
4533 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4535 union ccb *ccb = pccb->ccb;
4536 bus_dmasync_op_t op;
4538 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4539 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4541 #ifdef AGTIAPI_TEST_EPL
4542 tiEncrypt_t *encrypt;
4545 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4547 if (pccb->sgList != agNULL)
4549 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4553 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4556 /* set data transfer direction */
4557 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4559 op = BUS_DMASYNC_POSTWRITE;
4563 op = BUS_DMASYNC_POSTREAD;
4566 if (pccb->numSgElements == 0)
4569 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4571 else if (pccb->numSgElements == 1)
4573 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4574 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4575 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4576 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4580 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4581 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4582 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4583 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4586 #ifdef AGTIAPI_TEST_DPL
4587 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4589 memset( (char *) pccb->dplPtr,
4591 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4592 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4593 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4594 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4598 #ifdef AGTIAPI_TEST_EPL
4599 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4600 if (encrypt->enableEncryptionPerLA == TRUE) {
4601 encrypt->enableEncryptionPerLA = FALSE;
4602 encrypt->EncryptionPerLAAddrLo = 0;
4603 encrypt->EncryptionPerLAAddrHi = 0;
4607 #ifdef ENABLE_SATA_DIF
4608 if (pccb->holePtr && pccb->dmaHandleHole)
4609 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4612 pccb->dmaHandleHole );
4614 pccb->dmaHandleHole = 0;
4618 pccb->retryCount = 0;
4619 pccb->ccbStatus = 0;
4620 pccb->scsiStatus = 0;
4621 pccb->startTime = 0;
4622 pccb->dmaHandle = 0;
4623 pccb->numSgElements = 0;
4624 pccb->tiIORequest.tdData = 0;
4625 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4627 #ifdef HIALEAH_ENCRYPTION
4629 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4634 pccb->pccbIO = NULL;
4635 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4636 pmcsc->ccbFreeList = (caddr_t *)pccb;
4640 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4645 /******************************************************************************
4649 Flush all in processed ccbs.
4651 ag_card_t *pCard (IN) Pointer to HBA data structure
4652 U32 flag (IN) Flag to call back
4655 ******************************************************************************/
4656 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4661 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4662 for( pccb = (pccb_t)pCard->ccbChainList;
4664 pccb = pccb->pccbChainNext ) {
4665 if( pccb->flags == 0 )
4667 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4671 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4673 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4674 agtiapi_FreeTMCCB( pCard, pccb );
4678 if ( pccb->flags & TAG_SMP )
4680 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4681 agtiapi_FreeSMPCCB( pCard, pccb );
4685 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4686 agtiapi_FreeCCB( pCard, pccb );
4689 CMND_DMA_UNMAP( pCard, ccb );
4690 if( flag == AGTIAPI_CALLBACK ) {
4691 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4699 /*****************************************************************************
4700 agtiapi_FreeSMPCCB()
4703 Free a ccb and put it back to ccbFreeList.
4705 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4706 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4710 *****************************************************************************/
4711 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4713 union ccb *ccb = pccb->ccb;
4714 bus_dmasync_op_t op;
4716 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4717 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4719 /* set data transfer direction */
4720 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4722 op = BUS_DMASYNC_POSTWRITE;
4726 op = BUS_DMASYNC_POSTREAD;
4729 if (pccb->numSgElements == 0)
4732 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4734 else if (pccb->numSgElements == 1)
4736 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4737 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4738 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4739 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4743 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4744 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4745 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4746 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4749 /*dma api cleanning*/
4751 pccb->retryCount = 0;
4752 pccb->ccbStatus = 0;
4753 pccb->startTime = 0;
4754 pccb->dmaHandle = 0;
4755 pccb->numSgElements = 0;
4756 pccb->tiIORequest.tdData = 0;
4757 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4761 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4762 pmcsc->ccbFreeList = (caddr_t *)pccb;
4766 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4771 /*****************************************************************************
4775 Free a ccb and put it back to ccbFreeList.
4777 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4778 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4782 *****************************************************************************/
4783 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4785 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4786 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4788 pccb->retryCount = 0;
4789 pccb->ccbStatus = 0;
4790 pccb->scsiStatus = 0;
4791 pccb->startTime = 0;
4792 pccb->dmaHandle = 0;
4793 pccb->numSgElements = 0;
4794 pccb->tiIORequest.tdData = 0;
4795 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4798 pccb->pccbIO = NULL;
4799 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4800 pmcsc->ccbFreeList = (caddr_t *)pccb;
4802 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4805 /******************************************************************************
4806 agtiapi_CheckAllVectors():
4812 Currently, not used.
4813 ******************************************************************************/
4814 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4816 #ifdef SPC_MSIX_INTR
4817 if (!agtiapi_intx_mode)
4821 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4822 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4823 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4826 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4827 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4829 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4830 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4836 /******************************************************************************
4840 Check call back function returned event for process completion
4842 struct agtiapi_softc *pCard Pointer to card data structure
4843 U32 milisec (IN) Waiting time for expected event
4844 U32 flag (IN) Flag of the event to check
4845 U32 *pStatus (IN) Pointer to status of the card or port to check
4847 AGTIAPI_SUCCESS - event comes as expected
4848 AGTIAPI_FAIL - event not coming
4851 ******************************************************************************/
4852 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4855 volatile U32 *pStatus )
4857 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4858 initiatorOption.usecsPerTick / 1000;
4859 S32 i = milisec/msecsPerTick;
4860 AG_GLOBAL_ARG( _flags );
4862 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4863 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4869 if (*pStatus & TASK_MANAGEMENT)
4871 if (*pStatus & AGTIAPI_CB_DONE)
4873 if( flag == 0 || *pStatus & flag )
4874 return AGTIAPI_SUCCESS;
4876 return AGTIAPI_FAIL;
4879 else if (pCard->flags & AGTIAPI_CB_DONE)
4881 if( flag == 0 || *pStatus & flag )
4882 return AGTIAPI_SUCCESS;
4884 return AGTIAPI_FAIL;
4887 agtiapi_DelayMSec( msecsPerTick );
4889 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4890 tiCOMTimerTick( &pCard->tiRoot );
4892 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4893 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4898 if( *pStatus & TASK_MANAGEMENT )
4899 *pStatus |= TASK_TIMEOUT;
4901 return AGTIAPI_FAIL;
4905 /******************************************************************************
4906 agtiapi_DiscoverTgt()
4909 Discover available devices
4911 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4914 ******************************************************************************/
4915 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4918 ag_portal_data_t *pPortalData;
4921 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4922 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4923 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4925 pPortalData = pCard->pPortalData;
4926 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4928 pCard->flags &= ~AGTIAPI_CB_DONE;
4929 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4931 if (pCard->flags & AGTIAPI_INIT_TIME)
4933 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4934 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4936 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4938 pPortalData, count );
4940 * There is no need to spend time on discovering device
4941 * if port is not ready to do so.
4950 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4952 AGTIAPI_INIT_DELAY(1000);
4954 pCard->flags &= ~AGTIAPI_CB_DONE;
4955 if (tiINIDiscoverTargets(&pCard->tiRoot,
4956 &pPortalData->portalInfo.tiPortalContext,
4957 FORCE_PERSISTENT_ASSIGN_MASK)
4959 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4962 * Should wait till discovery completion to start
4963 * next portal. However, lower layer have issue on
4964 * multi-portal case under Linux.
4968 pPortalData = pCard->pPortalData;
4969 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4971 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4973 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4974 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4976 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4977 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4980 PORTAL_STATUS(pPortalData) );
4982 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4983 "completed, status 0x%x\n",
4984 pPortalData, PORTAL_STATUS(pPortalData) );
4987 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4994 * Calling to get device handle should be done per portal based
4995 * and better right after discovery is done. However, lower iscsi
4996 * layer may not returns discovery complete in correct sequence or we
4997 * ran out time. We get device handle for all portals together
4998 * after discovery is done or timed out.
5000 pPortalData = pCard->pPortalData;
5001 for (count = 0; count < pCard->portCount; count++, pPortalData++)
5004 * We try to get device handle no matter
5005 * if discovery is completed or not.
5007 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
5011 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
5013 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
5015 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
5018 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
5019 (pCard->tgtCount > 0))
5020 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
5021 AGTIAPI_PORT_LINK_UP );
5031 /******************************************************************************
5035 Prepares CCB including DMA map.
5037 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5038 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5040 U32 max_ccb (IN) count
5044 ******************************************************************************/
5045 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5059 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5060 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5061 nsegs = AGTIAPI_NSEGS;
5062 sgl_sz = sizeof(tiSgl_t) * nsegs;
5063 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5064 "%lu, max_ccb %d\n",
5071 ccb_sz = (AGTIAPI_CCB_SIZE + cache_line_size() - 1) & ~(cache_line_size() -1);
5072 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5074 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5076 memset((void *)hdr, 0, size);
5077 hdr->next = pCard->ccbAllocList;
5078 pCard->ccbAllocList = hdr;
5080 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5082 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5084 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5086 pccb->tiIORequest.osData = (void *)pccb;
5089 * Initially put all the ccbs on the free list
5090 * in addition to chainlist.
5091 * ccbChainList is a list of all available ccbs
5092 * (free/active everything)
5094 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5095 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5097 pCard->ccbChainList = (caddr_t *)pccb;
5098 pCard->ccbFreeList = (caddr_t *)pccb;
5101 #ifdef AGTIAPI_ALIGN_CHECK
5103 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5104 if (pccb->devHandle & 0x63)
5105 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5106 if (&pccb->lun & 0x63)
5107 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5108 if (&pccb->targetId & 0x63)
5109 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5110 if (&pccb->ccbStatus & 0x63)
5111 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5112 if (&pccb->scsiStatus & 0x63)
5113 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5114 if (&pccb->dataLen & 0x63)
5115 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5116 if (&pccb->senseLen & 0x63)
5117 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5118 if (&pccb->numSgElements & 0x63)
5119 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5120 if (&pccb->retryCount & 0x63)
5121 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5122 if (&pccb->flags & 0x63)
5123 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5124 if (&pccb->pSenseData & 0x63)
5125 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5126 if (&pccb->sgList[0] & 0x63)
5127 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5128 if (&pccb->pccbNext & 0x63)
5129 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5130 if (&pccb->pccbChainNext & 0x63)
5131 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5132 if (&pccb->cmd & 0x63)
5133 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5134 if( &pccb->startTime & 0x63 )
5135 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5136 if (&pccb->tiIORequest & 0x63)
5137 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5138 if (&pccb->tdIOReqBody & 0x63)
5139 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5140 if (&pccb->tiSuperScsiRequest & 0x63)
5141 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5142 &pccb->tiSuperScsiRequest );
5144 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5147 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5150 /* assigns tiSgl_t memory to pccb */
5151 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5152 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5154 pccb->pccbIO = NULL;
5155 pccb->startTime = 0;
5158 #ifdef AGTIAPI_ALIGN_CHECK
5159 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5164 /******************************************************************************
5168 Create and initialize per card based CCB pool.
5170 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5171 int tgtCount (IN) Count
5173 Total number of ccb allocated
5175 ******************************************************************************/
5176 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5179 U32 max_ccb, size, ccb_sz, hdr_sz;
5180 int no_allocs = 0, i;
5183 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5184 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5185 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5187 #ifndef HOTPLUG_SUPPORT
5188 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5191 if (tgtCount > AGSA_MAX_INBOUND_Q)
5192 tgtCount = AGSA_MAX_INBOUND_Q;
5195 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5196 ccb_sz = ( (AGTIAPI_CCB_SIZE + cache_line_size() - 1) &
5197 ~(cache_line_size() -1) );
5198 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5199 size = ccb_sz * max_ccb + hdr_sz;
5201 for (i = 0; i < (1 << no_allocs); i++)
5203 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5206 panic( "agtiapi_InitCCBs: bug!!!\n" );
5210 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5219 #ifdef LINUX_PERBI_SUPPORT
5220 /******************************************************************************
5221 agtiapi_GetWWNMappings()
5224 Get the mappings from target IDs to WWNs, if any.
5225 Store them in the WWN_list array, indexed by target ID.
5226 Leave the devListIndex field blank; this will be filled-in later.
5228 ag_card_t *pCard (IN) Pointer to HBA data structure
5229 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5231 Note: The boot command line parameters are used to load the
5232 mapping information, which is contained in the system
5234 ******************************************************************************/
5235 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5236 ag_mapping_t *pMapList )
5240 ag_tgt_map_t *pWWNList;
5241 ag_slr_map_t *pSLRList;
5242 ag_device_t *pDevList;
5245 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5247 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5249 pWWNList = pCard->pWWNList;
5250 pSLRList = pCard->pSLRList;
5251 pDevList = pCard->pDevList;
5252 pCard->numTgtHardMapped = 0;
5253 devDisc = pCard->devDiscover;
5255 pWWNList[devDisc-1].devListIndex = maxTargets;
5256 pSLRList[devDisc-1].localeNameLen = -2;
5257 pSLRList[devDisc-1].remoteNameLen = -2;
5258 pDevList[devDisc-1].targetId = maxTargets;
5261 * Get the mappings from holding area which contains
5262 * the input of the system file and store them
5263 * in the WWN_list array, indexed by target ID.
5265 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5266 pWWNList[lIdx].flags = 0;
5267 pWWNList[lIdx].devListIndex = maxTargets;
5268 pSLRList[lIdx].localeNameLen = -1;
5269 pSLRList[lIdx].remoteNameLen = -1;
5272 // this is where we would propagate values fed to pMapList
5274 } /* agtiapi_GetWWNMappings */
5279 /******************************************************************************
5280 agtiapi_FindWWNListNext()
5282 finds first available new (unused) wwn list entry
5285 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5286 int lstMax Number of entries in WWNList
5288 index into WWNList indicating available entry space;
5289 if available entry space is not found, return negative value
5290 ******************************************************************************/
5291 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5295 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5297 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5298 pWWNList[lLstIdx].targetLen == 0 )
5300 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5302 pWWNList[lLstIdx].devListIndex,
5303 pWWNList[lLstIdx].targetLen,
5304 pWWNList[lLstIdx].portId,
5313 /******************************************************************************
5314 agtiapi_GetDevHandle()
5317 Get device handle. Handles will be placed in the
5318 devlist array with same order as TargetList provided and
5319 will be mapped to a scsi target id and registered to OS later.
5321 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5322 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5323 U32 eType (IN) Port event
5324 U32 eStatus (IN) Port event status
5326 Number of device handle slot present
5328 The sequence of device handle will match the sequence of taregt list
5329 ******************************************************************************/
5330 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5331 ag_portal_info_t *pPortalInfo,
5335 ag_device_t *pDevice;
5336 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5337 tiDeviceHandle_t **agDev;
5338 int devIdx, szdv, devTotal, cmpsetRtn;
5339 int lDevIndex = 0, lRunScanFlag = FALSE;
5341 tiPortInfo_t portInfT;
5342 ag_device_t lTmpDevice;
5343 ag_tgt_map_t *pWWNList;
5344 ag_slr_map_t *pSLRList;
5349 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5350 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5351 pCard->devDiscover, pCard->tgtCount );
5352 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5353 AGTIAPI_INIT_DELAY( 1000 );
5355 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5356 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5359 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5363 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5364 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5365 if (lDevFlags == NULL)
5367 free((caddr_t)agDev, M_PMC_MDEV);
5368 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5372 pWWNList = pCard->pWWNList;
5373 pSLRList = pCard->pSLRList;
5375 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5376 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5378 // get device handles
5379 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5380 &pPortalInfo->tiPortalContext,
5381 (tiDeviceHandle_t **)agDev,
5382 pCard->devDiscover );
5384 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5385 "status %u card %p pCard->devDiscover %d devTotal %d "
5386 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5387 "AGTIAPI_INIT_TIME %x\n",
5388 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5389 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5390 pPortalInfo->devPrev,
5391 pCard->flags & AGTIAPI_INIT_TIME );
5393 // reset devTotal from any previous runs of this
5394 pPortalInfo->devPrev = devTotal;
5395 pPortalInfo->devTotal = devTotal;
5397 AG_LIST_LOCK( &pCard->devListLock );
5399 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5400 &pPortalInfo->tiPortalContext,
5404 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5408 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5409 if (szdv > pCard->devDiscover)
5411 szdv = pCard->devDiscover;
5414 // reconstructing dev list via comparison of wwn
5416 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5418 if ( agDev[devIdx] != 0 )
5420 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5421 // devIdx, agDev[devIdx] );
5423 // pack temp device structure for tiINIGetDeviceInfo call
5424 pDevice = &lTmpDevice;
5425 pDevice->devType = DIRECT_DEVICE;
5426 pDevice->pCard = (void *)pCard;
5427 pDevice->flags = ACTIVE;
5428 pDevice->pPortalInfo = pPortalInfo;
5429 pDevice->pDevHandle = agDev[devIdx];
5430 pDevice->qbusy = agFALSE;
5432 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5433 // devIdx, pCard->devDiscover, agDev[devIdx] );
5435 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5436 &pDevice->devInfo );
5438 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5439 // sizeof(pDevice->targetName),
5440 // pDevice->devInfo.osAddress1,
5441 // pDevice->devInfo.osAddress2 );
5444 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5446 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5448 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5449 pDevice->targetLen > 0 &&
5450 portInfT.localNameLen > 0 &&
5451 portInfT.remoteNameLen > 0 &&
5452 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5453 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5454 ( portInfT.localNameLen ==
5455 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5456 ( portInfT.remoteNameLen ==
5457 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5458 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5459 pDevice->targetLen ) == 0 &&
5460 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5462 portInfT.localNameLen ) == 0 &&
5463 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5464 portInfT.remoteName,
5465 portInfT.remoteNameLen ) == 0 )
5467 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5468 lDevIndex, devIdx, pPortalInfo->portID );
5470 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5471 ( pPortalInfo->pDevList[lDevIndex] ==
5472 &pCard->pDevList[lDevIndex] ) ) // active
5475 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5476 lDevIndex, devTotal, pPortalInfo->portID );
5477 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5478 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5479 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5480 if ( lReadRm ) // cleared timeout, now remove count for timer
5482 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5484 lDevIndex, pPortalInfo->portID );
5485 atomic_subtract_16( &pCard->rmChkCt, 1 );
5486 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5489 callout_stop( &pCard->devRmTimer );
5495 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5496 lDevIndex, // reactivate now
5497 devTotal, pPortalInfo->portID );
5499 // pDevice going fresh
5500 lRunScanFlag = TRUE; // scan and clear outstanding removals
5502 // pCard->tgtCount++; ##
5503 pDevice->targetId = lDevIndex;
5504 pDevice->portalId = pPortalInfo->portID;
5506 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5507 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5508 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5510 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5511 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5512 AG_LIST_UNLOCK( &pCard->devListLock );
5513 free((caddr_t)lDevFlags, M_PMC_MFLG);
5514 free((caddr_t)agDev, M_PMC_MDEV);
5517 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5518 if ( 0 == lDevFlags[devIdx] )
5520 pPortalInfo->devTotal++;
5521 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5522 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5526 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5527 "status inspect %d %d %d\n",
5528 lDevFlags[devIdx], devIdx, lDevIndex );
5529 pPortalInfo->devTotal++;
5530 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5531 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5537 // end: match this wwn with previous wwn list
5539 // we have an agDev entry, but no pWWNList target for it
5540 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5541 { // flag dev handle not accounted for yet
5542 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5543 // later, get an empty pDevice and map this agDev.
5544 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5545 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5550 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5554 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5555 // "devLstIdx/flags/(WWNL)portId ... \n" );
5556 // review device list for further action needed
5557 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5559 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5561 int lNextDyad; // find next available dyad entry
5563 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5564 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5565 lRunScanFlag = TRUE; // scan and clear outstanding removals
5566 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5568 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5569 pSLRList[lNextDyad].remoteNameLen < 0 )
5573 if ( lNextDyad == pCard->devDiscover )
5575 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5576 AG_LIST_UNLOCK( &pCard->devListLock );
5577 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5578 free( (caddr_t)agDev, M_PMC_MDEV );
5581 // index of new entry
5582 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5583 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5584 lDevIndex, devTotal, pPortalInfo->portID );
5585 if ( 0 > lDevIndex )
5587 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5591 pDevice = &pCard->pDevList[lDevIndex];
5593 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5595 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5597 pDevice->pCard = (void *)pCard;
5598 pDevice->devType = DIRECT_DEVICE;
5600 // begin to populate new WWNList entry
5601 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5602 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5604 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5605 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5606 pWWNList[lDevIndex].devListIndex = lDevIndex;
5607 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5609 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5610 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5611 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5612 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5613 // end of populating new WWNList entry
5615 pDevice->targetId = lDevIndex;
5617 pDevice->flags = ACTIVE;
5618 pDevice->CCBCount = 0;
5619 pDevice->pDevHandle = agDev[devIdx];
5620 agDev[devIdx]->osData = (void*)pDevice;
5622 pDevice->pPortalInfo = pPortalInfo;
5623 pDevice->portalId = pPortalInfo->portID;
5624 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5625 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5628 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5629 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5631 pDevice = &pCard->pDevList[devIdx];
5632 //pDevice->flags &= ~ACTIVE;
5633 if ( ( pDevice->pDevHandle != NULL ||
5634 pPortalInfo->pDevList[devIdx] != NULL ) )
5636 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5638 if (FALSE == lRunScanFlag)
5641 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5642 devIdx, devTotal, pPortalInfo->portID );
5643 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5644 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5645 if ( 0 == cmpsetRtn )
5647 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5652 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5655 // else ... scan coming soon enough anyway, ignore timer for dropout
5658 } // end of for ( devIdx = 0; ...
5660 AG_LIST_UNLOCK( &pCard->devListLock );
5662 free((caddr_t)lDevFlags, M_PMC_MFLG);
5663 free((caddr_t)agDev, M_PMC_MDEV);
5665 if ( TRUE == lRunScanFlag )
5666 agtiapi_clrRmScan( pCard );
5669 } // end agtiapi_GetDevHandle
5671 /******************************************************************************
5677 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5680 ******************************************************************************/
5681 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5684 int bus, tid, lun, card_no;
5687 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5689 bus = cam_sim_path(pmcsc->sim);
5691 tid = CAM_TARGET_WILDCARD;
5692 lun = CAM_LUN_WILDCARD;
5694 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5695 ccb = xpt_alloc_ccb_nowait();
5698 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5701 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5702 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5704 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5709 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5710 pmcsc->dev_scan = agTRUE;
5715 /******************************************************************************
5716 agtiapi_DeQueueCCB()
5719 Remove a ccb from a queue
5721 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5722 pccb_t *phead (IN) Pointer to a head of ccb queue
5723 ccb_t *pccd (IN) Pointer to the ccb to be processed
5725 AGTIAPI_SUCCESS - the ccb is removed from queue
5726 AGTIAPI_FAIL - the ccb is not found from queue
5728 ******************************************************************************/
5730 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5731 #ifdef AGTIAPI_LOCAL_LOCK
5737 U32 status = AGTIAPI_FAIL;
5739 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5741 if (pccb == NULL || *phead == NULL)
5743 return AGTIAPI_FAIL;
5746 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5747 AG_LOCAL_LOCK(lock);
5751 *phead = (*phead)->pccbNext;
5757 pccb->pccbNext = NULL;
5758 status = AGTIAPI_SUCCESS;
5763 while (pccb_curr->pccbNext != NULL)
5765 if (pccb_curr->pccbNext == pccb)
5767 pccb_curr->pccbNext = pccb->pccbNext;
5768 pccb->pccbNext = NULL;
5774 pccb->pccbNext = NULL;
5775 status = AGTIAPI_SUCCESS;
5778 pccb_curr = pccb_curr->pccbNext;
5781 AG_LOCAL_UNLOCK(lock);
5787 STATIC void wwnprintk( unsigned char *name, int len )
5791 for (i = 0; i < len; i++, name++)
5792 AGTIAPI_PRINTK("%02x", *name);
5793 AGTIAPI_PRINTK("\n");
5796 * SAS and SATA behind expander has 8 byte long unique address.
5797 * However, direct connect SATA device use 512 byte unique device id.
5798 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5799 * address of memory that holding ID.
5801 STATIC int wwncpy( ag_device_t *pDevice )
5805 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5806 pDevice->devInfo.osAddress2)
5808 memcpy(pDevice->targetName,
5809 pDevice->devInfo.remoteName,
5810 pDevice->devInfo.osAddress1);
5811 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5812 pDevice->devInfo.remoteAddress,
5813 pDevice->devInfo.osAddress2);
5814 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5815 pDevice->devInfo.osAddress2;
5816 rc = pDevice->targetLen;
5820 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5821 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5828 /******************************************************************************
5829 agtiapi_ReleaseCCBs()
5832 Free all allocated CCB memories for the Host Adapter.
5834 struct agtiapi_softc *pCard (IN) Pointer to HBA data stucture
5837 ******************************************************************************/
5838 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5845 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5847 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5851 #ifdef AGTIAPI_TEST_DPL
5852 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5853 pccb = pccb->pccbChainNext)
5855 if(pccb->dplPtr && pccb->dplDma)
5856 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5860 #ifdef AGTIAPI_TEST_EPL
5861 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5862 pccb = pccb->pccbChainNext)
5864 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5866 pCard->epl_ctx_pool,
5873 while ((hdr = pCard->ccbAllocList) != NULL)
5875 pCard->ccbAllocList = hdr->next;
5876 hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1);
5877 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5878 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5880 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5882 free(hdr, M_PMC_MCCB);
5884 pCard->ccbAllocList = NULL;
5890 /******************************************************************************
5894 Timer tick for tisa common layer
5896 void *data (IN) Pointer to the HBA data structure
5899 ******************************************************************************/
5900 STATIC void agtiapi_TITimer( void *data )
5904 struct agtiapi_softc *pCard;
5906 pCard = (struct agtiapi_softc *)data;
5908 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5909 AG_GLOBAL_ARG( flags );
5911 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5912 loLevelOption.usecsPerTick / USEC_PER_TICK;
5914 if( next_tick == 0 ) /* no timer required */
5916 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5917 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5919 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5921 //add for polling mode
5923 if( agtiapi_polling_mode )
5924 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5926 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5928 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5932 /******************************************************************************
5936 Clears device list entries scheduled for timeout and calls scan
5938 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5939 ******************************************************************************/
5940 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5942 ag_tgt_map_t *pWWNList;
5943 ag_portal_info_t *pPortalInfo;
5944 ag_portal_data_t *pPortalData;
5949 pWWNList = pCard->pWWNList;
5951 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5953 AG_LIST_LOCK( &pCard->devListLock );
5955 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5957 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5960 break; // trim to who cares
5963 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5966 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5967 pCard->pDevList[lIdx].pDevHandle = NULL;
5969 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5970 pPortalInfo = &pPortalData->portalInfo;
5971 pPortalInfo->pDevList[lIdx] = NULL;
5972 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5973 lIdx, pWWNList[lIdx].portId );
5974 atomic_subtract_16( &pCard->rmChkCt, 1 );
5977 AG_LIST_UNLOCK( &pCard->devListLock );
5979 agtiapi_scan( pCard );
5983 /******************************************************************************
5984 agtiapi_devRmCheck()
5987 Timer tick to check for timeout on missing targets
5988 Removes device list entry when timeout is reached
5990 void *data (IN) Pointer to the HBA data structure
5991 ******************************************************************************/
5992 STATIC void agtiapi_devRmCheck( void *data )
5994 struct agtiapi_softc *pCard;
5995 ag_tgt_map_t *pWWNList;
5996 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
6000 pCard = ( struct agtiapi_softc * )data;
6003 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
6007 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
6011 callout_deactivate( &pCard->devRmTimer );
6013 if( pCard->flags & AGTIAPI_SHUT_DOWN )
6015 return; // implicit timer clear
6018 pWWNList = pCard->pWWNList;
6020 AG_LIST_LOCK( &pCard->devListLock );
6021 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6024 if ( callout_pending(&pCard->devRmTimer) == FALSE )
6026 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
6030 AG_LIST_UNLOCK( &pCard->devListLock );
6034 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
6036 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6039 break; // if handled somewhere else, get out
6042 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6045 if ( 1 == lReadRm ) // timed out
6046 { // no decrement of devRemoved as way to leave a clrRmScan marker
6047 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6048 break; // ... so bail out
6052 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6053 lIdx, lReadRm, lReadCt );
6054 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6057 if ( 0 == cmpsetRtn )
6059 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6065 AG_LIST_UNLOCK( &pCard->devListLock );
6067 if ( TRUE == lRunScanFlag )
6068 agtiapi_clrRmScan( pCard );
6072 AG_LIST_UNLOCK( &pCard->devListLock );
6079 static void agtiapi_cam_poll( struct cam_sim *asim )
6084 /*****************************************************************************
6088 Hard or soft reset on the controller and resend any
6089 outstanding requests if needed.
6091 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6092 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6094 AGTIAPI_SUCCESS - reset successful
6095 AGTIAPI_FAIL - reset failed
6097 *****************************************************************************/
6098 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6100 ag_device_t *pDevice;
6104 ag_portal_info_t *pPortalInfo;
6105 ag_portal_data_t *pPortalData;
6109 if( pCard->flags & AGTIAPI_RESET ) {
6110 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6111 return AGTIAPI_FAIL;
6114 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6115 pCard->resetCount );
6117 agtiapi_LogEvent( pCard,
6118 IOCTL_EVT_SEV_INFORMATIONAL,
6122 "Reset initiator time = %d!",
6123 pCard->resetCount + 1 );
6126 pCard->flags |= AGTIAPI_RESET;
6127 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6128 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6129 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6131 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6133 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6135 if( pCard->flags & AGTIAPI_SOFT_RESET )
6137 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6138 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6142 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6145 lFlagVal = AGTIAPI_RESET_SUCCESS;
6146 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6147 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6148 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6150 if( ret == AGTIAPI_FAIL )
6152 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6162 if ( AGTIAPI_FAIL == ret )
6164 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6169 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6173 if( AGTIAPI_FAIL == ret )
6175 printf( "agtiapi_ResetCard: reset ERROR\n" );
6176 pCard->flags &= ~AGTIAPI_INSTALLED;
6177 return AGTIAPI_FAIL;
6180 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6182 // disable all devices
6183 pDevice = pCard->pDevList;
6184 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6186 /* if ( pDevice->flags & ACTIVE )
6188 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6190 pDevice->flags &= ~ACTIVE;
6193 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6194 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6195 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6197 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6199 if( !pCard->pDevList ) { // try to get a little sanity here
6200 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6202 return AGTIAPI_FAIL;
6205 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6206 pCard->tgtCount, pCard->portCount );
6207 pCard->tgtCount = 0;
6211 pCard->flags &= ~AGTIAPI_CB_DONE;
6213 pPortalData = pCard->pPortalData;
6215 for( count = 0; count < pCard->portCount; count++ ) {
6216 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6217 pPortalInfo = &pPortalData->portalInfo;
6218 pPortalInfo->portStatus = 0;
6219 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6220 AGTIAPI_PORT_DISC_READY |
6222 AGTIAPI_DISC_COMPLETE );
6225 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6226 if (szdv > pCard->devDiscover)
6228 szdv = pCard->devDiscover;
6231 for( lIdx = 0, loop = 0;
6232 lIdx < szdv && loop < pPortalInfo->devTotal;
6235 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6239 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6240 // don't erase more as the device is scheduled for removal on DPC
6242 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6243 pDevice, pPortalInfo->pDevList, lIdx );
6244 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6247 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6248 { // we reconstruct dev list later in get dev handle
6249 pPortalInfo->pDevList[lIdx] = NULL;
6252 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6254 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6257 pPortalInfo->portID,
6258 &pPortalInfo->tiPortalContext );
6260 if( tiCOMPortStart( &pCard->tiRoot,
6261 pPortalInfo->portID,
6262 &pPortalInfo->tiPortalContext,
6266 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6267 pPortalInfo->portID );
6271 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6272 pPortalInfo->portID );
6276 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6277 tiCOMGetPortInfo( &pCard->tiRoot,
6278 &pPortalInfo->tiPortalContext,
6279 &pPortalInfo->tiPortInfo );
6282 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6285 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6287 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6289 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6290 "!AGTIAPI_INSTALLED \n" );
6291 return AGTIAPI_FAIL;
6294 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6297 agtiapi_LogEvent( pCard,
6298 IOCTL_EVT_SEV_INFORMATIONAL,
6302 "Reset initiator total device = %d!",
6305 pCard->resetCount++;
6307 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6308 // clear send & done queue
6309 AG_LOCAL_LOCK( &pCard->sendLock );
6310 pCard->ccbSendHead = NULL;
6311 pCard->ccbSendTail = NULL;
6312 AG_LOCAL_UNLOCK( &pCard->sendLock );
6314 AG_LOCAL_LOCK( &pCard->doneLock );
6315 pCard->ccbDoneHead = NULL;
6316 pCard->ccbDoneTail = NULL;
6317 AG_LOCAL_UNLOCK( &pCard->doneLock );
6319 // clear smp queues also
6320 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6321 pCard->smpSendHead = NULL;
6322 pCard->smpSendTail = NULL;
6323 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6325 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6326 pCard->smpDoneHead = NULL;
6327 pCard->smpDoneTail = NULL;
6328 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6330 // finished with all reset stuff, now start things back up
6331 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6332 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6333 pCard->flags |= AGTIAPI_HAD_RESET;
6334 pCard->flags &= ~AGTIAPI_RESET; // ##
6335 agtiapi_StartIO( pCard );
6336 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6337 return AGTIAPI_SUCCESS;
6338 } // agtiapi_ResetCard
6341 /******************************************************************************
6342 agtiapi_ReleaseHBA()
6345 Releases all resources previously acquired to support
6346 a specific Host Adapter, including the I/O Address range,
6347 and unregisters the agtiapi Host Adapter.
6349 device_t dev (IN) - device pointer
6351 always return 0 - success
6353 ******************************************************************************/
6354 int agtiapi_ReleaseHBA( device_t dev )
6357 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6359 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6360 struct ccb_setasync csa;
6361 struct agtiapi_softc *pCard;
6362 pCard = device_get_softc( dev );
6363 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6364 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6366 AG_GLOBAL_ARG(flags);
6368 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6370 if (thisCardInst != pCardInfo)
6372 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6376 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6384 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6385 pCard->flags |= AGTIAPI_SHUT_DOWN;
6389 if (pCard->flags & AGTIAPI_TIMER_ON)
6391 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6392 callout_drain( &pCard->OS_timer );
6393 callout_drain( &pCard->devRmTimer );
6394 callout_drain(&pCard->IO_timer);
6395 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6396 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6399 #ifdef HIALEAH_ENCRYPTION
6400 //Release encryption table memory - Fix it
6401 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6402 //agtiapi_CleanupEncryption(pCard);
6406 * Shutdown the channel so that chip gets frozen
6407 * and it does not do any more pci-bus accesses.
6409 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6411 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6412 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6413 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6415 if (pCard->flags & AGTIAPI_INSTALLED)
6417 tiCOMShutDown( &pCard->tiRoot );
6418 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6422 * first release IRQ, so that we do not get any more interrupts
6425 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6427 if (!agtiapi_intx_mode)
6430 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6432 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6434 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6435 bus_release_resource( dev,
6441 pci_release_msi(dev);
6443 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6448 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6449 tasklet_kill(&pCard->tasklet_dpc[i]);
6451 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6454 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6455 if( pCard->osti_busaddr != 0 ) {
6456 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6458 if( pCard->osti_mem != NULL ) {
6459 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6461 if( pCard->osti_dmat != NULL ) {
6462 bus_dma_tag_destroy( pCard->osti_dmat );
6465 /* unmap the mapped PCI memory */
6466 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6467 agtiapi_ReleasePCIMem(thisCardInst);
6469 /* release all ccbs */
6470 if (pCard->ccbTotal)
6472 //calls bus_dmamap_destroy() for all pccbs
6473 agtiapi_ReleaseCCBs(pCard);
6474 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6477 #ifdef HIALEAH_ENCRYPTION
6478 /*release encryption resources - Fix it*/
6481 /*Check that all IO's are completed */
6482 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6484 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6486 //agtiapi_CleanupEncryptionPools(pCard);
6491 /* release device list */
6492 if( pCard->pDevList ) {
6493 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6494 pCard->pDevList = NULL;
6495 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6497 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6498 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6499 if( pCard->pWWNList ) {
6500 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6501 pCard->pWWNList = NULL;
6502 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6504 if( pCard->pSLRList ) {
6505 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6506 pCard->pSLRList = NULL;
6507 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6511 if (pCard->pPortalData)
6513 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6514 pCard->pPortalData = NULL;
6515 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6517 //calls contigfree() or free()
6518 agtiapi_MemFree(pCardInfo);
6519 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6521 #ifdef HOTPLUG_SUPPORT
6522 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6524 // agtiapi_FreeDevWorkList(pCard);
6525 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6530 * TBD, scsi_unregister may release wrong host data structure
6531 * which cause NULL pointer shows up.
6533 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6535 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6538 #ifdef AGTIAPI_LOCAL_LOCK
6543 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6545 for( i = 0; i < maxLocks; i++ )
6547 mtx_destroy(&pCard->STLock[i]);
6549 free(pCard->STLock, M_PMC_MSTL);
6550 pCard->STLock = NULL;
6557 /* reset agtiapi_1st_time if this is the only card */
6558 if (!ag_card_good && !agtiapi_1st_time)
6560 agtiapi_1st_time = 1;
6563 /* for tiSgl_t memeory */
6564 if (pCard->tisgl_busaddr != 0)
6566 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6568 if (pCard->tisgl_mem != NULL)
6570 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6572 if (pCard->tisgl_dmat != NULL)
6574 bus_dma_tag_destroy(pCard->tisgl_dmat);
6577 if (pCard->buffer_dmat != agNULL)
6579 bus_dma_tag_destroy(pCard->buffer_dmat);
6582 if (pCard->sim != NULL)
6584 mtx_lock(&thisCardInst->pmIOLock);
6585 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6586 csa.ccb_h.func_code = XPT_SASYNC_CB;
6587 csa.event_enable = 0;
6588 csa.callback = agtiapi_async;
6589 csa.callback_arg = pCard;
6590 xpt_action((union ccb *)&csa);
6591 xpt_free_path(pCard->path);
6592 // if (pCard->ccbTotal == 0)
6593 if (pCard->ccbTotal <= thisCard)
6596 no link up so that simq has not been released.
6597 In order to remove cam, we call this.
6599 xpt_release_simq(pCard->sim, 1);
6601 xpt_bus_deregister(cam_sim_path(pCard->sim));
6602 cam_sim_free(pCard->sim, FALSE);
6603 mtx_unlock(&thisCardInst->pmIOLock);
6605 if (pCard->devq != NULL)
6607 cam_simq_free(pCard->devq);
6611 mtx_destroy( &thisCardInst->pmIOLock );
6612 mtx_destroy( &pCard->sendLock );
6613 mtx_destroy( &pCard->doneLock );
6614 mtx_destroy( &pCard->sendSMPLock );
6615 mtx_destroy( &pCard->doneSMPLock );
6616 mtx_destroy( &pCard->ccbLock );
6617 mtx_destroy( &pCard->devListLock );
6618 mtx_destroy( &pCard->OS_timer_lock );
6619 mtx_destroy( &pCard->devRmTimerLock );
6620 mtx_destroy( &pCard->memLock );
6621 mtx_destroy( &pCard->freezeLock );
6623 destroy_dev( pCard->my_cdev );
6624 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6629 // Called during system shutdown after sync
6630 static int agtiapi_shutdown( device_t dev )
6632 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6636 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6638 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6642 static int agtiapi_resume( device_t dev ) // Device resume routine.
6644 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6648 static device_method_t agtiapi_methods[] = { // Device interface
6649 DEVMETHOD( device_probe, agtiapi_probe ),
6650 DEVMETHOD( device_attach, agtiapi_attach ),
6651 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6652 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6653 DEVMETHOD( device_suspend, agtiapi_suspend ),
6654 DEVMETHOD( device_resume, agtiapi_resume ),
6658 static devclass_t pmspcv_devclass;
6660 static driver_t pmspcv_driver = {
6663 sizeof( struct agtiapi_softc )
6666 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6667 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6668 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6670 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6671 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6672 #include <dev/pms/freebsd/driver/common/lxutil.c>
6673 #include <dev/pms/freebsd/driver/common/lxencrypt.c>