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 <dev/pci/pcivar.h> // For pci_get macros
47 #include <dev/pci/pcireg.h>
48 #include <sys/endian.h>
50 #include <sys/mutex.h>
52 #include <sys/queue.h>
53 #include <sys/taskqueue.h>
54 #include <machine/atomic.h>
55 #include <sys/libkern.h>
57 #include <cam/cam_ccb.h>
58 #include <cam/cam_debug.h>
59 #include <cam/cam_periph.h> //
60 #include <cam/cam_sim.h>
61 #include <cam/cam_xpt_sim.h>
62 #include <cam/scsi/scsi_all.h>
63 #include <cam/scsi/scsi_message.h>
64 #include <sys/systm.h>
65 #include <sys/types.h>
66 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
67 #include <dev/pms/freebsd/driver/ini/src/agtiapi.h>
68 #include <dev/pms/freebsd/driver/ini/src/agtiproto.h>
69 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
70 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
71 #include <dev/pms/freebsd/driver/common/lxencrypt.h>
73 MALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" );
75 MALLOC_DEFINE( M_PMC_MSTL, "STLock malloc",
76 "allocated in agtiapi_attach as memory for lock use" );
77 MALLOC_DEFINE( M_PMC_MDVT, "ag_device_t malloc",
78 "allocated in agtiapi_attach as mem for ag_device_t pDevList" );
79 MALLOC_DEFINE( M_PMC_MPRT, "ag_portal_data_t malloc",
80 "allocated in agtiapi_attach as mem for *pPortalData" );
81 MALLOC_DEFINE( M_PMC_MDEV, "tiDeviceHandle_t * malloc",
82 "allocated in agtiapi_GetDevHandle as local mem for **agDev" );
83 MALLOC_DEFINE( M_PMC_MFLG, "lDevFlags * malloc",
84 "allocated in agtiapi_GetDevHandle as local mem for * flags" );
85 #ifdef LINUX_PERBI_SUPPORT
86 MALLOC_DEFINE( M_PMC_MSLR, "ag_slr_map_t malloc",
87 "mem allocated in agtiapi_attach for pSLRList" );
88 MALLOC_DEFINE( M_PMC_MTGT, "ag_tgt_map_t malloc",
89 "mem allocated in agtiapi_attach for pWWNList" );
91 MALLOC_DEFINE(TEMP,"tempbuff","buffer for payload");
92 MALLOC_DEFINE(TEMP2, "tempbuff", "buffer for agtiapi_getdevlist");
93 STATIC U32 agtiapi_intx_mode = 0;
94 STATIC U08 ag_Perbi = 0;
95 STATIC U32 agtiapi_polling_mode = 0;
96 STATIC U32 ag_card_good = 0; // * total card initialized
97 STATIC U32 ag_option_flag = 0; // * adjustable parameter flag
98 STATIC U32 agtiapi_1st_time = 1;
99 STATIC U32 ag_timeout_secs = 10; //Made timeout equivalent to linux
101 U32 gTiDebugLevel = 1;
102 S32 ag_encryption_enable = 0;
103 atomic_t outstanding_encrypted_io_count;
105 #define cache_line_size() CACHE_LINE_SIZE
107 #define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
109 #define CPU_TO_LE32(dst, src) \
110 dst.lower = htole32(LOW_32_BITS(src)); \
111 dst.upper = htole32(HIGH_32_BITS(src))
113 #define CMND_TO_CHANNEL( ccb ) ( ccb->ccb_h.path_id )
114 #define CMND_TO_TARGET( ccb ) ( ccb->ccb_h.target_id )
115 #define CMND_TO_LUN( ccb ) ( ccb->ccb_h.target_lun )
117 STATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] =
118 { AGTIAPI_PERIPHERAL };
120 #ifdef LINUX_PERBI_SUPPORT
121 // Holding area for target-WWN mapping assignments on the boot line
122 static ag_mapping_t *agMappingList = NULL; // modified by agtiapi_Setup()
125 // * For Debugging Purpose
127 #define AGTIAPI_WWN(name, len) wwnprintk(name, len)
129 #define AGTIAPI_WWN(name, len)
133 #define AGTIAPI_WWNPRINTK(name, len, format, a...) \
134 AGTIAPI_PRINTK(format "name ", a); \
135 AGTIAPI_WWN((unsigned char*)name, len);
137 #define AGTIAPI_ERR_WWNPRINTK(name, len, format, a...) \
138 printk(KERN_DEBUG format "name ", ## a); \
139 wwnprintk((unsigned char*)name, len);
140 #define AGTIAPI_CPY_DEV_INFO(root, dev, pDev) \
141 tiINIGetDeviceInfo(root, dev, &pDev->devInfo); \
144 #ifdef AGTIAPI_LOCAL_LOCK
146 #define AG_CARD_LOCAL_LOCK(lock) ,(lock)
147 #define AG_SPIN_LOCK_IRQ(lock, flags)
148 #define AG_SPIN_UNLOCK_IRQ(lock, flags)
149 #define AG_SPIN_LOCK(lock)
150 #define AG_SPIN_UNLOCK(lock)
151 #define AG_GLOBAL_ARG(arg)
152 #define AG_PERF_SPINLOCK(lock)
153 #define AG_PERF_SPINLOCK_IRQ(lock, flags)
156 #define AG_LOCAL_LOCK(lock) if (lock) \
158 #define AG_LOCAL_UNLOCK(lock) if (lock) \
160 #define AG_LOCAL_FLAGS(_flags) unsigned long _flags = 0
164 #define AG_GET_DONE_PCCB(pccb, pmcsc) \
166 AG_LOCAL_LOCK(&pmcsc->doneLock); \
167 pccb = pmcsc->ccbDoneHead; \
170 pmcsc->ccbDoneHead = NULL; \
171 pmcsc->ccbDoneTail = NULL; \
172 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
173 agtiapi_Done(pmcsc, pccb); \
176 AG_LOCAL_UNLOCK(&pmcsc->doneLock); \
179 #define AG_GET_DONE_SMP_PCCB(pccb, pmcsc) \
181 AG_LOCAL_LOCK(&pmcsc->doneSMPLock); \
182 pccb = pmcsc->smpDoneHead; \
185 pmcsc->smpDoneHead = NULL; \
186 pmcsc->smpDoneTail = NULL; \
187 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
188 agtiapi_SMPDone(pmcsc, pccb); \
191 AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \
194 #ifdef AGTIAPI_DUMP_IO_DEBUG
195 #define AG_IO_DUMPCCB(pccb) agtiapi_DumpCCB(pccb)
197 #define AG_IO_DUMPCCB(pccb)
200 #define SCHED_DELAY_JIFFIES 4 /* in seconds */
202 #ifdef HOTPLUG_SUPPORT
203 #define AG_HOTPLUG_LOCK_INIT(lock) mxt_init(lock)
204 #define AG_LIST_LOCK(lock) mtx_lock(lock)
205 #define AG_LIST_UNLOCK(lock) mtx_unlock(lock)
207 #define AG_HOTPLUG_LOCK_INIT(lock)
208 #define AG_LIST_LOCK(lock)
209 #define AG_LIST_UNLOCK(lock)
212 STATIC void agtiapi_CheckIOTimeout(void *data);
216 static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list
217 static void agtiapi_cam_action( struct cam_sim *, union ccb * );
218 static void agtiapi_cam_poll( struct cam_sim * );
220 // Function prototypes
221 static d_open_t agtiapi_open;
222 static d_close_t agtiapi_close;
223 static d_read_t agtiapi_read;
224 static d_write_t agtiapi_write;
225 static d_ioctl_t agtiapi_CharIoctl;
226 static void agtiapi_async(void *callback_arg, u_int32_t code,
227 struct cam_path *path, void *arg);
228 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth);
230 // Character device entry points
231 static struct cdevsw agtiapi_cdevsw = {
232 .d_version = D_VERSION,
233 .d_open = agtiapi_open,
234 .d_close = agtiapi_close,
235 .d_read = agtiapi_read,
236 .d_write = agtiapi_write,
237 .d_ioctl = agtiapi_CharIoctl,
242 U32 ag_portal_count = 0;
244 // In the cdevsw routines, we find our softc by using the si_drv1 member
245 // of struct cdev. We set this variable to point to our softc in our
246 // attach routine when we create the /dev entry.
248 int agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td )
250 struct agtiapi_softc *sc;
251 /* Look up our softc. */
253 AGTIAPI_PRINTK("agtiapi_open\n");
254 AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev);
258 int agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td )
260 struct agtiapi_softc *sc;
263 AGTIAPI_PRINTK("agtiapi_close\n");
264 AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev);
268 int agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag )
270 struct agtiapi_softc *sc;
273 AGTIAPI_PRINTK( "agtiapi_read\n" );
274 AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n",
275 uio->uio_resid, sc->my_dev );
279 int agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag )
281 struct agtiapi_softc *sc;
284 AGTIAPI_PRINTK( "agtiapi_write\n" );
285 AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n",
286 uio->uio_resid, sc->my_dev );
290 int agtiapi_getdevlist( struct agtiapi_softc *pCard,
291 tiIOCTLPayload_t *agIOCTLPayload )
293 tdDeviceListPayload_t *pIoctlPayload =
294 (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea;
295 tdDeviceInfoIOCTL_t *pDeviceInfo = NULL;
296 bit8 *pDeviceInfoOrg;
297 tdsaDeviceData_t *pDeviceData = NULL;
298 tiDeviceHandle_t **devList = NULL;
299 tiDeviceHandle_t **devHandleArray = NULL;
300 tiDeviceHandle_t *pDeviceHandle = NULL;
303 bit32 MaxDeviceCount;
304 bit32 ret_val=IOCTL_CALL_INVALID_CODE;
305 ag_portal_data_t *pPortalData;
306 bit8 *pDeviceHandleList = NULL;
307 AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" );
309 pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo;
310 MaxDeviceCount = pCard->devDiscover;
311 if (MaxDeviceCount > pIoctlPayload->deviceLength )
313 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
314 MaxDeviceCount = pIoctlPayload->deviceLength;
315 ret_val = IOCTL_CALL_FAIL;
317 AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength );
318 memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *),
320 AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount);
321 devList = malloc(memNeeded1, TEMP2, M_WAITOK);
324 AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n");
325 ret_val = IOCTL_CALL_FAIL;
326 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
329 osti_memset(devList, 0, memNeeded1);
330 pPortalData = &pCard->pPortalData[0];
331 pDeviceHandleList = (bit8*)devList;
332 for (total = x = 0; x < pCard->portCount; x++, pPortalData++)
334 count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot,
335 &pPortalData->portalInfo.tiPortalContext,
336 ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount );
337 if (count == DISCOVERY_IN_PROGRESS)
339 AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on "
341 free(devList, TEMP2);
342 ret_val = IOCTL_CALL_FAIL;
343 agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR;
347 pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *);
348 MaxDeviceCount-= count;
350 if (total > pIoctlPayload->deviceLength)
352 total = pIoctlPayload->deviceLength;
354 // dump device information from device handle list
357 devHandleArray = devList;
358 for (x = 0; x < pCard->devDiscover; x++)
360 pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x];
361 if (devList[x] != agNULL)
363 pDeviceData = devList [x]->tdData;
365 pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count);
366 if (pDeviceData != agNULL && pDeviceInfo != agNULL)
368 osti_memcpy( &pDeviceInfo->sasAddressHi,
369 pDeviceData->agDeviceInfo.sasAddressHi,
371 osti_memcpy( &pDeviceInfo->sasAddressLo,
372 pDeviceData->agDeviceInfo.sasAddressLo,
375 pDeviceInfo->sasAddressHi =
376 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
377 pDeviceInfo->sasAddressLo =
378 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
381 pDeviceInfo->deviceType =
382 ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4;
383 pDeviceInfo->linkRate =
384 pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F;
385 pDeviceInfo->phyId = pDeviceData->phyID;
386 pDeviceInfo->ishost = pDeviceData->target_ssp_stp_smp;
387 pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle;
388 if(pDeviceInfo->deviceType == 0x02)
392 tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo);
393 pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi);
394 pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16;
398 pDeviceInfo->sasAddressHi =
399 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi );
400 pDeviceInfo->sasAddressLo =
401 DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo );
404 AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n",
405 pDeviceInfo->deviceType );
406 AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n",
407 pDeviceInfo->linkRate );
408 AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n",
409 pDeviceInfo->phyId );
410 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n",
411 pDeviceInfo->sasAddressHi );
412 AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n",
413 pDeviceInfo->sasAddressHi );
417 AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo "
418 "%p is NULL %d\n", pDeviceData, pDeviceInfo, x );
423 pIoctlPayload->realDeviceCount = count;
424 AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count );
427 free(devList, TEMP2);
429 if(ret_val != IOCTL_CALL_FAIL)
431 ret_val = IOCTL_CALL_SUCCESS;
433 agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK;
437 /******************************************************************************
438 agtiapi_getCardInfo()
441 This function retrives the Card information
446 0 - HBA has been detected
448 ******************************************************************************/
449 int agtiapi_getCardInfo ( struct agtiapi_softc *pCard,
453 CardInfo_t *pCardInfo;
455 pCardInfo = (CardInfo_t *)buffer;
457 pCardInfo->deviceId = pci_get_device(pCard->my_dev);
458 pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ;
459 memcpy( pCardInfo->pciMemBaseSpc,
460 pCard->pCardInfo->pciMemBaseSpc,
461 ((sizeof(U32_64))*PCI_NUMBER_BARS) );
462 pCardInfo->deviceNum = pci_get_slot(pCard->my_dev);
463 pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase;
464 pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow;
465 pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp;
466 pCardInfo->busNum =pci_get_bus(pCard->my_dev);
470 void agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth)
472 struct ccb_relsim crs;
473 xpt_setup_ccb(&crs.ccb_h, path, 5);
474 crs.ccb_h.func_code = XPT_REL_SIMQ;
475 crs.ccb_h.flags = CAM_DEV_QFREEZE;
476 crs.release_flags = RELSIM_ADJUST_OPENINGS;
477 crs.openings = QueueDepth;
478 xpt_action((union ccb *)&crs);
479 if(crs.ccb_h.status != CAM_REQ_CMP) {
480 printf("XPT_REL_SIMQ failed\n");
484 agtiapi_async(void *callback_arg, u_int32_t code,
485 struct cam_path *path, void *arg)
487 struct agtiapi_softc *pmsc;
490 pmsc = (struct agtiapi_softc*)callback_arg;
492 case AC_FOUND_DEVICE:
494 struct ccb_getdev *cgd;
495 cgd = (struct ccb_getdev *)arg;
499 TID = cgd->ccb_h.target_id;
500 if (TID >= 0 && TID < maxTargets){
502 TID = INDEX(pmsc, TID);
503 targ = &pmsc->pDevList[TID];
504 agtiapi_adjust_queue_depth(path, targ->qdepth);
513 /******************************************************************************
517 This function handles the ioctl from application layer
522 0 - HBA has been detected
524 ******************************************************************************/
525 static int agtiapi_CharIoctl( struct cdev *dev,
532 datatosend *load; // structure defined in lxcommon.h
533 tiIOCTLPayload_t *pIoctlPayload;
534 struct agtiapi_softc *pCard;
540 tdDeviceListPayload_t *pDeviceList = NULL;
546 load=(datatosend*)data;
547 pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK);
548 AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize );
549 //Copy payload to kernel buffer, on success it returns 0
550 err = copyin(load->data,pIoctlPayload,load->datasize);
553 status = IOCTL_CALL_FAIL;
556 sema_init(&mx,0,"sem");
557 pCard->pIoctlSem =&mx;
558 pCard->up_count = pCard->down_count = 0;
559 if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST )
561 retValue = agtiapi_getdevlist(pCard, pIoctlPayload);
564 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
565 status = IOCTL_CALL_SUCCESS;
569 pIoctlPayload->Status = IOCTL_CALL_FAIL;
570 status = IOCTL_CALL_FAIL;
572 //update new device length
573 pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea;
574 load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount);
575 AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize );
578 else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO)
580 retValue = agtiapi_getCardInfo( pCard,
581 pIoctlPayload->Length,
582 (pIoctlPayload->FunctionSpecificArea) );
585 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
586 status = IOCTL_CALL_SUCCESS;
590 pIoctlPayload->Status = IOCTL_CALL_FAIL;
591 status = IOCTL_CALL_FAIL;
594 else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT )
596 if ( pCard->flags & AGTIAPI_PORT_PANIC )
598 strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" );
602 strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" );
604 pIoctlPayload->Status = IOCTL_CALL_SUCCESS;
605 status = IOCTL_CALL_SUCCESS;
607 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR )
609 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo);
610 //read port status to see if there is a fatal event
611 if(pCard->flags & AGTIAPI_PORT_PANIC)
613 printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo);
614 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE;
618 AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo);
619 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE;
621 status = IOCTL_CALL_SUCCESS;
623 else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE)
625 AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo);
626 //set flags bit status to be a soft reset
627 pCard->flags |= AGTIAPI_SOFT_RESET;
628 //trigger soft reset for the card
629 retValue = agtiapi_ResetCard (pCard, &flags);
631 if(retValue == AGTIAPI_SUCCESS)
633 //clear port panic status
634 pCard->flags &= ~AGTIAPI_PORT_PANIC;
635 pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG;
636 status = IOCTL_CALL_SUCCESS;
640 pIoctlPayload->Status = IOCTL_CALL_FAIL;
641 status = IOCTL_CALL_FAIL;
646 status = tiCOMMgntIOCTL( &pCard->tiRoot,
651 if (status == IOCTL_CALL_PENDING)
653 ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL);
654 status = IOCTL_CALL_SUCCESS;
657 pCard->pIoctlSem = NULL;
660 //copy kernel buffer to userland buffer
661 err=copyout(pIoctlPayload,load->data,load->datasize);
664 status = IOCTL_CALL_FAIL;
667 free(pIoctlPayload,TEMP);
677 /******************************************************************************
681 This function initialize and registere all detected HBAs.
682 The first function being called in driver after agtiapi_probe()
684 device_t dev (IN) - device pointer
687 0 - HBA has been detected
689 ******************************************************************************/
690 static int agtiapi_probe( device_t dev )
694 ag_card_info_t *thisCardInst;
696 thisCard = device_get_unit( dev );
697 if ( thisCard >= AGTIAPI_MAX_CARDS )
699 device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" );
700 return (ENXIO); // maybe change to different return value?
702 thisCardInst = &agCardInfoList[ thisCard ];
703 retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard );
705 return (ENXIO); // maybe change to different return value?
706 return( BUS_PROBE_DEFAULT ); // successful probe
710 /******************************************************************************
714 This function initialize and registere all detected HBAs.
715 The first function being called in driver after agtiapi_probe()
717 device_t dev (IN) - device pointer
720 0 - HBA has been detected
722 ******************************************************************************/
723 static int agtiapi_attach( device_t devx )
725 // keeping get_unit call to once
726 int thisCard = device_get_unit( devx );
727 struct agtiapi_softc *pmsc;
728 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
729 ag_resource_info_t *pRscInfo;
732 char buffer [256], *pLastUsedChar;
735 struct ccb_setasync csa;
737 AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard);
738 // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values A %p / %p\n",
739 // thisCardInst->pPCIDev, thisCardInst );
740 AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) );
742 TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS", &ag_timeout_secs );
743 TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel );
744 // printf( "agtiapi_attach: debugLevel %d, timeout %d\n",
745 // gTiDebugLevel, ag_timeout_secs );
746 if ( ag_timeout_secs < 1 )
748 ag_timeout_secs = 1; // set minimum timeout value of 1 second
750 ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation
752 // Look up our softc and initialize its fields.
753 pmsc = device_get_softc( devx );
756 /* Get NumberOfPortals */
757 if ((ostiGetTransportParam(
769 ) == tiSuccess) && (lenRecv != 0))
771 if (osti_strncmp(buffer, "0x", 2) == 0)
773 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0);
777 ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10);
779 if (ag_portal_count > AGTIAPI_MAX_PORTALS)
780 ag_portal_count = AGTIAPI_MAX_PORTALS;
784 ag_portal_count = AGTIAPI_MAX_PORTALS;
786 AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count );
787 // initialize hostdata structure
788 pmsc->flags |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED |
790 pmsc->cardNo = thisCard;
792 pmsc->portCount = ag_portal_count;
793 pmsc->pCardInfo = thisCardInst;
794 pmsc->tiRoot.osData = pmsc;
795 pmsc->pCardInfo->pCard = (void *)pmsc;
796 pmsc->VidDid = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx );
797 pmsc->SimQFrozen = agFALSE;
798 pmsc->devq_flag = agFALSE;
799 pRscInfo = &thisCardInst->tiRscInfo;
801 osti_memset(buffer, 0, 256);
805 if ((ostiGetTransportParam(
817 ) == tiSuccess) && (lenRecv != 0))
819 if (osti_strncmp(buffer, "0x", 2) == 0)
821 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
822 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" );
826 maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
827 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" );
834 maxTargets = AGTIAPI_MAX_DEVICE_8H;
835 else if(Is_ADP7H(pmsc))
836 maxTargets = AGTIAPI_MAX_DEVICE_7H;
838 maxTargets = AGTIAPI_MAX_DEVICE;
841 if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE)
843 AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n", maxTargets, AGTIAPI_HW_LIMIT_DEVICE );
844 AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" );
845 maxTargets = AGTIAPI_HW_LIMIT_DEVICE;
847 pmsc->devDiscover = maxTargets ;
849 #ifdef HIALEAH_ENCRYPTION
850 ag_encryption_enable = 1;
851 if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) ==
852 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
855 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
856 printf("agtiapi_attach: Encryption Enabled\n" );
859 // ## for now, skip calls to ostiGetTransportParam(...)
860 // ## for now, skip references to DIF & EDC
862 // Create a /dev entry for this device. The kernel will assign us
863 // a major number automatically. We use the unit number of this
864 // device as the minor number and name the character device
866 pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL,
867 0600, "spcv%u", thisCard );
868 pmsc->my_cdev->si_drv1 = pmsc;
870 mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock",
871 NULL, MTX_DEF|MTX_RECURSE );
873 struct cam_devq *devq;
875 /* set the maximum number of pending IOs */
876 devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH );
879 AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" );
883 struct cam_sim *lsim;
884 lsim = cam_sim_alloc( agtiapi_cam_action,
889 &thisCardInst->pmIOLock,
890 1, // queued per target
891 AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth
893 if ( lsim == NULL ) {
894 cam_simq_free( devq );
895 AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" );
899 pmsc->dev_scan = agFALSE;
900 //one cam sim per scsi bus
901 mtx_lock( &thisCardInst->pmIOLock );
902 if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS )
904 cam_sim_free( lsim, TRUE );
905 mtx_unlock( &thisCardInst->pmIOLock );
906 AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" );
911 bus = cam_sim_path(pmsc->sim);
912 tid = CAM_TARGET_WILDCARD;
913 lun = CAM_LUN_WILDCARD;
914 ccb = xpt_alloc_ccb_nowait();
917 mtx_unlock( &thisCardInst->pmIOLock );
918 cam_sim_free( lsim, TRUE );
919 cam_simq_free( devq );
922 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
923 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
925 mtx_unlock( &thisCardInst->pmIOLock );
926 cam_sim_free( lsim, TRUE );
927 cam_simq_free( devq );
931 pmsc->path = ccb->ccb_h.path;
932 xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5);
933 csa.ccb_h.func_code = XPT_SASYNC_CB;
934 csa.event_enable = AC_FOUND_DEVICE;
935 csa.callback = agtiapi_async;
936 csa.callback_arg = pmsc;
937 xpt_action((union ccb *)&csa);
938 if (csa.ccb_h.status != CAM_REQ_CMP) {
939 AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" );
942 mtx_unlock( &thisCardInst->pmIOLock );
947 // get TD and lower layer memory requirements
948 tiCOMGetResource( &pmsc->tiRoot,
949 &pRscInfo->tiLoLevelResource,
950 &pRscInfo->tiInitiatorResource,
952 &pRscInfo->tiSharedMem );
954 agtiapi_ScopeDMARes( thisCardInst );
955 AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes"
956 " 0x%x \n", pmsc->typhn );
958 // initialize card information and get resource ready
959 if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) {
960 AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n",
964 // begin: allocate and initialize card portal info resource
965 ag_portal_data_t *pPortalData;
966 if (pmsc->portCount == 0)
968 pmsc->pPortalData = NULL;
972 pmsc->pPortalData = (ag_portal_data_t *)
973 malloc( sizeof(ag_portal_data_t) * pmsc->portCount,
974 M_PMC_MPRT, M_ZERO | M_WAITOK );
975 if (pmsc->pPortalData == NULL)
977 AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" );
981 pPortalData = pmsc->pPortalData;
982 for( idx = 0; idx < pmsc->portCount; idx++ ) {
983 pPortalData->pCard = pmsc;
984 pPortalData->portalInfo.portID = idx;
985 pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData;
988 // end: allocate and initialize card portal info resource
990 // begin: enable msix
993 // map to interrupt handler
995 int mesgs = MAX_MSIX_NUM_VECTOR;
998 void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) =
1000 agtiapi_IntrHandler0,
1001 agtiapi_IntrHandler1,
1002 agtiapi_IntrHandler2,
1003 agtiapi_IntrHandler3,
1004 agtiapi_IntrHandler4,
1005 agtiapi_IntrHandler5,
1006 agtiapi_IntrHandler6,
1007 agtiapi_IntrHandler7,
1008 agtiapi_IntrHandler8,
1009 agtiapi_IntrHandler9,
1010 agtiapi_IntrHandler10,
1011 agtiapi_IntrHandler11,
1012 agtiapi_IntrHandler12,
1013 agtiapi_IntrHandler13,
1014 agtiapi_IntrHandler14,
1015 agtiapi_IntrHandler15
1019 cnt = pci_msix_count(devx);
1020 AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64
1021 mesgs = MIN(mesgs, cnt);
1022 error = pci_alloc_msix(devx, &mesgs);
1024 printf( "pci_alloc_msix error %d\n", error );
1025 AGTIAPI_PRINTK("error %d\n", error);
1029 for(i=0; i < mesgs; i++) {
1030 pmsc->rscID[i] = i + 1;
1031 pmsc->irq[i] = bus_alloc_resource_any( devx,
1035 if( pmsc->irq[i] == NULL ) {
1036 printf( "RES_IRQ went terribly bad at %d\n", i );
1040 if ( (error = bus_setup_intr( devx, pmsc->irq[i],
1041 INTR_TYPE_CAM | INTR_MPSAFE,
1045 &pmsc->intrcookie[i] )
1047 device_printf( devx, "Failed to register handler" );
1051 pmsc->flags |= AGTIAPI_IRQ_REQUESTED;
1052 pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR;
1056 ret = agtiapi_InitCardSW(pmsc);
1057 if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN)
1059 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n",
1064 pmsc->ccbFreeList = NULL;
1065 pmsc->ccbChainList = NULL;
1066 pmsc->ccbAllocList = NULL;
1068 pmsc->flags |= ( AGTIAPI_INSTALLED );
1070 ret = agtiapi_alloc_requests( pmsc );
1072 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n",
1077 ret = agtiapi_alloc_ostimem( pmsc );
1078 if (ret != AGTIAPI_SUCCESS)
1080 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n",
1085 ret = agtiapi_InitCardHW( pmsc );
1088 AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n",
1093 #ifdef HIALEAH_ENCRYPTION
1096 if((agtiapi_SetupEncryption(pmsc)) < 0)
1097 AGTIAPI_PRINTK("SetupEncryption returned less than 0\n");
1101 pmsc->flags &= ~AGTIAPI_INIT_TIME;
1105 /******************************************************************************
1106 agtiapi_InitCardSW()
1109 Host Bus Adapter Initialization
1111 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1113 AGTIAPI_SUCCESS - success
1116 TBD, need chip register information
1117 ******************************************************************************/
1118 STATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc )
1120 ag_card_info_t *thisCardInst = pmsc->pCardInfo;
1121 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
1124 // begin: agtiapi_InitCardSW()
1125 // now init some essential locks n agtiapi_InitCardSW
1126 mtx_init( &pmsc->sendLock, "local q send lock", NULL, MTX_DEF );
1127 mtx_init( &pmsc->doneLock, "local q done lock", NULL, MTX_DEF );
1128 mtx_init( &pmsc->sendSMPLock, "local q send lock", NULL, MTX_DEF );
1129 mtx_init( &pmsc->doneSMPLock, "local q done lock", NULL, MTX_DEF );
1130 mtx_init( &pmsc->ccbLock, "ccb list lock", NULL, MTX_DEF );
1131 mtx_init( &pmsc->devListLock, "hotP devListLock", NULL, MTX_DEF );
1132 mtx_init( &pmsc->memLock, "dynamic memory lock", NULL, MTX_DEF );
1133 mtx_init( &pmsc->freezeLock, "sim freeze lock", NULL, MTX_DEF | MTX_RECURSE);
1135 // initialize lower layer resources
1136 //## if (pCard->flags & AGTIAPI_INIT_TIME) {
1137 #ifdef HIALEAH_ENCRYPTION
1138 /* Enable encryption if chip supports it */
1139 if (pci_get_device(pmsc->pCardInfo->pPCIDev) ==
1140 PCI_DEVICE_ID_HIALEAH_HBA_SPCVE)
1144 pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE;
1146 pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON);
1149 // For now, up to 16 MSIX vectors are supported
1150 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.
1151 maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors;
1152 AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d",
1153 pmsc->pCardInfo->maxInterruptVectors );
1154 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0;
1155 thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0;
1156 pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0;
1158 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n",
1159 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1160 if( tiCOMInit( &pmsc->tiRoot,
1161 &thisCardInst->tiRscInfo.tiLoLevelResource,
1162 &thisCardInst->tiRscInfo.tiInitiatorResource,
1164 &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) {
1165 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" );
1166 return AGTIAPI_FAIL;
1169 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
1170 pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL,
1171 M_ZERO | M_WAITOK );
1173 for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ )
1176 mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF );
1179 if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) {
1180 printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" );
1181 return AGTIAPI_FAIL;
1183 AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit"
1184 " root %p, dev %p, pmsc %p\n",
1185 &pmsc->tiRoot, pmsc->my_dev, pmsc );
1187 pmsc->flags |= AGTIAPI_PORT_INITIALIZED;
1188 pmsc->freezeSim = agFALSE;
1190 #ifdef HIALEAH_ENCRYPTION
1191 atomic_set(&outstanding_encrypted_io_count, 0);
1193 /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME))
1194 if((agtiapi_SetupEncryptionPools(pmsc)) != 0)
1195 printf("SetupEncryptionPools failed\n"); */
1197 return AGTIAPI_SUCCESS;
1198 // end: agtiapi_InitCardSW()
1201 /******************************************************************************
1202 agtiapi_InitCardHW()
1205 Host Bus Adapter Initialization
1207 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1209 AGTIAPI_SUCCESS - success
1212 TBD, need chip register information
1213 ******************************************************************************/
1214 STATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc )
1219 // begin: agtiapi_InitCardHW()
1221 ag_portal_info_t *pPortalInfo = NULL;
1222 ag_portal_data_t *pPortalData;
1224 // ISR is registered, enable chip interrupt.
1225 tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE );
1226 pmsc->flags |= AGTIAPI_SYS_INTR_ON;
1228 numVal = sizeof(ag_device_t) * pmsc->devDiscover;
1230 (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK );
1231 if( !pmsc->pDevList ) {
1232 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal );
1233 panic( "agtiapi_InitCardHW\n" );
1234 return AGTIAPI_FAIL;
1237 #ifdef LINUX_PERBI_SUPPORT
1238 numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover;
1240 (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK );
1241 if( !pmsc->pSLRList ) {
1242 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal );
1243 panic( "agtiapi_InitCardHW SLRL\n" );
1244 return AGTIAPI_FAIL;
1247 numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover;
1249 (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK );
1250 if( !pmsc->pWWNList ) {
1251 AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal );
1252 panic( "agtiapi_InitCardHW WWNL\n" );
1253 return AGTIAPI_FAIL;
1256 // Get the WWN_to_target_ID mappings from the
1257 // holding area which contains the input of the
1258 // system configuration file.
1260 agtiapi_GetWWNMappings( pmsc, agMappingList );
1262 agtiapi_GetWWNMappings( pmsc, 0 );
1264 printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" );
1268 //agtiapi_DelaySec(5);
1273 pmsc->flags &= ~AGTIAPI_CB_DONE;
1274 pPortalData = pmsc->pPortalData;
1278 for (count = 0; count < pmsc->portCount; count++)
1280 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
1282 pPortalInfo = &pPortalData->portalInfo;
1283 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
1284 AGTIAPI_PORT_DISC_READY |
1286 AGTIAPI_DISC_COMPLETE );
1288 for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++)
1290 AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n",
1292 pPortalInfo->portID,
1293 &pPortalInfo->tiPortalContext );
1295 if( tiCOMPortStart( &pmsc->tiRoot,
1296 pPortalInfo->portID,
1297 &pPortalInfo->tiPortalContext,
1300 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1301 agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY );
1302 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
1303 AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n",
1307 AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n",
1311 } // end of for loop
1313 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
1315 if( loop >= AGTIAPI_LOOP_MAX ) {
1316 return AGTIAPI_FAIL;
1318 tiCOMGetPortInfo( &pmsc->tiRoot,
1319 &pPortalInfo->tiPortalContext,
1320 &pPortalInfo->tiPortInfo );
1324 /* discover target device */
1325 #ifndef HOTPLUG_SUPPORT
1326 agtiapi_DiscoverTgt( pCard );
1330 pmsc->flags |= AGTIAPI_INSTALLED;
1332 if( pmsc->flags & AGTIAPI_INIT_TIME ) {
1333 agtiapi_TITimer( (void *)pmsc );
1334 pmsc->flags |= AGTIAPI_TIMER_ON;
1342 /******************************************************************************
1343 agtiapi_IntrHandlerx_()
1346 Interrupt service routine.
1348 void arg (IN) Pointer to the HBA data structure
1349 bit32 idx (IN) Vector index
1350 ******************************************************************************/
1351 void agtiapi_IntrHandlerx_( void *arg, int index )
1354 struct agtiapi_softc *pCard;
1357 pCard = (struct agtiapi_softc *)arg;
1363 AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock));
1364 AG_PERF_SPINLOCK(agtiapi_host_lock);
1365 if (pCard->flags & AGTIAPI_SHUT_DOWN)
1368 rv = tiCOMInterruptHandler(&pCard->tiRoot, index);
1372 AG_SPIN_UNLOCK(agtiapi_host_lock);
1373 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1379 tasklet_hi_schedule(&pCard->tasklet_dpc[idx]);
1381 /* consume all completed entries, 100 is random number to be big enough */
1382 tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext);
1383 AG_GET_DONE_PCCB(pccb, pCard);
1384 AG_GET_DONE_SMP_PCCB(pccb, pCard);
1388 AG_SPIN_UNLOCK(agtiapi_host_lock);
1389 AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock));
1394 /******************************************************************************
1395 agtiapi_IntrHandler0()
1396 Purpose: Interrupt service routine for interrupt vector index 0.
1397 Parameters: void arg (IN) Pointer to the HBA data structure
1398 ******************************************************************************/
1399 void agtiapi_IntrHandler0( void *arg )
1401 agtiapi_IntrHandlerx_( arg, 0 );
1405 /******************************************************************************
1406 agtiapi_IntrHandler1()
1407 Purpose: Interrupt service routine for interrupt vector index 1.
1408 Parameters: void arg (IN) Pointer to the HBA data structure
1409 ******************************************************************************/
1410 void agtiapi_IntrHandler1( void *arg )
1412 agtiapi_IntrHandlerx_( arg, 1 );
1416 /******************************************************************************
1417 agtiapi_IntrHandler2()
1418 Purpose: Interrupt service routine for interrupt vector index 2.
1419 Parameters: void arg (IN) Pointer to the HBA data structure
1420 ******************************************************************************/
1421 void agtiapi_IntrHandler2( void *arg )
1423 agtiapi_IntrHandlerx_( arg, 2 );
1427 /******************************************************************************
1428 agtiapi_IntrHandler3()
1429 Purpose: Interrupt service routine for interrupt vector index 3.
1430 Parameters: void arg (IN) Pointer to the HBA data structure
1431 ******************************************************************************/
1432 void agtiapi_IntrHandler3( void *arg )
1434 agtiapi_IntrHandlerx_( arg, 3 );
1438 /******************************************************************************
1439 agtiapi_IntrHandler4()
1440 Purpose: Interrupt service routine for interrupt vector index 4.
1441 Parameters: void arg (IN) Pointer to the HBA data structure
1442 ******************************************************************************/
1443 void agtiapi_IntrHandler4( void *arg )
1445 agtiapi_IntrHandlerx_( arg, 4 );
1449 /******************************************************************************
1450 agtiapi_IntrHandler5()
1451 Purpose: Interrupt service routine for interrupt vector index 5.
1452 Parameters: void arg (IN) Pointer to the HBA data structure
1453 ******************************************************************************/
1454 void agtiapi_IntrHandler5( void *arg )
1456 agtiapi_IntrHandlerx_( arg, 5 );
1460 /******************************************************************************
1461 agtiapi_IntrHandler6()
1462 Purpose: Interrupt service routine for interrupt vector index 6.
1463 Parameters: void arg (IN) Pointer to the HBA data structure
1464 ******************************************************************************/
1465 void agtiapi_IntrHandler6( void *arg )
1467 agtiapi_IntrHandlerx_( arg, 6 );
1471 /******************************************************************************
1472 agtiapi_IntrHandler7()
1473 Purpose: Interrupt service routine for interrupt vector index 7.
1474 Parameters: void arg (IN) Pointer to the HBA data structure
1475 ******************************************************************************/
1476 void agtiapi_IntrHandler7( void *arg )
1478 agtiapi_IntrHandlerx_( arg, 7 );
1482 /******************************************************************************
1483 agtiapi_IntrHandler8()
1484 Purpose: Interrupt service routine for interrupt vector index 8.
1485 Parameters: void arg (IN) Pointer to the HBA data structure
1486 ******************************************************************************/
1487 void agtiapi_IntrHandler8( void *arg )
1489 agtiapi_IntrHandlerx_( arg, 8 );
1493 /******************************************************************************
1494 agtiapi_IntrHandler9()
1495 Purpose: Interrupt service routine for interrupt vector index 9.
1496 Parameters: void arg (IN) Pointer to the HBA data structure
1497 ******************************************************************************/
1498 void agtiapi_IntrHandler9( void *arg )
1500 agtiapi_IntrHandlerx_( arg, 9 );
1504 /******************************************************************************
1505 agtiapi_IntrHandler10()
1506 Purpose: Interrupt service routine for interrupt vector index 10.
1507 Parameters: void arg (IN) Pointer to the HBA data structure
1508 ******************************************************************************/
1509 void agtiapi_IntrHandler10( void *arg )
1511 agtiapi_IntrHandlerx_( arg, 10 );
1515 /******************************************************************************
1516 agtiapi_IntrHandler11()
1517 Purpose: Interrupt service routine for interrupt vector index 11.
1518 Parameters: void arg (IN) Pointer to the HBA data structure
1519 ******************************************************************************/
1520 void agtiapi_IntrHandler11( void *arg )
1522 agtiapi_IntrHandlerx_( arg, 11 );
1526 /******************************************************************************
1527 agtiapi_IntrHandler12()
1528 Purpose: Interrupt service routine for interrupt vector index 12.
1529 Parameters: void arg (IN) Pointer to the HBA data structure
1530 ******************************************************************************/
1531 void agtiapi_IntrHandler12( void *arg )
1533 agtiapi_IntrHandlerx_( arg, 12 );
1537 /******************************************************************************
1538 agtiapi_IntrHandler13()
1539 Purpose: Interrupt service routine for interrupt vector index 13.
1540 Parameters: void arg (IN) Pointer to the HBA data structure
1541 ******************************************************************************/
1542 void agtiapi_IntrHandler13( void *arg )
1544 agtiapi_IntrHandlerx_( arg, 13 );
1548 /******************************************************************************
1549 agtiapi_IntrHandler14()
1550 Purpose: Interrupt service routine for interrupt vector index 14.
1551 Parameters: void arg (IN) Pointer to the HBA data structure
1552 ******************************************************************************/
1553 void agtiapi_IntrHandler14( void *arg )
1555 agtiapi_IntrHandlerx_( arg, 14 );
1559 /******************************************************************************
1560 agtiapi_IntrHandler15()
1561 Purpose: Interrupt service routine for interrupt vector index 15.
1562 Parameters: void arg (IN) Pointer to the HBA data structure
1563 ******************************************************************************/
1564 void agtiapi_IntrHandler15( void *arg )
1566 agtiapi_IntrHandlerx_( arg, 15 );
1570 static void agtiapi_SglMemoryCB( void *arg,
1571 bus_dma_segment_t *dm_segs,
1576 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n");
1579 AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error);
1580 panic("agtiapi_SglMemoryCB: error %d\n", error);
1584 *addr = dm_segs[0].ds_addr;
1588 static void agtiapi_MemoryCB( void *arg,
1589 bus_dma_segment_t *dm_segs,
1594 AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n");
1597 AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error);
1598 panic("agtiapi_MemoryCB: error %d\n", error);
1602 *addr = dm_segs[0].ds_addr;
1606 /******************************************************************************
1607 agtiapi_alloc_requests()
1610 Allocates resources such as dma tag and timer
1612 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
1614 AGTIAPI_SUCCESS - success
1617 ******************************************************************************/
1618 int agtiapi_alloc_requests( struct agtiapi_softc *pmcsc )
1624 nsegs = AGTIAPI_NSEGS;
1625 rsize = AGTIAPI_MAX_DMA_SEGS; // 128
1626 AGTIAPI_PRINTK( "agtiapi_alloc_requests: maxphys 0x%lx PAGE_SIZE 0x%x \n",
1627 maxphys, PAGE_SIZE );
1628 AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n",
1629 nsegs, rsize ); // 32, 128
1630 // This is for csio->data_ptr
1631 if( bus_dma_tag_create( agNULL, // parent
1634 BUS_SPACE_MAXADDR, // lowaddr
1635 BUS_SPACE_MAXADDR, // highaddr
1638 BUS_SPACE_MAXSIZE_32BIT, // maxsize
1640 BUS_SPACE_MAXSIZE_32BIT, // maxsegsize
1641 BUS_DMA_ALLOCNOW, // flags
1642 busdma_lock_mutex, // lockfunc
1643 &pmcsc->pCardInfo->pmIOLock, // lockarg
1644 &pmcsc->buffer_dmat ) ) {
1645 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1649 // This is for tiSgl_t of pccb in agtiapi_PrepCCBs()
1651 (sizeof(tiSgl_t) * AGTIAPI_NSEGS) *
1652 AGTIAPI_CCB_PER_DEVICE * maxTargets;
1653 AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128
1654 if( bus_dma_tag_create( agNULL, // parent
1657 BUS_SPACE_MAXADDR_32BIT, // lowaddr
1658 BUS_SPACE_MAXADDR, // highaddr
1663 rsize, // maxsegsize
1664 BUS_DMA_ALLOCNOW, // flags
1667 &pmcsc->tisgl_dmat ) ) {
1668 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" );
1672 if( bus_dmamem_alloc( pmcsc->tisgl_dmat,
1673 (void **)&pmcsc->tisgl_mem,
1675 &pmcsc->tisgl_map ) ) {
1676 AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" );
1680 bzero( pmcsc->tisgl_mem, rsize );
1681 bus_dmamap_load( pmcsc->tisgl_dmat,
1685 agtiapi_SglMemoryCB,
1686 &pmcsc->tisgl_busaddr,
1687 BUS_DMA_NOWAIT /* 0 */ );
1689 mtx_init( &pmcsc->OS_timer_lock, "OS timer lock", NULL, MTX_DEF );
1690 mtx_init( &pmcsc->IO_timer_lock, "IO timer lock", NULL, MTX_DEF );
1691 mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF );
1692 callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 );
1693 callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 );
1694 callout_init_mtx( &pmcsc->devRmTimer,
1695 &pmcsc->devRmTimerLock, 0);
1697 next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource.
1698 loLevelOption.usecsPerTick / USEC_PER_TICK;
1699 AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, "
1700 "next_tick 0x%x\n", next_tick );
1701 callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc );
1705 /******************************************************************************
1706 agtiapi_alloc_ostimem()
1709 Allocates memory used later in ostiAllocMemory
1711 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure
1713 AGTIAPI_SUCCESS - success
1716 This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls
1717 ******************************************************************************/
1718 int agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) {
1722 rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M
1723 AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize);
1725 if( bus_dma_tag_create( agNULL, // parent
1728 BUS_SPACE_MAXADDR, // lowaddr
1729 BUS_SPACE_MAXADDR, // highaddr
1732 rsize, // maxsize (size)
1733 1, // number of segments
1734 rsize, // maxsegsize
1738 &pmcsc->osti_dmat ) ) {
1739 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" );
1740 return AGTIAPI_FAIL;
1744 if( bus_dmamem_alloc( pmcsc->osti_dmat,
1746 BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
1747 &pmcsc->osti_mapp ) ) {
1748 AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n",
1750 return AGTIAPI_FAIL;
1754 bus_dmamap_load( pmcsc->osti_dmat,
1758 agtiapi_MemoryCB, // try reuse of CB for same goal
1759 &pmcsc->osti_busaddr,
1762 // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for
1763 // handy reference when driver is in motion
1765 ag_card_info_t *pCardInfo = pmcsc->pCardInfo;
1766 ag_dma_addr_t *pMem;
1768 for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
1769 pMem = &pCardInfo->dynamicMem[idx];
1770 pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize );
1771 pMem->nocache_mem = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize ));
1772 pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx];
1775 pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX;
1777 return AGTIAPI_SUCCESS;
1781 /******************************************************************************
1782 agtiapi_cam_action()
1785 Parses CAM frames and triggers a corresponding action
1787 struct cam_sim *sim (IN) Pointer to SIM data structure
1788 union ccb * ccb (IN) Pointer to CAM ccb data structure
1791 ******************************************************************************/
1792 static void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb )
1794 struct agtiapi_softc *pmcsc;
1795 tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well
1796 tiDeviceInfo_t devInfo;
1797 int pathID, targetID, lunID;
1802 pmcsc = cam_sim_softc( sim );
1803 AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc );
1805 if (pmcsc == agNULL)
1807 AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" );
1810 mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED );
1812 AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code );
1814 pathID = xpt_path_path_id( ccb->ccb_h.path );
1815 targetID = xpt_path_target_id( ccb->ccb_h.path );
1816 lunID = xpt_path_lun_id( ccb->ccb_h.path );
1818 AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n",
1819 pathID, targetID, lunID );
1821 switch (ccb->ccb_h.func_code)
1825 struct ccb_pathinq *cpi;
1827 /* See architecure book p180*/
1829 cpi->version_num = 1;
1830 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16;
1831 cpi->target_sprt = 0;
1832 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
1833 cpi->hba_eng_cnt = 0;
1834 cpi->max_target = maxTargets - 1;
1835 cpi->max_lun = AGTIAPI_MAX_LUN;
1836 /* Max supported I/O size, in bytes. */
1837 cpi->maxio = ulmin(1024 * 1024, maxphys);
1838 cpi->initiator_id = 255;
1839 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1840 strlcpy(cpi->hba_vid, "PMC", HBA_IDLEN);
1841 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1842 cpi->unit_number = cam_sim_unit(sim);
1843 cpi->bus_id = cam_sim_bus(sim);
1844 // rate is set when XPT_GET_TRAN_SETTINGS is processed
1845 cpi->base_transfer_speed = 150000;
1846 cpi->transport = XPORT_SAS;
1847 cpi->transport_version = 0;
1848 cpi->protocol = PROTO_SCSI;
1849 cpi->protocol_version = SCSI_REV_SPC3;
1850 cpi->ccb_h.status = CAM_REQ_CMP;
1853 case XPT_GET_TRAN_SETTINGS:
1855 struct ccb_trans_settings *cts;
1856 struct ccb_trans_settings_sas *sas;
1857 struct ccb_trans_settings_scsi *scsi;
1859 if ( pmcsc->flags & AGTIAPI_SHUT_DOWN )
1865 sas = &ccb->cts.xport_specific.sas;
1866 scsi = &cts->proto_specific.scsi;
1868 cts->protocol = PROTO_SCSI;
1869 cts->protocol_version = SCSI_REV_SPC3;
1870 cts->transport = XPORT_SAS;
1871 cts->transport_version = 0;
1873 sas->valid = CTS_SAS_VALID_SPEED;
1875 /* this sets the "MB/s transfers" */
1876 if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets)
1878 if (pmcsc->pWWNList != NULL)
1880 TID = INDEX(pmcsc, targetID);
1881 if (TID < maxTargets)
1883 pDevHandle = pmcsc->pDevList[TID].pDevHandle;
1889 tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo );
1890 switch (devInfo.info.devType_S_Rate & 0xF)
1892 case 0x8: speed = 150000;
1894 case 0x9: speed = 300000;
1896 case 0xA: speed = 600000;
1898 case 0xB: speed = 1200000;
1900 default: speed = 150000;
1904 sas->bitrate = speed;
1905 scsi->valid = CTS_SCSI_VALID_TQ;
1906 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
1907 ccb->ccb_h.status = CAM_REQ_CMP;
1912 lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time
1913 if ( SUCCESS == lRetVal )
1915 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" );
1919 AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" );
1921 ccb->ccb_h.status = CAM_REQ_CMP;
1926 ccb->ccb_h.status = CAM_REQ_CMP;
1931 ccb->ccb_h.status = CAM_REQ_CMP;
1934 #if __FreeBSD_version >= 900026
1937 agtiapi_QueueSMP( pmcsc, ccb );
1940 #endif /* __FreeBSD_version >= 900026 */
1943 if(pmcsc->dev_scan == agFALSE)
1945 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1948 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
1950 AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n",
1952 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1957 AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n",
1959 agtiapi_QueueCmnd_( pmcsc, ccb );
1964 case XPT_CALC_GEOMETRY:
1966 cam_calc_geometry(&ccb->ccg, 1);
1967 ccb->ccb_h.status = CAM_REQ_CMP;
1973 XPT_SET_TRAN_SETTINGS
1975 AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n",
1976 ccb->ccb_h.func_code );
1977 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1985 /******************************************************************************
1989 Get a ccb from free list or allocate a new one
1991 struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure
1993 Pointer to a ccb structure, or NULL if not available
1995 ******************************************************************************/
1996 STATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc )
2000 AGTIAPI_IO( "agtiapi_GetCCB: start\n" );
2002 AG_LOCAL_LOCK( &pmcsc->ccbLock );
2004 /* get the ccb from the head of the free list */
2005 if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL)
2007 pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext;
2008 pccb->pccbNext = NULL;
2009 pccb->flags = ACTIVE;
2010 pccb->startTime = 0;
2012 AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb );
2016 AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" );
2019 AG_LOCAL_UNLOCK( &pmcsc->ccbLock );
2023 /******************************************************************************
2024 agtiapi_QueueCmnd_()
2027 Calls for sending CCB and excuting on HBA.
2029 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2030 union ccb * ccb (IN) Pointer to CAM ccb data structure
2032 0 - Command is pending to execute
2033 1 - Command returned without further process
2035 ******************************************************************************/
2036 int agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb)
2038 struct ccb_scsiio *csio = &ccb->csio;
2039 pccb_t pccb = agNULL; // call dequeue
2040 int status = tiSuccess;
2041 U32 Channel = CMND_TO_CHANNEL(ccb);
2042 U32 TID = CMND_TO_TARGET(ccb);
2043 U32 LUN = CMND_TO_LUN(ccb);
2045 AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" );
2047 /* no support for CBD > 16 */
2048 if (csio->cdb_len > 16)
2050 AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n",
2052 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2053 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2054 ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP;
2058 if (TID < 0 || TID >= maxTargets)
2060 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n");
2061 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2062 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2063 ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP;
2068 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
2070 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n");
2074 TID = INDEX(pmcsc, TID);
2075 targ = &pmcsc->pDevList[TID];
2076 agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth);
2078 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2079 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2080 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2084 pccb->pmcsc = pmcsc;
2085 /* initialize Command Control Block (CCB) */
2086 pccb->targetId = TID;
2088 pccb->channel = Channel;
2089 pccb->ccb = ccb; /* for struct scsi_cmnd */
2090 pccb->senseLen = csio->sense_len;
2091 pccb->startTime = ticks;
2092 pccb->pSenseData = (caddr_t) &csio->sense_data;
2093 pccb->tiSuperScsiRequest.flags = 0;
2095 /* each channel is reserved for different addr modes */
2096 pccb->addrMode = agtiapi_AddrModes[Channel];
2098 status = agtiapi_PrepareSGList(pmcsc, pccb);
2099 if (status != tiSuccess)
2101 AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n");
2102 agtiapi_FreeCCB(pmcsc, pccb);
2103 if (status == tiReject)
2105 ccb->ccb_h.status = CAM_REQ_INVALID;
2109 ccb->ccb_h.status = CAM_REQ_CMP;
2117 /******************************************************************************
2123 const char *ptitle (IN) A string to be printed
2124 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2127 ******************************************************************************/
2128 STATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb)
2131 struct ccb_scsiio *csio;
2137 printf( "agtiapi_DumpCDB: no pccb here \n" );
2138 panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle);
2144 printf( "agtiapi_DumpCDB: no ccb here \n" );
2145 panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! "
2147 pccb, pccb->ccb, pccb->flags, ptitle );
2153 printf( "agtiapi_DumpCDB: no csio here \n" );
2154 panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n",
2155 pccb, pccb->ccb, pccb->flags, ptitle );
2158 len = MIN(64, csio->cdb_len);
2159 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2161 bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len);
2165 bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len);
2168 AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d"
2169 " len %d from %s\n",
2177 /******************************************************************************
2178 agtiapi_DoSoftReset()
2183 *data (IN) point to pmcsc (struct agtiapi_softc *)
2186 ******************************************************************************/
2187 int agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc)
2190 unsigned long flags;
2192 pmcsc->flags |= AGTIAPI_SOFT_RESET;
2193 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
2194 ret = agtiapi_ResetCard( pmcsc, &flags );
2195 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
2197 if( ret != AGTIAPI_SUCCESS )
2203 /******************************************************************************
2204 agtiapi_CheckIOTimeout()
2207 Timeout function for SCSI IO or TM
2209 *data (IN) point to pCard (ag_card_t *)
2212 ******************************************************************************/
2213 STATIC void agtiapi_CheckIOTimeout(void *data)
2215 U32 status = AGTIAPI_SUCCESS;
2217 struct agtiapi_softc *pmcsc;
2220 pmcsc = (struct agtiapi_softc *)data;
2222 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n");
2224 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB);
2226 pccb = (pccb_t)pmcsc->ccbChainList;
2228 /* if link is down, do nothing */
2229 if ((pccb == NULL) || (pmcsc->activeCCB == 0))
2231 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n");
2235 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags);
2236 if (pmcsc->flags & AGTIAPI_SHUT_DOWN)
2241 /* Walk thorugh the IO Chain linked list to find the pending io */
2242 /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */
2243 while (pccb_curr != NULL)
2245 /* start from 1st ccb in the chain */
2246 pccb_next = pccb_curr->pccbChainNext;
2247 if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) ||
2248 (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */)
2250 //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n");
2252 else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) &&
2253 !(pccb_curr->flags & TIMEDOUT) )
2255 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM "
2256 "function -- flags=%x startTime=%ld tdData = %p\n",
2257 pccb_curr, pccb_curr->flags, pccb->startTime,
2258 pccb_curr->tiIORequest.tdData );
2259 pccb_curr->flags |= TIMEDOUT;
2260 status = agtiapi_StartTM(pmcsc, pccb_curr);
2261 if (status == AGTIAPI_SUCCESS)
2263 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with "
2269 #ifdef AGTIAPI_LOCAL_RESET
2270 /* abort request did not go through */
2271 AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n");
2272 /* TODO: call Soft reset here */
2273 AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() "
2274 "abort request did not go thru ==> soft reset#7, then "
2275 "restart timer\n" );
2276 agtiapi_DoSoftReset (pmcsc);
2281 pccb_curr = pccb_next;
2284 callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc);
2287 AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags);
2291 /******************************************************************************
2295 DDI calls for aborting outstanding IO command
2297 struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted
2298 unsigned long flags (IN/out) spinlock flags used in locking from
2301 AGTIAPI_SUCCESS - success
2303 ******************************************************************************/
2305 agtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb)
2307 ccb_t *pTMccb = NULL;
2308 U32 status = AGTIAPI_SUCCESS;
2309 ag_device_t *pDevice = NULL;
2310 U32 TMstatus = tiSuccess;
2311 AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n",
2312 pccb, pccb->flags );
2315 AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb);
2316 status = AGTIAPI_SUCCESS;
2319 if (!pccb->tiIORequest.tdData)
2321 /* should not be the case */
2322 AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData "
2323 "ERROR\n", pccb, pccb->flags, pccb->targetId);
2324 status = AGTIAPI_FAIL;
2328 /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to
2329 clear pending TM_ABORT_TASK */
2330 /* Else Device State will not be put back to Operational, (refer FW) */
2331 if (pccb->flags & TASK_MANAGEMENT)
2333 if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess)
2335 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK "
2337 /* TODO: call Soft reset here */
2338 AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort "
2339 "tiINIIOAbort() failed ==> soft reset#8\n" );
2340 agtiapi_DoSoftReset( pCard );
2344 AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM "
2346 status = AGTIAPI_SUCCESS;
2352 if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL)
2354 AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n");
2355 status = AGTIAPI_FAIL;
2358 pTMccb->pmcsc = pCard;
2359 pTMccb->targetId = pccb->targetId;
2360 pTMccb->devHandle = pccb->devHandle;
2361 if (pTMccb->targetId >= pCard->devDiscover)
2363 AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n");
2364 status = AGTIAPI_FAIL;
2367 if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets)
2369 return AGTIAPI_FAIL;
2371 if (INDEX(pCard, pTMccb->targetId) >= maxTargets)
2373 return AGTIAPI_FAIL;
2375 pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)];
2376 if ((pDevice == NULL) || !(pDevice->flags & ACTIVE))
2378 return AGTIAPI_FAIL;
2381 /* save pending io to issue local abort at Task mgmt CB */
2382 pTMccb->pccbIO = pccb;
2383 AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM "
2385 pTMccb, pTMccb->flags, pTMccb->targetId );
2386 pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE);
2387 pTMccb->flags |= TASK_MANAGEMENT;
2388 TMstatus = tiINITaskManagement(&pCard->tiRoot,
2391 &pccb->tiSuperScsiRequest.scsiCmnd.lun,
2393 &pTMccb->tiIORequest);
2394 if (TMstatus == tiSuccess)
2396 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb "
2399 pTMccb->startTime = ticks;
2400 status = AGTIAPI_SUCCESS;
2402 else if (TMstatus == tiIONoDevice)
2404 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb "
2407 status = AGTIAPI_SUCCESS;
2411 AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, "
2414 status = AGTIAPI_FAIL;
2415 agtiapi_FreeTMCCB(pCard, pTMccb);
2417 /* call TM_TARGET_RESET */
2422 AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status,
2423 (pccb) ? pccb->flags : -1);
2425 } /* agtiapi_StartTM */
2427 #if __FreeBSD_version > 901000
2428 /******************************************************************************
2429 agtiapi_PrepareSGList()
2432 This function prepares scatter-gather list for the given ccb
2434 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2435 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2441 ******************************************************************************/
2442 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2444 union ccb *ccb = pccb->ccb;
2445 struct ccb_scsiio *csio = &ccb->csio;
2446 struct ccb_hdr *ccbh = &ccb->ccb_h;
2447 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2449 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2450 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2452 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2454 switch((ccbh->flags & CAM_DATA_MASK))
2457 struct bus_dma_segment seg;
2458 case CAM_DATA_VADDR:
2459 /* Virtual address that needs to translated into one or more physical address ranges. */
2461 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2462 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2463 error = bus_dmamap_load( pmcsc->buffer_dmat,
2467 agtiapi_PrepareSGListCB,
2469 BUS_DMA_NOWAIT/* 0 */ );
2470 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2472 if (error == EINPROGRESS)
2474 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2475 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2476 xpt_freeze_simq(pmcsc->sim, 1);
2477 pmcsc->SimQFrozen = agTRUE;
2478 ccbh->status |= CAM_RELEASE_SIMQ;
2481 case CAM_DATA_PADDR:
2482 /* We have been given a pointer to single physical buffer. */
2483 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2484 //struct bus_dma_segment seg;
2485 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2487 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2488 seg.ds_len = csio->dxfer_len;
2489 // * 0xFF to be defined
2490 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2493 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2499 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2504 /******************************************************************************
2505 agtiapi_PrepareSGList()
2508 This function prepares scatter-gather list for the given ccb
2510 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
2511 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
2517 ******************************************************************************/
2518 static int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb)
2520 union ccb *ccb = pccb->ccb;
2521 struct ccb_scsiio *csio = &ccb->csio;
2522 struct ccb_hdr *ccbh = &ccb->ccb_h;
2523 AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" );
2524 // agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb);
2525 AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len );
2527 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE)
2529 if ((ccbh->flags & CAM_SCATTER_VALID) == 0)
2531 /* We've been given a pointer to a single buffer. */
2532 if ((ccbh->flags & CAM_DATA_PHYS) == 0)
2534 /* Virtual address that needs to translated into one or more physical address ranges. */
2536 // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
2537 AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" );
2538 error = bus_dmamap_load( pmcsc->buffer_dmat,
2542 agtiapi_PrepareSGListCB,
2544 BUS_DMA_NOWAIT/* 0 */ );
2545 // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
2547 if (error == EINPROGRESS)
2549 /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */
2550 AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n");
2551 xpt_freeze_simq(pmcsc->sim, 1);
2552 pmcsc->SimQFrozen = agTRUE;
2553 ccbh->status |= CAM_RELEASE_SIMQ;
2558 /* We have been given a pointer to single physical buffer. */
2559 /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */
2560 struct bus_dma_segment seg;
2561 AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n");
2563 (bus_addr_t)(vm_offset_t)csio->data_ptr;
2564 seg.ds_len = csio->dxfer_len;
2565 // * 0xFF to be defined
2566 agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD);
2572 AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n");
2578 agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA);
2584 /******************************************************************************
2585 agtiapi_PrepareSGListCB()
2588 Callback function for bus_dmamap_load()
2589 This fuctions sends IO to LL layer.
2591 void *arg (IN) Pointer to the HBA data structure
2592 bus_dma_segment_t *segs (IN) Pointer to dma segment
2593 int nsegs (IN) number of dma segment
2594 int error (IN) error
2597 ******************************************************************************/
2598 static void agtiapi_PrepareSGListCB( void *arg,
2599 bus_dma_segment_t *segs,
2604 union ccb *ccb = pccb->ccb;
2605 struct ccb_scsiio *csio = &ccb->csio;
2607 struct agtiapi_softc *pmcsc;
2608 tiIniScsiCmnd_t *pScsiCmnd;
2610 bus_dmasync_op_t op;
2613 int io_is_encryptable = 0;
2614 unsigned long long start_lba = 0;
2616 U32 TID = CMND_TO_TARGET(ccb);
2618 AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n",
2620 pmcsc = pccb->pmcsc;
2622 if (error != tiSuccess)
2624 if (error == 0xAABBCCDD || error == 0xAAAAAAAA)
2630 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error);
2631 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2632 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2633 agtiapi_FreeCCB(pmcsc, pccb);
2634 ccb->ccb_h.status = CAM_REQ_CMP;
2640 if (nsegs > AGTIAPI_MAX_DMA_SEGS)
2642 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d"
2643 " AGTIAPI_MAX_DMA_SEGS %d\n",
2644 nsegs, AGTIAPI_MAX_DMA_SEGS );
2645 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2646 bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap);
2647 agtiapi_FreeCCB(pmcsc, pccb);
2648 ccb->ccb_h.status = CAM_REQ_CMP;
2654 /* fill in IO information */
2655 pccb->dataLen = csio->dxfer_len;
2657 /* start fill in sgl structure */
2658 if (nsegs == 1 && error == 0xAABBCCDD)
2661 /* A single physical buffer */
2662 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n");
2663 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2664 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2665 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2666 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr;
2667 pccb->numSgElements = 1;
2669 else if (nsegs == 0 && error == 0xAAAAAAAA)
2671 /* no data transfer */
2672 AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" );
2673 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2675 pccb->numSgElements = 0;
2679 /* virtual/logical buffer */
2682 pccb->dataLen = segs[0].ds_len;
2684 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr);
2685 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2686 pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len);
2687 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2688 pccb->numSgElements = nsegs;
2695 for (i = 0; i < nsegs; i++)
2697 pccb->sgList[i].len = htole32(segs[i].ds_len);
2698 CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr);
2699 pccb->sgList[i].type = htole32(tiSgl);
2700 pccb->dataLen += segs[i].ds_len;
2703 pccb->numSgElements = nsegs;
2704 /* set up sgl buffer address */
2705 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr);
2706 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList);
2707 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen);
2708 pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr;
2709 pccb->numSgElements = nsegs;
2713 /* set data transfer direction */
2714 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2716 op = BUS_DMASYNC_PREWRITE;
2717 pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut;
2721 op = BUS_DMASYNC_PREREAD;
2722 pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn;
2725 pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd;
2727 pScsiCmnd->expDataLength = pccb->dataLen;
2729 if (csio->ccb_h.flags & CAM_CDB_POINTER)
2731 bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len);
2735 bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len);
2738 CDB = &pScsiCmnd->cdb[0];
2742 case REQUEST_SENSE: /* requires different buffer */
2743 /* This code should not be excercised because SAS support auto sense
2744 For the completeness, vtophys() is still used here.
2746 AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n");
2747 pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen);
2748 phys_addr = vtophys(&csio->sense_data);
2749 CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr);
2750 pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl);
2751 pccb->dataLen = pccb->senseLen;
2752 pccb->numSgElements = 1;
2755 /* only using lun 0 for device type detection */
2756 pccb->flags |= AGTIAPI_INQUIRY;
2758 case TEST_UNIT_READY:
2762 pccb->tiSuperScsiRequest.agSgl1.len = 0;
2768 start_lba = ((CDB[1] & 0x1f) << 16) |
2771 #ifdef HIALEAH_ENCRYPTION
2772 io_is_encryptable = 1;
2780 start_lba = (CDB[2] << 24) |
2784 #ifdef HIALEAH_ENCRYPTION
2785 io_is_encryptable = 1;
2791 start_lba = (CDB[2] << 24) |
2796 start_lba |= ((CDB[6] << 24) |
2800 #ifdef HIALEAH_ENCRYPTION
2801 io_is_encryptable = 1;
2808 /* fill device lun based one address mode */
2809 agtiapi_SetLunField(pccb);
2811 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
2813 pccb->ccbStatus = tiIOFailed;
2814 pccb->scsiStatus = tiDetailNoLogin;
2815 agtiapi_FreeCCB(pmcsc, pccb);
2816 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2821 if (INDEX(pmcsc, pccb->targetId) >= maxTargets)
2823 pccb->ccbStatus = tiIOFailed;
2824 pccb->scsiStatus = tiDetailNoLogin;
2825 agtiapi_FreeCCB(pmcsc, pccb);
2826 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
2831 pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)];
2834 if ((pmcsc->flags & EDC_DATA) &&
2835 (pDev->flags & EDC_DATA))
2840 * Possible command supported -
2841 * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER,
2842 * READ_DEFECT_DATA, etc.
2843 * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2,
2844 * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc.
2846 * Do some data length adjustment and set chip operation instruction.
2854 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2855 #ifdef AGTIAPI_TEST_DIF
2856 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2858 pccb->flags |= EDC_DATA;
2860 #ifdef TEST_VERIFY_AND_FORWARD
2861 pccb->tiSuperScsiRequest.Dif.flags =
2862 DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT;
2863 if(pDev->sector_size == 520) {
2864 pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8;
2865 } else if(pDev->sector_size == 4104) {
2866 pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8;
2869 #ifdef AGTIAPI_TEST_DIF
2870 pccb->tiSuperScsiRequest.Dif.flags =
2871 DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT;
2874 #ifdef AGTIAPI_TEST_DIF
2875 switch(pDev->sector_size) {
2877 pccb->tiSuperScsiRequest.Dif.flags |=
2878 ( DIF_BLOCK_SIZE_520 << 16 );
2881 pccb->tiSuperScsiRequest.Dif.flags |=
2882 ( DIF_BLOCK_SIZE_4096 << 16 );
2885 pccb->tiSuperScsiRequest.Dif.flags |=
2886 ( DIF_BLOCK_SIZE_4160 << 16 );
2890 if(pCard->flags & EDC_DATA_CRC)
2891 pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION;
2893 /* Turn on upper 4 bits of UVM */
2894 pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000;
2897 #ifdef AGTIAPI_TEST_DPL
2898 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2899 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2900 cmnd->result = SCSI_HOST(DID_ERROR);
2903 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2905 #ifdef AGTIAPI_TEST_DIF
2907 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2908 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2910 /* Set LBA in UDT array */
2911 if(CDB[0] == READ_6) {
2912 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2913 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2914 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2915 pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0;
2916 } else if(CDB[0] == READ_10 || CDB[0] == READ_12) {
2917 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2918 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2919 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2920 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2921 } else if(CDB[0] == READ_16) {
2922 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9];
2923 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8];
2924 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7];
2925 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6];
2926 /* Note: 32 bits lost */
2935 // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT);
2936 pccb->flags |= EDC_DATA;
2937 #ifdef AGTIAPI_TEST_DIF
2938 pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF;
2939 pccb->tiSuperScsiRequest.Dif.flags =
2940 DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT;
2941 switch(pDev->sector_size) {
2943 pccb->tiSuperScsiRequest.Dif.flags |=
2944 (DIF_BLOCK_SIZE_520 << 16);
2947 pccb->tiSuperScsiRequest.Dif.flags |=
2948 ( DIF_BLOCK_SIZE_4096 << 16 );
2951 pccb->tiSuperScsiRequest.Dif.flags |=
2952 ( DIF_BLOCK_SIZE_4160 << 16 );
2956 /* Turn on upper 4 bits of UUM */
2957 pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000;
2959 #ifdef AGTIAPI_TEST_DPL
2960 if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) {
2961 printk(KERN_ERR "SetupDifPerLA Failed.\n");
2962 cmnd->result = SCSI_HOST(DID_ERROR);
2965 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE;
2967 #ifdef AGTIAPI_TEST_DIF
2969 pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa;
2970 pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb;
2972 /* Set LBA in UDT array */
2973 if(CDB[0] == WRITE_6) {
2974 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3];
2975 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2];
2976 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f;
2977 } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) {
2978 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2979 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2980 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2981 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2982 } else if(CDB[0] == WRITE_16) {
2983 pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5];
2984 pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4];
2985 pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3];
2986 pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2];
2987 /* Note: 32 bits lost */
2993 #endif /* end of DIF */
2995 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
2997 switch(csio->tag_action)
2999 case MSG_HEAD_OF_Q_TAG:
3000 pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE;
3003 pScsiCmnd->taskAttribute = TASK_ACA;
3005 case MSG_ORDERED_Q_TAG:
3006 pScsiCmnd->taskAttribute = TASK_ORDERED;
3008 case MSG_SIMPLE_Q_TAG: /* fall through */
3010 pScsiCmnd->taskAttribute = TASK_SIMPLE;
3015 if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0)
3017 /* should be just before start IO */
3018 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
3022 * If assigned pDevHandle is not available
3023 * then there is no need to send it to StartIO()
3025 if (pccb->targetId < 0 || pccb->targetId >= maxTargets)
3027 pccb->ccbStatus = tiIOFailed;
3028 pccb->scsiStatus = tiDetailNoLogin;
3029 agtiapi_FreeCCB(pmcsc, pccb);
3030 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3035 TID = INDEX(pmcsc, pccb->targetId);
3036 if ((TID >= pmcsc->devDiscover) ||
3037 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle))
3040 AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p,"
3041 " target %d tid %d/%d card %p ERROR pccb %p\n",
3042 pccb->devHandle, pccb->targetId, TID,
3043 pmcsc->devDiscover, pmcsc, pccb );
3045 pccb->ccbStatus = tiIOFailed;
3046 pccb->scsiStatus = tiDetailNoLogin;
3047 agtiapi_FreeCCB(pmcsc, pccb);
3048 ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL
3053 AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, "
3054 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3055 pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover,
3057 #ifdef HIALEAH_ENCRYPTION
3058 if(pmcsc->encrypt && io_is_encryptable) {
3059 agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba);
3061 io_is_encryptable = 0;
3062 pccb->tiSuperScsiRequest.flags = 0;
3065 // put the request in send queue
3066 agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3067 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb );
3068 agtiapi_StartIO(pmcsc);
3072 /******************************************************************************
3076 Send IO request down for processing.
3078 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3081 ******************************************************************************/
3082 STATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc )
3088 AGTIAPI_IO( "agtiapi_StartIO: start\n" );
3090 AG_LOCAL_LOCK( &pmcsc->sendLock );
3091 pccb = pmcsc->ccbSendHead;
3093 /* if link is down, do nothing */
3094 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3096 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3097 AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" );
3102 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3104 TID = INDEX(pmcsc, pccb->targetId);
3105 targ = &pmcsc->pDevList[TID];
3109 /* clear send queue */
3110 pmcsc->ccbSendHead = NULL;
3111 pmcsc->ccbSendTail = NULL;
3112 AG_LOCAL_UNLOCK( &pmcsc->sendLock );
3114 /* send all ccbs down */
3120 pccb_next = pccb->pccbNext;
3121 pccb->pccbNext = NULL;
3125 AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" );
3129 AG_IO_DUMPCCB( pccb );
3131 if (!pccb->devHandle)
3133 agtiapi_DumpCCB( pccb );
3134 AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" );
3138 AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount );
3141 if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */
3142 !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE))
3144 AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n",
3146 if( pccb->devHandle ) {
3147 AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail"
3149 pccb->devHandle->osData );
3150 if( pccb->devHandle->osData ) {
3151 AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail"
3152 " -- active flag:%d\n",
3154 (pccb->devHandle->osData))->flags & ACTIVE );
3157 pccb->ccbStatus = tiIOFailed;
3158 pccb->scsiStatus = tiDetailNoLogin;
3159 agtiapi_Done( pmcsc, pccb );
3166 status = agtiapi_FastIOTest( pmcsc, pccb );
3168 status = tiINISuperIOStart( &pmcsc->tiRoot,
3171 &pccb->tiSuperScsiRequest,
3172 (void *)&pccb->tdIOReqBody,
3173 tiInterruptContext );
3179 static int squelchCount = 0;
3180 if ( 200000 == squelchCount++ ) // squelch prints
3182 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n",
3184 squelchCount = 0; // reset count
3191 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n",
3194 agtiapi_LogEvent( pmcsc,
3195 IOCTL_EVT_SEV_INFORMATIONAL,
3199 "tiINIIOStart tiDeviceBusy " );
3201 pccb->ccbStatus = tiIOFailed;
3202 pccb->scsiStatus = tiDeviceBusy;
3203 agtiapi_Done(pmcsc, pccb);
3207 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n",
3210 agtiapi_LogEvent( pmcsc,
3211 IOCTL_EVT_SEV_INFORMATIONAL,
3215 "tiINIIOStart tiBusy " );
3218 pccb->ccbStatus = tiIOFailed;
3219 pccb->scsiStatus = tiBusy;
3220 agtiapi_Done(pmcsc, pccb);
3224 AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p "
3225 "ERROR\n", pccb->ccb );
3227 agtiapi_LogEvent( pmcsc,
3228 IOCTL_EVT_SEV_INFORMATIONAL,
3232 "tiINIIOStart invalid device handle " );
3235 /* return command back to OS due to no device available */
3236 ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE;
3237 pccb->ccbStatus = tiIOFailed;
3238 pccb->scsiStatus = tiDetailNoLogin;
3239 agtiapi_Done(pmcsc, pccb);
3241 /* for short cable pull, we want IO retried - 3-18-2005 */
3242 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
3243 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
3247 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3250 agtiapi_LogEvent(pmcsc,
3251 IOCTL_EVT_SEV_INFORMATIONAL,
3255 "tiINIIOStart tiError ");
3257 pccb->ccbStatus = tiIOFailed;
3258 pccb->scsiStatus = tiDetailOtherError;
3259 agtiapi_Done(pmcsc, pccb);
3262 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3265 agtiapi_LogEvent(pmcsc,
3266 IOCTL_EVT_SEV_ERROR,
3270 "tiINIIOStart unexpected status ");
3272 pccb->ccbStatus = tiIOFailed;
3273 pccb->scsiStatus = tiDetailOtherError;
3274 agtiapi_Done(pmcsc, pccb);
3280 /* some IO requests might have been completed */
3281 AG_GET_DONE_PCCB(pccb, pmcsc);
3285 /******************************************************************************
3289 Send SMP request down for processing.
3291 (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3294 ******************************************************************************/
3295 STATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc)
3299 AGTIAPI_PRINTK("agtiapi_StartSMP: start\n");
3301 AG_LOCAL_LOCK(&pmcsc->sendSMPLock);
3302 pccb = pmcsc->smpSendHead;
3304 /* if link is down, do nothing */
3305 if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET)
3307 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3308 AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n");
3312 /* clear send queue */
3313 pmcsc->smpSendHead = NULL;
3314 pmcsc->smpSendTail = NULL;
3315 AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock);
3317 /* send all ccbs down */
3323 pccb_next = pccb->pccbNext;
3324 pccb->pccbNext = NULL;
3328 AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n");
3333 if (!pccb->devHandle)
3335 AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n");
3339 pccb->flags |= TAG_SMP; // mark as SMP for later tracking
3340 AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n",
3341 pccb, pccb->retryCount );
3342 status = tiINISMPStart( &pmcsc->tiRoot,
3346 (void *)&pccb->tdIOReqBody,
3347 tiInterruptContext);
3354 AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n",
3356 /* pending ccb back to send queue */
3357 agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3358 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb);
3361 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n",
3363 pccb->ccbStatus = tiSMPFailed;
3364 agtiapi_SMPDone(pmcsc, pccb);
3367 AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n",
3369 pccb->ccbStatus = tiSMPFailed;
3370 agtiapi_SMPDone(pmcsc, pccb);
3376 /* some SMP requests might have been completed */
3377 AG_GET_DONE_SMP_PCCB(pccb, pmcsc);
3382 #if __FreeBSD_version > 901000
3383 /******************************************************************************
3384 agtiapi_PrepareSMPSGList()
3387 This function prepares scatter-gather list for the given ccb
3389 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3390 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3396 ******************************************************************************/
3397 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3399 /* Pointer to CAM's ccb */
3400 union ccb *ccb = pccb->ccb;
3401 struct ccb_smpio *csmpio = &ccb->smpio;
3402 struct ccb_hdr *ccbh = &ccb->ccb_h;
3404 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3405 switch((ccbh->flags & CAM_DATA_MASK))
3407 case CAM_DATA_PADDR:
3408 case CAM_DATA_SG_PADDR:
3409 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n");
3410 ccb->ccb_h.status = CAM_REQ_INVALID;
3416 * Currently we do not support Multiple SG list
3417 * return error for now
3419 if ( (csmpio->smp_request_sglist_cnt > 1)
3420 || (csmpio->smp_response_sglist_cnt > 1) )
3422 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n");
3423 ccb->ccb_h.status = CAM_REQ_INVALID;
3428 if ( csmpio->smp_request_sglist_cnt != 0 )
3431 * Virtual address that needs to translated into
3432 * one or more physical address ranges.
3435 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3436 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3437 error = bus_dmamap_load( pmcsc->buffer_dmat,
3439 csmpio->smp_request,
3440 csmpio->smp_request_len,
3441 agtiapi_PrepareSMPSGListCB,
3443 BUS_DMA_NOWAIT /* 0 */ );
3445 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3447 if (error == EINPROGRESS)
3450 * So as to maintain ordering,
3451 * freeze the controller queue
3452 * until our mapping is
3455 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3456 xpt_freeze_simq( pmcsc->sim, 1 );
3457 pmcsc->SimQFrozen = agTRUE;
3458 ccbh->status |= CAM_RELEASE_SIMQ;
3461 if( csmpio->smp_response_sglist_cnt != 0 )
3464 * Virtual address that needs to translated into
3465 * one or more physical address ranges.
3468 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3469 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3470 error = bus_dmamap_load( pmcsc->buffer_dmat,
3472 csmpio->smp_response,
3473 csmpio->smp_response_len,
3474 agtiapi_PrepareSMPSGListCB,
3476 BUS_DMA_NOWAIT /* 0 */ );
3478 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3480 if ( error == EINPROGRESS )
3483 * So as to maintain ordering,
3484 * freeze the controller queue
3485 * until our mapping is
3488 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3489 xpt_freeze_simq( pmcsc->sim, 1 );
3490 pmcsc->SimQFrozen = agTRUE;
3491 ccbh->status |= CAM_RELEASE_SIMQ;
3497 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3498 (csmpio->smp_response_sglist_cnt == 0) )
3500 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3501 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3502 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3503 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3505 // 0xFF to be defined
3506 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3508 pccb->tiSMPFrame.flag = 0;
3515 /******************************************************************************
3516 agtiapi_PrepareSMPSGList()
3519 This function prepares scatter-gather list for the given ccb
3521 struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure
3522 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3528 ******************************************************************************/
3529 static int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb )
3531 /* Pointer to CAM's ccb */
3532 union ccb *ccb = pccb->ccb;
3533 struct ccb_smpio *csmpio = &ccb->smpio;
3534 struct ccb_hdr *ccbh = &ccb->ccb_h;
3536 AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n");
3538 if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS))
3540 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address "
3541 "not supported\n" );
3542 ccb->ccb_h.status = CAM_REQ_INVALID;
3547 if (ccbh->flags & CAM_SCATTER_VALID)
3550 * Currently we do not support Multiple SG list
3551 * return error for now
3553 if ( (csmpio->smp_request_sglist_cnt > 1)
3554 || (csmpio->smp_response_sglist_cnt > 1) )
3556 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list "
3557 "not supported\n" );
3558 ccb->ccb_h.status = CAM_REQ_INVALID;
3562 if ( csmpio->smp_request_sglist_cnt != 0 )
3565 * Virtual address that needs to translated into
3566 * one or more physical address ranges.
3569 //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock));
3570 AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n");
3571 error = bus_dmamap_load( pmcsc->buffer_dmat,
3573 csmpio->smp_request,
3574 csmpio->smp_request_len,
3575 agtiapi_PrepareSMPSGListCB,
3577 BUS_DMA_NOWAIT /* 0 */ );
3579 //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock));
3581 if (error == EINPROGRESS)
3584 * So as to maintain ordering,
3585 * freeze the controller queue
3586 * until our mapping is
3589 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3590 xpt_freeze_simq( pmcsc->sim, 1 );
3591 pmcsc->SimQFrozen = agTRUE;
3592 ccbh->status |= CAM_RELEASE_SIMQ;
3595 if( csmpio->smp_response_sglist_cnt != 0 )
3598 * Virtual address that needs to translated into
3599 * one or more physical address ranges.
3602 //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) );
3603 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" );
3604 error = bus_dmamap_load( pmcsc->buffer_dmat,
3606 csmpio->smp_response,
3607 csmpio->smp_response_len,
3608 agtiapi_PrepareSMPSGListCB,
3610 BUS_DMA_NOWAIT /* 0 */ );
3612 //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) );
3614 if ( error == EINPROGRESS )
3617 * So as to maintain ordering,
3618 * freeze the controller queue
3619 * until our mapping is
3622 AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" );
3623 xpt_freeze_simq( pmcsc->sim, 1 );
3624 pmcsc->SimQFrozen = agTRUE;
3625 ccbh->status |= CAM_RELEASE_SIMQ;
3631 if ( (csmpio->smp_request_sglist_cnt == 0) &&
3632 (csmpio->smp_response_sglist_cnt == 0) )
3634 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" );
3635 pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request;
3636 pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len;
3637 pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len;
3639 // 0xFF to be defined
3640 agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD );
3642 pccb->tiSMPFrame.flag = 0;
3649 /******************************************************************************
3650 agtiapi_PrepareSMPSGListCB()
3653 Callback function for bus_dmamap_load()
3654 This fuctions sends IO to LL layer.
3656 void *arg (IN) Pointer to the HBA data structure
3657 bus_dma_segment_t *segs (IN) Pointer to dma segment
3658 int nsegs (IN) number of dma segment
3659 int error (IN) error
3662 ******************************************************************************/
3663 static void agtiapi_PrepareSMPSGListCB( void *arg,
3664 bus_dma_segment_t *segs,
3669 union ccb *ccb = pccb->ccb;
3670 struct agtiapi_softc *pmcsc;
3671 U32 TID = CMND_TO_TARGET(ccb);
3673 tiDeviceHandle_t *tiExpDevHandle;
3674 tiPortalContext_t *tiExpPortalContext;
3675 ag_portal_info_t *tiExpPortalInfo;
3677 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n",
3679 pmcsc = pccb->pmcsc;
3681 if ( error != tiSuccess )
3683 if (error == 0xAABBCCDD)
3689 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n",
3691 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3692 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3693 agtiapi_FreeCCB( pmcsc, pccb );
3694 ccb->ccb_h.status = CAM_REQ_CMP;
3700 if ( nsegs > AGTIAPI_MAX_DMA_SEGS )
3702 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d "
3703 "AGTIAPI_MAX_DMA_SEGS %d\n",
3704 nsegs, AGTIAPI_MAX_DMA_SEGS );
3705 bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3706 bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap );
3707 agtiapi_FreeCCB( pmcsc, pccb );
3708 ccb->ccb_h.status = CAM_REQ_CMP;
3714 * If assigned pDevHandle is not available
3715 * then there is no need to send it to StartIO()
3717 /* TODO: Add check for deviceType */
3718 if ( pccb->targetId < 0 || pccb->targetId >= maxTargets )
3720 agtiapi_FreeCCB( pmcsc, pccb );
3721 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3726 TID = INDEX( pmcsc, pccb->targetId );
3727 if ( (TID >= pmcsc->devDiscover) ||
3728 !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) )
3730 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, "
3731 "target %d tid %d/%d "
3732 "card %p ERROR pccb %p\n",
3739 agtiapi_FreeCCB( pmcsc, pccb );
3740 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3745 /* TODO: add indirect handling */
3746 /* set the flag correctly based on Indiret SMP request and response */
3748 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
3749 "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
3751 pccb->targetId, TID,
3754 tiExpDevHandle = pccb->devHandle;
3755 tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo;
3756 tiExpPortalContext = &tiExpPortalInfo->tiPortalContext;
3757 /* Look for the expander associated with the ses device */
3758 status = tiINIGetExpander( &pmcsc->tiRoot,
3763 if ( status != tiSuccess )
3765 AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander "
3767 agtiapi_FreeCCB( pmcsc, pccb );
3768 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3774 /* this is expander device */
3775 pccb->devHandle = tiExpDevHandle;
3776 /* put the request in send queue */
3777 agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail
3778 AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb );
3780 agtiapi_StartSMP( pmcsc );
3786 /******************************************************************************
3790 Processing completed ccbs
3792 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
3793 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
3796 ******************************************************************************/
3797 STATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3799 pccb_t pccb_curr = pccb;
3802 tiIniScsiCmnd_t *cmnd;
3805 AGTIAPI_IO("agtiapi_Done: start\n");
3808 /* start from 1st ccb in the chain */
3809 pccb_next = pccb_curr->pccbNext;
3811 if (agtiapi_CheckError(pmcsc, pccb_curr) != 0)
3813 /* send command back and release the ccb */
3814 cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd;
3816 if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC)
3818 AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb "
3819 "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd,
3823 CMND_DMA_UNMAP(pmcsc, ccb);
3825 /* send the request back to the CAM */
3826 ccb = pccb_curr->ccb;
3827 agtiapi_FreeCCB(pmcsc, pccb_curr);
3830 pccb_curr = pccb_next;
3835 /******************************************************************************
3839 Processing completed ccbs
3841 struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure
3842 ccb_t *pccb (IN) A pointer to the driver's own CCB, not
3846 ******************************************************************************/
3847 STATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3849 pccb_t pccb_curr = pccb;
3854 AGTIAPI_PRINTK("agtiapi_SMPDone: start\n");
3858 /* start from 1st ccb in the chain */
3859 pccb_next = pccb_curr->pccbNext;
3861 if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0)
3863 CMND_DMA_UNMAP(pmcsc, ccb);
3865 /* send the request back to the CAM */
3866 ccb = pccb_curr->ccb;
3867 agtiapi_FreeSMPCCB(pmcsc, pccb_curr);
3871 pccb_curr = pccb_next;
3874 AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n");
3878 /******************************************************************************
3882 Utility function for dumping in hex
3884 const char *ptitle (IN) A string to be printed
3885 bit8 *pbuf (IN) A pointer to a buffer to be printed.
3886 int len (IN) The lengther of the buffer
3889 ******************************************************************************/
3890 void agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len)
3893 AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len);
3896 AGTIAPI_PRINTK("pbuf is NULL\n");
3899 for (i = 0; i < len; )
3903 AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1],
3904 pbuf[i+2], pbuf[i+3] );
3909 AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]);
3913 AGTIAPI_PRINTK("\n");
3917 /******************************************************************************
3918 agtiapi_CheckError()
3921 Processes status pertaining to the ccb -- whether it was
3922 completed successfully, aborted, or error encountered.
3924 ag_card_t *pCard (IN) Pointer to HBA data structure
3925 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
3927 0 - the command retry is required
3928 1 - the command process is completed
3931 ******************************************************************************/
3932 STATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb)
3934 ag_device_t *pDevice;
3935 // union ccb * ccb = pccb->ccb;
3943 AGTIAPI_IO("agtiapi_CheckError: start\n");
3946 /* shouldn't be here but just in case we do */
3947 AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb);
3948 agtiapi_FreeCCB(pmcsc, pccb);
3954 if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets)
3956 if (pmcsc->pWWNList != NULL)
3958 TID = INDEX(pmcsc, pccb->targetId);
3959 if (TID < maxTargets)
3961 pDevice = &pmcsc->pDevList[TID];
3962 if (pDevice != NULL)
3971 AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n");
3972 agtiapi_FreeCCB(pmcsc, pccb);
3977 ccb->csio.scsi_status = pccb->scsiStatus;
3979 if(pDevice->CCBCount > 0){
3980 atomic_subtract_int(&pDevice->CCBCount,1);
3982 AG_LOCAL_LOCK(&pmcsc->freezeLock);
3983 if(pmcsc->freezeSim == agTRUE)
3985 pmcsc->freezeSim = agFALSE;
3986 xpt_release_simq(pmcsc->sim, 1);
3988 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
3990 switch (pccb->ccbStatus)
3993 AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb);
3995 if (pccb->scsiStatus == SCSI_STATUS_OK)
3997 ccb->ccb_h.status = CAM_REQ_CMP;
4000 if (pccb->scsiStatus == SCSI_TASK_ABORTED)
4002 ccb->ccb_h.status = CAM_REQ_ABORTED;
4006 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
4008 if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION)
4010 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4016 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb);
4017 /* resid is ignored for this condition */
4018 ccb->csio.resid = 0;
4019 ccb->ccb_h.status = CAM_DATA_RUN_ERR;
4022 AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb);
4023 ccb->csio.resid = pccb->scsiStatus;
4024 ccb->ccb_h.status = CAM_REQ_CMP;
4025 ccb->csio.scsi_status = SCSI_STATUS_OK;
4029 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4030 pccb, pccb->scsiStatus, pccb->targetId );
4031 if (pccb->scsiStatus == tiDeviceBusy)
4033 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n",
4035 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
4036 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4037 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)
4039 ccb->ccb_h.status |= CAM_DEV_QFRZN;
4040 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
4043 else if(pccb->scsiStatus == tiBusy)
4045 AG_LOCAL_LOCK(&pmcsc->freezeLock);
4046 if(pmcsc->freezeSim == agFALSE)
4048 pmcsc->freezeSim = agTRUE;
4049 xpt_freeze_simq(pmcsc->sim, 1);
4051 AG_LOCAL_UNLOCK(&pmcsc->freezeLock);
4052 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
4053 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
4055 else if (pccb->scsiStatus == tiDetailNoLogin)
4057 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4058 "tiDetailNoLogin ERROR\n", pccb );
4059 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
4061 else if (pccb->scsiStatus == tiDetailNotValid)
4063 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4064 "tiDetailNotValid ERROR\n", pccb );
4065 ccb->ccb_h.status = CAM_REQ_INVALID;
4067 else if (pccb->scsiStatus == tiDetailAbortLogin)
4069 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4070 "tiDetailAbortLogin ERROR\n", pccb );
4071 ccb->ccb_h.status = CAM_REQ_ABORTED;
4073 else if (pccb->scsiStatus == tiDetailAbortReset)
4075 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4076 "tiDetailAbortReset ERROR\n", pccb );
4077 ccb->ccb_h.status = CAM_REQ_ABORTED;
4079 else if (pccb->scsiStatus == tiDetailAborted)
4081 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4082 "tiDetailAborted ERROR\n", pccb );
4083 ccb->ccb_h.status = CAM_REQ_ABORTED;
4085 else if (pccb->scsiStatus == tiDetailOtherError)
4087 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4088 "tiDetailOtherError ERROR\n", pccb );
4089 ccb->ccb_h.status = CAM_REQ_ABORTED;
4093 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4094 pccb, pccb->scsiStatus, pccb->targetId );
4095 if (pccb->scsiStatus == tiDetailDifAppTagMismatch)
4097 AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - "
4098 "tiDetailDifAppTagMismatch\n", pccb );
4099 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4101 else if (pccb->scsiStatus == tiDetailDifRefTagMismatch)
4103 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4104 "tiDetailDifRefTagMismatch\n", pccb );
4105 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4107 else if (pccb->scsiStatus == tiDetailDifCrcMismatch)
4109 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - "
4110 "tiDetailDifCrcMismatch\n", pccb );
4111 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4114 #ifdef HIALEAH_ENCRYPTION
4115 case tiIOEncryptError:
4116 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n",
4117 pccb, pccb->scsiStatus, pccb->targetId );
4118 if (pccb->scsiStatus == tiDetailDekKeyCacheMiss)
4120 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4121 "tiDetailDekKeyCacheMiss ERROR\n",
4122 __FUNCTION__, pccb );
4123 ccb->ccb_h.status = CAM_REQ_ABORTED;
4124 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4126 else if (pccb->scsiStatus == tiDetailDekIVMismatch)
4128 AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - "
4129 "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb );
4130 ccb->ccb_h.status = CAM_REQ_ABORTED;
4131 agtiapi_HandleEncryptedIOFailure(pDevice, pccb);
4136 AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n",
4137 pccb, pccb->ccbStatus, pccb->targetId );
4138 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4146 /******************************************************************************
4147 agtiapi_SMPCheckError()
4150 Processes status pertaining to the ccb -- whether it was
4151 completed successfully, aborted, or error encountered.
4153 ag_card_t *pCard (IN) Pointer to HBA data structure
4154 ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB
4156 0 - the command retry is required
4157 1 - the command process is completed
4160 ******************************************************************************/
4161 STATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb )
4163 union ccb * ccb = pccb->ccb;
4165 AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n");
4169 /* shouldn't be here but just in case we do */
4170 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n",
4172 agtiapi_FreeSMPCCB(pmcsc, pccb);
4176 switch (pccb->ccbStatus)
4179 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n",
4182 ccb->ccb_h.status = CAM_REQ_CMP;
4185 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n",
4188 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4191 AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d "
4196 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
4205 /******************************************************************************
4206 agtiapi_HandleEncryptedIOFailure():
4213 ******************************************************************************/
4214 void agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb)
4217 AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n");
4221 /******************************************************************************
4227 struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure
4228 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4232 ******************************************************************************/
4233 STATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb)
4236 pccb->flags = ACTIVE | AGTIAPI_RETRY;
4237 pccb->ccbStatus = 0;
4238 pccb->scsiStatus = 0;
4239 pccb->startTime = ticks;
4241 AGTIAPI_PRINTK( "agtiapi_Retry: start\n" );
4242 AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb,
4243 pccb->retryCount, pccb->flags );
4245 agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail
4246 AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb);
4251 /******************************************************************************
4255 Dump CCB for debuging
4257 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4260 ******************************************************************************/
4261 STATIC void agtiapi_DumpCCB(ccb_t *pccb)
4263 AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n",
4268 AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n",
4273 AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n",
4274 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4275 pccb->numSgElements);
4276 AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n",
4279 AGTIAPI_PRINTK("tiSuperScsiRequest:\n");
4280 AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n",
4281 pccb->tiSuperScsiRequest.scsiCmnd.expDataLength,
4282 pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute);
4283 AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n",
4284 pccb->tiSuperScsiRequest.scsiCmnd.cdb[0],
4285 pccb->tiSuperScsiRequest.scsiCmnd.cdb[1],
4286 pccb->tiSuperScsiRequest.scsiCmnd.cdb[2],
4287 pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]);
4288 AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n",
4289 pccb->tiSuperScsiRequest.scsiCmnd.cdb[4],
4290 pccb->tiSuperScsiRequest.scsiCmnd.cdb[5],
4291 pccb->tiSuperScsiRequest.scsiCmnd.cdb[6],
4292 pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]);
4293 AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, "
4295 pccb->tiSuperScsiRequest.scsiCmnd.cdb[8],
4296 pccb->tiSuperScsiRequest.scsiCmnd.cdb[9],
4297 pccb->tiSuperScsiRequest.scsiCmnd.cdb[10],
4298 pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] );
4299 AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n",
4300 pccb->tiSuperScsiRequest.agSgl1.upper,
4301 pccb->tiSuperScsiRequest.agSgl1.lower,
4302 pccb->tiSuperScsiRequest.agSgl1.len,
4303 pccb->tiSuperScsiRequest.agSgl1.type);
4306 /******************************************************************************
4307 agtiapi_eh_HostReset()
4310 A new error handler of Host Reset command.
4312 scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset
4317 ******************************************************************************/
4318 int agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd )
4320 AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n",
4325 printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" );
4326 return tiInvalidHandle;
4330 agtiapi_LogEvent( pmcsc,
4331 IOCTL_EVT_SEV_INFORMATIONAL,
4335 "agtiapi_eh_HostReset! " );
4338 return agtiapi_DoSoftReset( pmcsc );
4342 /******************************************************************************
4346 Put ccb in ccb queue at the tail
4348 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4349 pccb_t *phead (IN) Double pointer to ccb queue head
4350 pccb_t *ptail (IN) Double pointer to ccb queue tail
4351 ccb_t *pccb (IN) Poiner to a ccb to be queued
4354 Put the ccb to the tail of queue
4355 ******************************************************************************/
4356 STATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc,
4359 #ifdef AGTIAPI_LOCAL_LOCK
4364 AGTIAPI_IO( "agtiapi_QueueCCB: start\n" );
4365 AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead );
4366 if (phead == NULL || ptail == NULL)
4368 panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail );
4370 pccb->pccbNext = NULL;
4371 AG_LOCAL_LOCK( mutex );
4374 //WARN_ON(*ptail != NULL); /* critical, just get more logs */
4379 //WARN_ON(*ptail == NULL); /* critical, just get more logs */
4381 (*ptail)->pccbNext = pccb;
4384 AG_LOCAL_UNLOCK( mutex );
4389 /******************************************************************************
4400 ******************************************************************************/
4401 static int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb)
4403 pccb_t pccb = agNULL; /* call dequeue */
4404 int status = tiSuccess;
4405 int targetID = xpt_path_target_id(ccb->ccb_h.path);
4407 AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n");
4410 if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL)
4412 AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n");
4413 ccb->ccb_h.status = CAM_REQ_CMP;
4417 pccb->pmcsc = pmcsc;
4419 /* initialize Command Control Block (CCB) */
4420 pccb->targetId = targetID;
4421 pccb->ccb = ccb; /* for struct scsi_cmnd */
4423 status = agtiapi_PrepareSMPSGList(pmcsc, pccb);
4425 if (status != tiSuccess)
4427 AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n");
4428 agtiapi_FreeCCB(pmcsc, pccb);
4429 if (status == tiReject)
4431 ccb->ccb_h.status = CAM_REQ_INVALID;
4435 ccb->ccb_h.status = CAM_REQ_CMP;
4444 /******************************************************************************
4445 agtiapi_SetLunField()
4448 Set LUN field based on different address mode
4450 ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB
4453 ******************************************************************************/
4454 void agtiapi_SetLunField(ccb_t *pccb)
4458 pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun;
4460 // AGTIAPI_PRINTK("agtiapi_SetLunField: start\n");
4462 switch (pccb->addrMode)
4464 case AGTIAPI_PERIPHERAL:
4466 *pchar = (U08)pccb->lun;
4468 case AGTIAPI_VOLUME_SET:
4469 *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) |
4470 (U08)((pccb->lun >> 8) & 0x3F);
4471 *pchar = (U08)pccb->lun;
4473 case AGTIAPI_LUN_ADDR:
4474 *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) |
4476 *pchar = (U08)pccb->lun;
4484 /*****************************************************************************
4488 Free a ccb and put it back to ccbFreeList.
4490 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4491 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4495 *****************************************************************************/
4496 STATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4498 union ccb *ccb = pccb->ccb;
4499 bus_dmasync_op_t op;
4501 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4502 AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb );
4504 #ifdef AGTIAPI_TEST_EPL
4505 tiEncrypt_t *encrypt;
4508 agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb );
4510 if (pccb->sgList != agNULL)
4512 AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" );
4516 AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" );
4519 /* set data transfer direction */
4520 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4522 op = BUS_DMASYNC_POSTWRITE;
4526 op = BUS_DMASYNC_POSTREAD;
4529 if (pccb->numSgElements == 0)
4532 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" );
4534 else if (pccb->numSgElements == 1)
4536 AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" );
4537 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4538 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4539 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4543 AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" );
4544 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4545 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4546 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4549 #ifdef AGTIAPI_TEST_DPL
4550 if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) {
4552 memset( (char *) pccb->dplPtr,
4554 MAX_DPL_REGIONS * sizeof(dplaRegion_t) );
4555 pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE;
4556 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0;
4557 pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0;
4561 #ifdef AGTIAPI_TEST_EPL
4562 encrypt = &pccb->tiSuperScsiRequest.Encrypt;
4563 if (encrypt->enableEncryptionPerLA == TRUE) {
4564 encrypt->enableEncryptionPerLA = FALSE;
4565 encrypt->EncryptionPerLAAddrLo = 0;
4566 encrypt->EncryptionPerLAAddrHi = 0;
4570 #ifdef ENABLE_SATA_DIF
4571 if (pccb->holePtr && pccb->dmaHandleHole)
4572 pci_free_consistent( pmcsc->pCardInfo->pPCIDev,
4575 pccb->dmaHandleHole );
4577 pccb->dmaHandleHole = 0;
4581 pccb->retryCount = 0;
4582 pccb->ccbStatus = 0;
4583 pccb->scsiStatus = 0;
4584 pccb->startTime = 0;
4585 pccb->dmaHandle = 0;
4586 pccb->numSgElements = 0;
4587 pccb->tiIORequest.tdData = 0;
4588 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4590 #ifdef HIALEAH_ENCRYPTION
4592 agtiapi_CleanupEncryptedIO(pmcsc, pccb);
4597 pccb->pccbIO = NULL;
4598 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4599 pmcsc->ccbFreeList = (caddr_t *)pccb;
4603 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4608 /******************************************************************************
4612 Flush all in processed ccbs.
4614 ag_card_t *pCard (IN) Pointer to HBA data structure
4615 U32 flag (IN) Flag to call back
4618 ******************************************************************************/
4619 STATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag )
4624 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" );
4625 for( pccb = (pccb_t)pCard->ccbChainList;
4627 pccb = pccb->pccbChainNext ) {
4628 if( pccb->flags == 0 )
4630 // printf( "agtiapi_FlushCCBs: nothing, continue \n" );
4634 if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) )
4636 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" );
4637 agtiapi_FreeTMCCB( pCard, pccb );
4641 if ( pccb->flags & TAG_SMP )
4643 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" );
4644 agtiapi_FreeSMPCCB( pCard, pccb );
4648 AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" );
4649 agtiapi_FreeCCB( pCard, pccb );
4652 CMND_DMA_UNMAP( pCard, ccb );
4653 if( flag == AGTIAPI_CALLBACK ) {
4654 ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
4662 /*****************************************************************************
4663 agtiapi_FreeSMPCCB()
4666 Free a ccb and put it back to ccbFreeList.
4668 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4669 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4673 *****************************************************************************/
4674 STATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4676 union ccb *ccb = pccb->ccb;
4677 bus_dmasync_op_t op;
4679 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4680 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb);
4682 /* set data transfer direction */
4683 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
4685 op = BUS_DMASYNC_POSTWRITE;
4689 op = BUS_DMASYNC_POSTREAD;
4692 if (pccb->numSgElements == 0)
4695 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n");
4697 else if (pccb->numSgElements == 1)
4699 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n");
4700 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4701 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4702 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4706 AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n");
4707 //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD
4708 bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op);
4709 bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap);
4712 /*dma api cleanning*/
4714 pccb->retryCount = 0;
4715 pccb->ccbStatus = 0;
4716 pccb->startTime = 0;
4717 pccb->dmaHandle = 0;
4718 pccb->numSgElements = 0;
4719 pccb->tiIORequest.tdData = 0;
4720 memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN);
4724 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4725 pmcsc->ccbFreeList = (caddr_t *)pccb;
4729 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4734 /*****************************************************************************
4738 Free a ccb and put it back to ccbFreeList.
4740 struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure
4741 pccb_t pccb (IN) A pointer to the driver's own CCB, not
4745 *****************************************************************************/
4746 STATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb)
4748 AG_LOCAL_LOCK(&pmcsc->ccbLock);
4749 AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb);
4751 pccb->retryCount = 0;
4752 pccb->ccbStatus = 0;
4753 pccb->scsiStatus = 0;
4754 pccb->startTime = 0;
4755 pccb->dmaHandle = 0;
4756 pccb->numSgElements = 0;
4757 pccb->tiIORequest.tdData = 0;
4758 memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN);
4761 pccb->pccbIO = NULL;
4762 pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList;
4763 pmcsc->ccbFreeList = (caddr_t *)pccb;
4765 AG_LOCAL_UNLOCK(&pmcsc->ccbLock);
4768 /******************************************************************************
4769 agtiapi_CheckAllVectors():
4775 Currently, not used.
4776 ******************************************************************************/
4777 void agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context )
4779 #ifdef SPC_MSIX_INTR
4780 if (!agtiapi_intx_mode)
4784 for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++)
4785 if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE)
4786 tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context);
4789 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4790 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4792 if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE)
4793 tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context);
4799 /******************************************************************************
4803 Check call back function returned event for process completion
4805 struct agtiapi_softc *pCard Pointer to card data structure
4806 U32 milisec (IN) Waiting time for expected event
4807 U32 flag (IN) Flag of the event to check
4808 U32 *pStatus (IN) Pointer to status of the card or port to check
4810 AGTIAPI_SUCCESS - event comes as expected
4811 AGTIAPI_FAIL - event not coming
4814 ******************************************************************************/
4815 agBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard,
4818 volatile U32 *pStatus )
4820 U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource.
4821 initiatorOption.usecsPerTick / 1000;
4822 S32 i = milisec/msecsPerTick;
4823 AG_GLOBAL_ARG( _flags );
4825 AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" );
4826 AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" );
4832 if (*pStatus & TASK_MANAGEMENT)
4834 if (*pStatus & AGTIAPI_CB_DONE)
4836 if( flag == 0 || *pStatus & flag )
4837 return AGTIAPI_SUCCESS;
4839 return AGTIAPI_FAIL;
4842 else if (pCard->flags & AGTIAPI_CB_DONE)
4844 if( flag == 0 || *pStatus & flag )
4845 return AGTIAPI_SUCCESS;
4847 return AGTIAPI_FAIL;
4850 agtiapi_DelayMSec( msecsPerTick );
4852 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags );
4853 tiCOMTimerTick( &pCard->tiRoot );
4855 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
4856 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags );
4861 if( *pStatus & TASK_MANAGEMENT )
4862 *pStatus |= TASK_TIMEOUT;
4864 return AGTIAPI_FAIL;
4868 /******************************************************************************
4869 agtiapi_DiscoverTgt()
4872 Discover available devices
4874 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
4877 ******************************************************************************/
4878 STATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard)
4881 ag_portal_data_t *pPortalData;
4884 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n");
4885 AGTIAPI_FLOW("agtiapi_DiscoverTgt\n");
4886 AGTIAPI_INIT("agtiapi_DiscoverTgt\n");
4888 pPortalData = pCard->pPortalData;
4889 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4891 pCard->flags &= ~AGTIAPI_CB_DONE;
4892 if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4894 if (pCard->flags & AGTIAPI_INIT_TIME)
4896 if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY,
4897 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4899 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for "
4901 pPortalData, count );
4903 * There is no need to spend time on discovering device
4904 * if port is not ready to do so.
4913 AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n",
4915 AGTIAPI_INIT_DELAY(1000);
4917 pCard->flags &= ~AGTIAPI_CB_DONE;
4918 if (tiINIDiscoverTargets(&pCard->tiRoot,
4919 &pPortalData->portalInfo.tiPortalContext,
4920 FORCE_PERSISTENT_ASSIGN_MASK)
4922 AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n");
4925 * Should wait till discovery completion to start
4926 * next portal. However, lower layer have issue on
4927 * multi-portal case under Linux.
4931 pPortalData = pCard->pPortalData;
4932 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4934 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY))
4936 if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE,
4937 &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL)
4939 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE))
4940 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, "
4943 PORTAL_STATUS(pPortalData) );
4945 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not "
4946 "completed, status 0x%x\n",
4947 pPortalData, PORTAL_STATUS(pPortalData) );
4950 AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target "
4957 * Calling to get device handle should be done per portal based
4958 * and better right after discovery is done. However, lower iscsi
4959 * layer may not returns discovery complete in correct sequence or we
4960 * ran out time. We get device handle for all portals together
4961 * after discovery is done or timed out.
4963 pPortalData = pCard->pPortalData;
4964 for (count = 0; count < pCard->portCount; count++, pPortalData++)
4967 * We try to get device handle no matter
4968 * if discovery is completed or not.
4970 if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)
4974 for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++)
4976 if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0)
4978 agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY);
4981 if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) ||
4982 (pCard->tgtCount > 0))
4983 PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE |
4984 AGTIAPI_PORT_LINK_UP );
4994 /******************************************************************************
4998 Prepares CCB including DMA map.
5000 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5001 ccb_hdr_t *hdr (IN) Pointer to the CCB header
5003 U32 max_ccb (IN) count
5007 ******************************************************************************/
5008 STATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard,
5022 AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n");
5023 offset = tid * AGTIAPI_CCB_PER_DEVICE;
5024 nsegs = AGTIAPI_NSEGS;
5025 sgl_sz = sizeof(tiSgl_t) * nsegs;
5026 AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) "
5027 "%lu, max_ccb %d\n",
5034 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5035 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5037 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n");
5039 memset((void *)hdr, 0, size);
5040 hdr->next = pCard->ccbAllocList;
5041 pCard->ccbAllocList = hdr;
5043 AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n");
5045 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5047 for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz))
5049 pccb->tiIORequest.osData = (void *)pccb;
5052 * Initially put all the ccbs on the free list
5053 * in addition to chainlist.
5054 * ccbChainList is a list of all available ccbs
5055 * (free/active everything)
5057 pccb->pccbChainNext = (pccb_t)pCard->ccbChainList;
5058 pccb->pccbNext = (pccb_t)pCard->ccbFreeList;
5060 pCard->ccbChainList = (caddr_t *)pccb;
5061 pCard->ccbFreeList = (caddr_t *)pccb;
5064 #ifdef AGTIAPI_ALIGN_CHECK
5066 AGTIAPI_PRINTK("pccb = %p\n", pccb);
5067 if (pccb->devHandle & 0x63)
5068 AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle);
5069 if (&pccb->lun & 0x63)
5070 AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun);
5071 if (&pccb->targetId & 0x63)
5072 AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId);
5073 if (&pccb->ccbStatus & 0x63)
5074 AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus);
5075 if (&pccb->scsiStatus & 0x63)
5076 AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus);
5077 if (&pccb->dataLen & 0x63)
5078 AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen);
5079 if (&pccb->senseLen & 0x63)
5080 AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen);
5081 if (&pccb->numSgElements & 0x63)
5082 AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements);
5083 if (&pccb->retryCount & 0x63)
5084 AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount);
5085 if (&pccb->flags & 0x63)
5086 AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags);
5087 if (&pccb->pSenseData & 0x63)
5088 AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData);
5089 if (&pccb->sgList[0] & 0x63)
5090 AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]);
5091 if (&pccb->pccbNext & 0x63)
5092 AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext);
5093 if (&pccb->pccbChainNext & 0x63)
5094 AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext);
5095 if (&pccb->cmd & 0x63)
5096 AGTIAPI_PRINTK("command = %p\n", &pccb->cmd);
5097 if( &pccb->startTime & 0x63 )
5098 AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime );
5099 if (&pccb->tiIORequest & 0x63)
5100 AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest);
5101 if (&pccb->tdIOReqBody & 0x63)
5102 AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody);
5103 if (&pccb->tiSuperScsiRequest & 0x63)
5104 AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n",
5105 &pccb->tiSuperScsiRequest );
5107 if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) !=
5110 AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n");
5113 /* assigns tiSgl_t memory to pccb */
5114 pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz));
5115 pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz);
5117 pccb->pccbIO = NULL;
5118 pccb->startTime = 0;
5121 #ifdef AGTIAPI_ALIGN_CHECK
5122 AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz);
5127 /******************************************************************************
5131 Create and initialize per card based CCB pool.
5133 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5134 int tgtCount (IN) Count
5136 Total number of ccb allocated
5138 ******************************************************************************/
5139 STATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid)
5142 U32 max_ccb, size, ccb_sz, hdr_sz;
5143 int no_allocs = 0, i;
5144 ccb_hdr_t *hdr = NULL;
5146 AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n");
5147 AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5148 AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid);
5150 #ifndef HOTPLUG_SUPPORT
5151 if (pCard->tgtCount > AGSA_MAX_INBOUND_Q)
5154 if (tgtCount > AGSA_MAX_INBOUND_Q)
5155 tgtCount = AGSA_MAX_INBOUND_Q;
5158 max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR
5159 ccb_sz = roundup2(AGTIAPI_CCB_SIZE, cache_line_size());
5160 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5161 size = ccb_sz * max_ccb + hdr_sz;
5163 for (i = 0; i < (1 << no_allocs); i++)
5165 hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT );
5168 panic( "agtiapi_InitCCBs: bug!!!\n" );
5172 agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid );
5181 #ifdef LINUX_PERBI_SUPPORT
5182 /******************************************************************************
5183 agtiapi_GetWWNMappings()
5186 Get the mappings from target IDs to WWNs, if any.
5187 Store them in the WWN_list array, indexed by target ID.
5188 Leave the devListIndex field blank; this will be filled-in later.
5190 ag_card_t *pCard (IN) Pointer to HBA data structure
5191 ag_mapping_t *pMapList (IN) Pointer to mapped device list
5193 Note: The boot command line parameters are used to load the
5194 mapping information, which is contained in the system
5196 ******************************************************************************/
5197 STATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard,
5198 ag_mapping_t *pMapList )
5202 ag_tgt_map_t *pWWNList;
5203 ag_slr_map_t *pSLRList;
5204 ag_device_t *pDevList;
5207 panic( "agtiapi_GetWWNMappings: no pCard \n" );
5209 AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" );
5211 pWWNList = pCard->pWWNList;
5212 pSLRList = pCard->pSLRList;
5213 pDevList = pCard->pDevList;
5214 pCard->numTgtHardMapped = 0;
5215 devDisc = pCard->devDiscover;
5217 pWWNList[devDisc-1].devListIndex = maxTargets;
5218 pSLRList[devDisc-1].localeNameLen = -2;
5219 pSLRList[devDisc-1].remoteNameLen = -2;
5220 pDevList[devDisc-1].targetId = maxTargets;
5223 * Get the mappings from holding area which contains
5224 * the input of the system file and store them
5225 * in the WWN_list array, indexed by target ID.
5227 for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) {
5228 pWWNList[lIdx].flags = 0;
5229 pWWNList[lIdx].devListIndex = maxTargets;
5230 pSLRList[lIdx].localeNameLen = -1;
5231 pSLRList[lIdx].remoteNameLen = -1;
5234 // this is where we would propagate values fed to pMapList
5236 } /* agtiapi_GetWWNMappings */
5241 /******************************************************************************
5242 agtiapi_FindWWNListNext()
5244 finds first available new (unused) wwn list entry
5247 ag_tgt_map_t *pWWNList Pointer to head of wwn list
5248 int lstMax Number of entries in WWNList
5250 index into WWNList indicating available entry space;
5251 if available entry space is not found, return negative value
5252 ******************************************************************************/
5253 STATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax )
5257 for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ )
5259 if ( pWWNList[lLstIdx].devListIndex == lstMax &&
5260 pWWNList[lLstIdx].targetLen == 0 )
5262 AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n",
5264 pWWNList[lLstIdx].devListIndex,
5265 pWWNList[lLstIdx].targetLen,
5266 pWWNList[lLstIdx].portId,
5275 /******************************************************************************
5276 agtiapi_GetDevHandle()
5279 Get device handle. Handles will be placed in the
5280 devlist array with same order as TargetList provided and
5281 will be mapped to a scsi target id and registered to OS later.
5283 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5284 ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure
5285 U32 eType (IN) Port event
5286 U32 eStatus (IN) Port event status
5288 Number of device handle slot present
5290 The sequence of device handle will match the sequence of taregt list
5291 ******************************************************************************/
5292 STATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard,
5293 ag_portal_info_t *pPortalInfo,
5297 ag_device_t *pDevice;
5298 // tiDeviceHandle_t *agDev[pCard->devDiscover];
5299 tiDeviceHandle_t **agDev;
5300 int devIdx, szdv, devTotal, cmpsetRtn;
5301 int lDevIndex = 0, lRunScanFlag = FALSE;
5303 tiPortInfo_t portInfT;
5304 ag_device_t lTmpDevice;
5305 ag_tgt_map_t *pWWNList;
5306 ag_slr_map_t *pSLRList;
5311 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" );
5312 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n",
5313 pCard->devDiscover, pCard->tgtCount );
5314 AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo );
5315 AGTIAPI_INIT_DELAY( 1000 );
5317 agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover,
5318 M_PMC_MDEV, M_ZERO | M_NOWAIT);
5321 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" );
5325 lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover,
5326 M_PMC_MFLG, M_ZERO | M_NOWAIT );
5327 if (lDevFlags == NULL)
5329 free((caddr_t)agDev, M_PMC_MDEV);
5330 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" );
5334 pWWNList = pCard->pWWNList;
5335 pSLRList = pCard->pSLRList;
5337 memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover );
5338 memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover );
5340 // get device handles
5341 devTotal = tiINIGetDeviceHandles( &pCard->tiRoot,
5342 &pPortalInfo->tiPortalContext,
5343 (tiDeviceHandle_t **)agDev,
5344 pCard->devDiscover );
5346 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u "
5347 "status %u card %p pCard->devDiscover %d devTotal %d "
5348 "pPortalInfo->devTotal %d pPortalInfo->devPrev %d "
5349 "AGTIAPI_INIT_TIME %x\n",
5350 pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard,
5351 pCard->devDiscover, devTotal, pPortalInfo->devTotal,
5352 pPortalInfo->devPrev,
5353 pCard->flags & AGTIAPI_INIT_TIME );
5355 // reset devTotal from any previous runs of this
5356 pPortalInfo->devPrev = devTotal;
5357 pPortalInfo->devTotal = devTotal;
5359 AG_LIST_LOCK( &pCard->devListLock );
5361 if ( tiCOMGetPortInfo( &pCard->tiRoot,
5362 &pPortalInfo->tiPortalContext,
5366 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" );
5370 szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
5371 if (szdv > pCard->devDiscover)
5373 szdv = pCard->devDiscover;
5376 // reconstructing dev list via comparison of wwn
5378 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5380 if ( agDev[devIdx] != NULL )
5382 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n",
5383 // devIdx, agDev[devIdx] );
5385 // pack temp device structure for tiINIGetDeviceInfo call
5386 pDevice = &lTmpDevice;
5387 pDevice->devType = DIRECT_DEVICE;
5388 pDevice->pCard = (void *)pCard;
5389 pDevice->flags = ACTIVE;
5390 pDevice->pPortalInfo = pPortalInfo;
5391 pDevice->pDevHandle = agDev[devIdx];
5392 pDevice->qbusy = agFALSE;
5394 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n",
5395 // devIdx, pCard->devDiscover, agDev[devIdx] );
5397 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx],
5398 &pDevice->devInfo );
5400 //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ",
5401 // sizeof(pDevice->targetName),
5402 // pDevice->devInfo.osAddress1,
5403 // pDevice->devInfo.osAddress2 );
5406 wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen );
5408 for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list
5410 if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) &&
5411 pDevice->targetLen > 0 &&
5412 portInfT.localNameLen > 0 &&
5413 portInfT.remoteNameLen > 0 &&
5414 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 &&
5415 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 &&
5416 ( portInfT.localNameLen ==
5417 pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) &&
5418 ( portInfT.remoteNameLen ==
5419 pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) &&
5420 memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName,
5421 pDevice->targetLen ) == 0 &&
5422 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName,
5424 portInfT.localNameLen ) == 0 &&
5425 memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName,
5426 portInfT.remoteName,
5427 portInfT.remoteNameLen ) == 0 )
5429 AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n",
5430 lDevIndex, devIdx, pPortalInfo->portID );
5432 if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) &&
5433 ( pPortalInfo->pDevList[lDevIndex] ==
5434 &pCard->pDevList[lDevIndex] ) ) // active
5437 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n",
5438 lDevIndex, devTotal, pPortalInfo->portID );
5439 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle
5440 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5441 lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved );
5442 if ( lReadRm ) // cleared timeout, now remove count for timer
5444 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for"
5446 lDevIndex, pPortalInfo->portID );
5447 atomic_subtract_16( &pCard->rmChkCt, 1 );
5448 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5451 callout_stop( &pCard->devRmTimer );
5457 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n",
5458 lDevIndex, // reactivate now
5459 devTotal, pPortalInfo->portID );
5461 // pDevice going fresh
5462 lRunScanFlag = TRUE; // scan and clear outstanding removals
5464 // pCard->tgtCount++; ##
5465 pDevice->targetId = lDevIndex;
5466 pDevice->portalId = pPortalInfo->portID;
5468 memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) );
5469 agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex];
5470 if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 )
5472 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB "
5473 "tgtCnt %d ERROR!\n", pCard->tgtCount );
5474 AG_LIST_UNLOCK( &pCard->devListLock );
5475 free((caddr_t)lDevFlags, M_PMC_MFLG);
5476 free((caddr_t)agDev, M_PMC_MDEV);
5479 pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *)
5480 if ( 0 == lDevFlags[devIdx] )
5482 pPortalInfo->devTotal++;
5483 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5484 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5488 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle "
5489 "status inspect %d %d %d\n",
5490 lDevFlags[devIdx], devIdx, lDevIndex );
5491 pPortalInfo->devTotal++;
5492 lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used
5493 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used
5499 // end: match this wwn with previous wwn list
5501 // we have an agDev entry, but no pWWNList target for it
5502 if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) )
5503 { // flag dev handle not accounted for yet
5504 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST;
5505 // later, get an empty pDevice and map this agDev.
5506 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n",
5507 // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) );
5512 lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle
5516 // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, "
5517 // "devLstIdx/flags/(WWNL)portId ... \n" );
5518 // review device list for further action needed
5519 for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ )
5521 if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register
5523 int lNextDyad; // find next available dyad entry
5525 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, "
5526 "devIdx %d -- %d \n", devIdx, pCard->devDiscover );
5527 lRunScanFlag = TRUE; // scan and clear outstanding removals
5528 for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ )
5530 if ( pSLRList[lNextDyad].localeNameLen < 0 &&
5531 pSLRList[lNextDyad].remoteNameLen < 0 )
5535 if ( lNextDyad == pCard->devDiscover )
5537 printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" );
5538 AG_LIST_UNLOCK( &pCard->devListLock );
5539 free( (caddr_t)lDevFlags, M_PMC_MFLG );
5540 free( (caddr_t)agDev, M_PMC_MDEV );
5543 // index of new entry
5544 lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover );
5545 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n",
5546 lDevIndex, devTotal, pPortalInfo->portID );
5547 if ( 0 > lDevIndex )
5549 printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" );
5553 pDevice = &pCard->pDevList[lDevIndex];
5555 tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo );
5557 agtiapi_InitCCBs( pCard, 1, lDevIndex );
5559 pDevice->pCard = (void *)pCard;
5560 pDevice->devType = DIRECT_DEVICE;
5562 // begin to populate new WWNList entry
5563 memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen );
5564 pWWNList[lDevIndex].targetLen = pDevice->targetLen;
5566 pWWNList[lDevIndex].flags = SOFT_MAPPED;
5567 pWWNList[lDevIndex].portId = pPortalInfo->portID;
5568 pWWNList[lDevIndex].devListIndex = lDevIndex;
5569 pWWNList[lDevIndex].sasLrIdx = lNextDyad;
5571 pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen;
5572 pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen;
5573 memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen );
5574 memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen );
5575 // end of populating new WWNList entry
5577 pDevice->targetId = lDevIndex;
5579 pDevice->flags = ACTIVE;
5580 pDevice->CCBCount = 0;
5581 pDevice->pDevHandle = agDev[devIdx];
5582 agDev[devIdx]->osData = (void*)pDevice;
5584 pDevice->pPortalInfo = pPortalInfo;
5585 pDevice->portalId = pPortalInfo->portID;
5586 pPortalInfo->pDevList[lDevIndex] = (void*)pDevice;
5587 lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used
5590 if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) &&
5591 !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used
5593 pDevice = &pCard->pDevList[devIdx];
5594 //pDevice->flags &= ~ACTIVE;
5595 if ( ( pDevice->pDevHandle != NULL ||
5596 pPortalInfo->pDevList[devIdx] != NULL ) )
5598 atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device
5600 if (FALSE == lRunScanFlag)
5603 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n",
5604 devIdx, devTotal, pPortalInfo->portID );
5605 // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5;
5606 cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 );
5607 if ( 0 == cmpsetRtn )
5609 AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n",
5614 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5617 // else ... scan coming soon enough anyway, ignore timer for dropout
5620 } // end of for ( devIdx = 0; ...
5622 AG_LIST_UNLOCK( &pCard->devListLock );
5624 free((caddr_t)lDevFlags, M_PMC_MFLG);
5625 free((caddr_t)agDev, M_PMC_MDEV);
5627 if ( TRUE == lRunScanFlag )
5628 agtiapi_clrRmScan( pCard );
5631 } // end agtiapi_GetDevHandle
5633 /******************************************************************************
5639 struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure
5642 ******************************************************************************/
5643 static void agtiapi_scan(struct agtiapi_softc *pmcsc)
5648 AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo);
5650 bus = cam_sim_path(pmcsc->sim);
5652 tid = CAM_TARGET_WILDCARD;
5653 lun = CAM_LUN_WILDCARD;
5655 mtx_lock(&(pmcsc->pCardInfo->pmIOLock));
5656 ccb = xpt_alloc_ccb_nowait();
5659 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5662 if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid,
5663 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
5665 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5670 mtx_unlock(&(pmcsc->pCardInfo->pmIOLock));
5671 pmcsc->dev_scan = agTRUE;
5676 /******************************************************************************
5677 agtiapi_DeQueueCCB()
5680 Remove a ccb from a queue
5682 struct agtiapi_softc *pCard (IN) Pointer to the card structure
5683 pccb_t *phead (IN) Pointer to a head of ccb queue
5684 ccb_t *pccd (IN) Pointer to the ccb to be processed
5686 AGTIAPI_SUCCESS - the ccb is removed from queue
5687 AGTIAPI_FAIL - the ccb is not found from queue
5689 ******************************************************************************/
5691 agtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail,
5692 #ifdef AGTIAPI_LOCAL_LOCK
5698 U32 status = AGTIAPI_FAIL;
5700 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5702 if (pccb == NULL || *phead == NULL)
5704 return AGTIAPI_FAIL;
5707 AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead);
5708 AG_LOCAL_LOCK(lock);
5712 *phead = (*phead)->pccbNext;
5718 pccb->pccbNext = NULL;
5719 status = AGTIAPI_SUCCESS;
5724 while (pccb_curr->pccbNext != NULL)
5726 if (pccb_curr->pccbNext == pccb)
5728 pccb_curr->pccbNext = pccb->pccbNext;
5729 pccb->pccbNext = NULL;
5735 pccb->pccbNext = NULL;
5736 status = AGTIAPI_SUCCESS;
5739 pccb_curr = pccb_curr->pccbNext;
5742 AG_LOCAL_UNLOCK(lock);
5748 STATIC void wwnprintk( unsigned char *name, int len )
5752 for (i = 0; i < len; i++, name++)
5753 AGTIAPI_PRINTK("%02x", *name);
5754 AGTIAPI_PRINTK("\n");
5757 * SAS and SATA behind expander has 8 byte long unique address.
5758 * However, direct connect SATA device use 512 byte unique device id.
5759 * SPC uses remoteName to indicate length of ID and remoteAddress for the
5760 * address of memory that holding ID.
5762 STATIC int wwncpy( ag_device_t *pDevice )
5766 if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 +
5767 pDevice->devInfo.osAddress2)
5769 memcpy(pDevice->targetName,
5770 pDevice->devInfo.remoteName,
5771 pDevice->devInfo.osAddress1);
5772 memcpy(pDevice->targetName + pDevice->devInfo.osAddress1,
5773 pDevice->devInfo.remoteAddress,
5774 pDevice->devInfo.osAddress2);
5775 pDevice->targetLen = pDevice->devInfo.osAddress1 +
5776 pDevice->devInfo.osAddress2;
5777 rc = pDevice->targetLen;
5781 AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n",
5782 pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2);
5789 /******************************************************************************
5790 agtiapi_ReleaseCCBs()
5793 Free all allocated CCB memories for the Host Adapter.
5795 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5798 ******************************************************************************/
5799 STATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard )
5806 AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" );
5808 #if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL )
5812 #ifdef AGTIAPI_TEST_DPL
5813 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5814 pccb = pccb->pccbChainNext)
5816 if(pccb->dplPtr && pccb->dplDma)
5817 pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma);
5821 #ifdef AGTIAPI_TEST_EPL
5822 for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL;
5823 pccb = pccb->pccbChainNext)
5825 if(pccb->epl_ptr && pccb->epl_dma_ptr)
5827 pCard->epl_ctx_pool,
5834 while ((hdr = pCard->ccbAllocList) != NULL)
5836 pCard->ccbAllocList = hdr->next;
5837 hdr_sz = roundup2(sizeof(*hdr), cache_line_size());
5838 pccb = (ccb_t*) ((char*)hdr + hdr_sz);
5839 if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL)
5841 bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap);
5843 free(hdr, M_PMC_MCCB);
5845 pCard->ccbAllocList = NULL;
5851 /******************************************************************************
5855 Timer tick for tisa common layer
5857 void *data (IN) Pointer to the HBA data structure
5860 ******************************************************************************/
5861 STATIC void agtiapi_TITimer( void *data )
5865 struct agtiapi_softc *pCard;
5867 pCard = (struct agtiapi_softc *)data;
5869 // AGTIAPI_PRINTK("agtiapi_TITimer: start\n");
5870 AG_GLOBAL_ARG( flags );
5872 next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource.
5873 loLevelOption.usecsPerTick / USEC_PER_TICK;
5875 if( next_tick == 0 ) /* no timer required */
5877 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
5878 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5880 tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */
5882 //add for polling mode
5884 if( agtiapi_polling_mode )
5885 agtiapi_CheckAllVectors( pCard, tiNonInterruptContext );
5887 callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard );
5889 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
5893 /******************************************************************************
5897 Clears device list entries scheduled for timeout and calls scan
5899 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
5900 ******************************************************************************/
5901 STATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard )
5903 ag_tgt_map_t *pWWNList;
5904 ag_portal_info_t *pPortalInfo;
5905 ag_portal_data_t *pPortalData;
5910 pWWNList = pCard->pWWNList;
5912 AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" );
5914 AG_LIST_LOCK( &pCard->devListLock );
5916 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5918 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5921 break; // trim to who cares
5924 lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved );
5927 pCard->pDevList[lIdx].flags &= ~ACTIVE;
5928 pCard->pDevList[lIdx].pDevHandle = NULL;
5930 pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId];
5931 pPortalInfo = &pPortalData->portalInfo;
5932 pPortalInfo->pDevList[lIdx] = NULL;
5933 AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n",
5934 lIdx, pWWNList[lIdx].portId );
5935 atomic_subtract_16( &pCard->rmChkCt, 1 );
5938 AG_LIST_UNLOCK( &pCard->devListLock );
5940 agtiapi_scan( pCard );
5944 /******************************************************************************
5945 agtiapi_devRmCheck()
5948 Timer tick to check for timeout on missing targets
5949 Removes device list entry when timeout is reached
5951 void *data (IN) Pointer to the HBA data structure
5952 ******************************************************************************/
5953 STATIC void agtiapi_devRmCheck( void *data )
5955 struct agtiapi_softc *pCard;
5956 ag_tgt_map_t *pWWNList;
5957 int lIdx, cmpsetRtn, lRunScanFlag = FALSE;
5961 pCard = ( struct agtiapi_softc * )data;
5964 if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset
5968 if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped
5972 callout_deactivate( &pCard->devRmTimer );
5974 if( pCard->flags & AGTIAPI_SHUT_DOWN )
5976 return; // implicit timer clear
5979 pWWNList = pCard->pWWNList;
5981 AG_LIST_LOCK( &pCard->devListLock );
5982 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
5985 if ( callout_pending(&pCard->devRmTimer) == FALSE )
5987 callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard );
5991 AG_LIST_UNLOCK( &pCard->devListLock );
5995 for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ )
5997 lReadCt = atomic_load_acq_16( &pCard->rmChkCt );
6000 break; // if handled somewhere else, get out
6003 lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved );
6006 if ( 1 == lReadRm ) // timed out
6007 { // no decrement of devRemoved as way to leave a clrRmScan marker
6008 lRunScanFlag = TRUE; // other devRemoved values are about to get wiped
6009 break; // ... so bail out
6013 AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n",
6014 lIdx, lReadRm, lReadCt );
6015 cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved,
6018 if ( 0 == cmpsetRtn )
6020 printf( "agtiapi_devRmCheck: %d decrement already handled\n",
6026 AG_LIST_UNLOCK( &pCard->devListLock );
6028 if ( TRUE == lRunScanFlag )
6029 agtiapi_clrRmScan( pCard );
6033 AG_LIST_UNLOCK( &pCard->devListLock );
6040 static void agtiapi_cam_poll( struct cam_sim *asim )
6045 /*****************************************************************************
6049 Hard or soft reset on the controller and resend any
6050 outstanding requests if needed.
6052 struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
6053 unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
6055 AGTIAPI_SUCCESS - reset successful
6056 AGTIAPI_FAIL - reset failed
6058 *****************************************************************************/
6059 U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
6061 ag_device_t *pDevice;
6065 ag_portal_info_t *pPortalInfo;
6066 ag_portal_data_t *pPortalData;
6070 if( pCard->flags & AGTIAPI_RESET ) {
6071 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
6072 return AGTIAPI_FAIL;
6075 AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
6076 pCard->resetCount );
6078 agtiapi_LogEvent( pCard,
6079 IOCTL_EVT_SEV_INFORMATIONAL,
6083 "Reset initiator time = %d!",
6084 pCard->resetCount + 1 );
6087 pCard->flags |= AGTIAPI_RESET;
6088 pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
6089 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6090 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6092 agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
6094 for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times
6096 if( pCard->flags & AGTIAPI_SOFT_RESET )
6098 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
6099 tiCOMReset( &pCard->tiRoot, tiSoftReset );
6103 AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
6106 lFlagVal = AGTIAPI_RESET_SUCCESS;
6107 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6108 ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
6109 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
6111 if( ret == AGTIAPI_FAIL )
6113 AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
6123 if ( AGTIAPI_FAIL == ret )
6125 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
6130 AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
6134 if( AGTIAPI_FAIL == ret )
6136 printf( "agtiapi_ResetCard: reset ERROR\n" );
6137 pCard->flags &= ~AGTIAPI_INSTALLED;
6138 return AGTIAPI_FAIL;
6141 pCard->flags &= ~AGTIAPI_SOFT_RESET;
6143 // disable all devices
6144 pDevice = pCard->pDevList;
6145 for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
6147 /* if ( pDevice->flags & ACTIVE )
6149 printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
6151 pDevice->flags &= ~ACTIVE;
6154 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
6155 if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
6156 printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
6158 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
6160 if( !pCard->pDevList ) { // try to get a little sanity here
6161 AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
6163 return AGTIAPI_FAIL;
6166 AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
6167 pCard->tgtCount, pCard->portCount );
6168 pCard->tgtCount = 0;
6172 pCard->flags &= ~AGTIAPI_CB_DONE;
6174 pPortalData = pCard->pPortalData;
6176 for( count = 0; count < pCard->portCount; count++ ) {
6177 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6178 pPortalInfo = &pPortalData->portalInfo;
6179 pPortalInfo->portStatus = 0;
6180 pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START |
6181 AGTIAPI_PORT_DISC_READY |
6183 AGTIAPI_DISC_COMPLETE );
6186 sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
6187 if (szdv > pCard->devDiscover)
6189 szdv = pCard->devDiscover;
6192 for( lIdx = 0, loop = 0;
6193 lIdx < szdv && loop < pPortalInfo->devTotal;
6196 pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
6200 pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[]
6201 // don't erase more as the device is scheduled for removal on DPC
6203 AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
6204 pDevice, pPortalInfo->pDevList, lIdx );
6205 pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
6208 for( lIdx = 0; lIdx < maxTargets; lIdx++ )
6209 { // we reconstruct dev list later in get dev handle
6210 pPortalInfo->pDevList[lIdx] = NULL;
6213 for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
6215 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
6218 pPortalInfo->portID,
6219 &pPortalInfo->tiPortalContext );
6221 if( tiCOMPortStart( &pCard->tiRoot,
6222 pPortalInfo->portID,
6223 &pPortalInfo->tiPortalContext,
6227 printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
6228 pPortalInfo->portID );
6232 AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
6233 pPortalInfo->portID );
6237 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6238 tiCOMGetPortInfo( &pCard->tiRoot,
6239 &pPortalInfo->tiPortalContext,
6240 &pPortalInfo->tiPortInfo );
6243 // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED;
6246 AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
6248 if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed !
6250 printf( "agtiapi_ResetCard: error, driver not intstalled? "
6251 "!AGTIAPI_INSTALLED \n" );
6252 return AGTIAPI_FAIL;
6255 AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
6258 agtiapi_LogEvent( pCard,
6259 IOCTL_EVT_SEV_INFORMATIONAL,
6263 "Reset initiator total device = %d!",
6266 pCard->resetCount++;
6268 AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
6269 // clear send & done queue
6270 AG_LOCAL_LOCK( &pCard->sendLock );
6271 pCard->ccbSendHead = NULL;
6272 pCard->ccbSendTail = NULL;
6273 AG_LOCAL_UNLOCK( &pCard->sendLock );
6275 AG_LOCAL_LOCK( &pCard->doneLock );
6276 pCard->ccbDoneHead = NULL;
6277 pCard->ccbDoneTail = NULL;
6278 AG_LOCAL_UNLOCK( &pCard->doneLock );
6280 // clear smp queues also
6281 AG_LOCAL_LOCK( &pCard->sendSMPLock );
6282 pCard->smpSendHead = NULL;
6283 pCard->smpSendTail = NULL;
6284 AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
6286 AG_LOCAL_LOCK( &pCard->doneSMPLock );
6287 pCard->smpDoneHead = NULL;
6288 pCard->smpDoneTail = NULL;
6289 AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
6291 // finished with all reset stuff, now start things back up
6292 tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
6293 pCard->flags |= AGTIAPI_SYS_INTR_ON;
6294 pCard->flags |= AGTIAPI_HAD_RESET;
6295 pCard->flags &= ~AGTIAPI_RESET; // ##
6296 agtiapi_StartIO( pCard );
6297 AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
6298 return AGTIAPI_SUCCESS;
6299 } // agtiapi_ResetCard
6302 /******************************************************************************
6303 agtiapi_ReleaseHBA()
6306 Releases all resources previously acquired to support
6307 a specific Host Adapter, including the I/O Address range,
6308 and unregisters the agtiapi Host Adapter.
6310 device_t dev (IN) - device pointer
6312 always return 0 - success
6314 ******************************************************************************/
6315 int agtiapi_ReleaseHBA( device_t dev )
6318 int thisCard = device_get_unit( dev ); // keeping get_unit call to once
6320 ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ];
6321 struct ccb_setasync csa;
6322 struct agtiapi_softc *pCard;
6323 pCard = device_get_softc( dev );
6324 ag_card_info_t *pCardInfo = pCard->pCardInfo;
6325 ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo;
6327 AG_GLOBAL_ARG(flags);
6329 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" );
6331 if (thisCardInst != pCardInfo)
6333 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p "
6337 panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo "
6345 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard );
6346 pCard->flags |= AGTIAPI_SHUT_DOWN;
6350 if (pCard->flags & AGTIAPI_TIMER_ON)
6352 AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
6353 callout_drain( &pCard->OS_timer );
6354 callout_drain( &pCard->devRmTimer );
6355 callout_drain(&pCard->IO_timer);
6356 AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
6357 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" );
6360 #ifdef HIALEAH_ENCRYPTION
6361 //Release encryption table memory - Fix it
6362 //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED))
6363 //agtiapi_CleanupEncryption(pCard);
6367 * Shutdown the channel so that chip gets frozen
6368 * and it does not do any more pci-bus accesses.
6370 if (pCard->flags & AGTIAPI_SYS_INTR_ON)
6372 tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
6373 pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
6374 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" );
6376 if (pCard->flags & AGTIAPI_INSTALLED)
6378 tiCOMShutDown( &pCard->tiRoot );
6379 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" );
6383 * first release IRQ, so that we do not get any more interrupts
6386 if (pCard->flags & AGTIAPI_IRQ_REQUESTED)
6388 if (!agtiapi_intx_mode)
6391 for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++)
6393 if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0)
6395 bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]);
6396 bus_release_resource( dev,
6402 pci_release_msi(dev);
6404 pCard->flags &= ~AGTIAPI_IRQ_REQUESTED;
6409 for (i = 0; i < MAX_MSIX_NUM_DPC; i++)
6410 tasklet_kill(&pCard->tasklet_dpc[i]);
6412 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n");
6415 // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory
6416 if( pCard->osti_busaddr != 0 ) {
6417 bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp );
6419 if( pCard->osti_mem != NULL ) {
6420 bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp );
6422 if( pCard->osti_dmat != NULL ) {
6423 bus_dma_tag_destroy( pCard->osti_dmat );
6426 /* unmap the mapped PCI memory */
6427 /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */
6428 agtiapi_ReleasePCIMem(thisCardInst);
6430 /* release all ccbs */
6431 if (pCard->ccbTotal)
6433 //calls bus_dmamap_destroy() for all pccbs
6434 agtiapi_ReleaseCCBs(pCard);
6435 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n");
6438 #ifdef HIALEAH_ENCRYPTION
6439 /*release encryption resources - Fix it*/
6442 /*Check that all IO's are completed */
6443 if(atomic_read (&outstanding_encrypted_io_count) > 0)
6445 printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count));
6447 //agtiapi_CleanupEncryptionPools(pCard);
6452 /* release device list */
6453 if( pCard->pDevList ) {
6454 free((caddr_t)pCard->pDevList, M_PMC_MDVT);
6455 pCard->pDevList = NULL;
6456 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n");
6458 #ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI
6459 AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList );
6460 if( pCard->pWWNList ) {
6461 free( (caddr_t)pCard->pWWNList, M_PMC_MTGT );
6462 pCard->pWWNList = NULL;
6463 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n");
6465 if( pCard->pSLRList ) {
6466 free( (caddr_t)pCard->pSLRList, M_PMC_MSLR );
6467 pCard->pSLRList = NULL;
6468 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n");
6472 if (pCard->pPortalData)
6474 free((caddr_t)pCard->pPortalData, M_PMC_MPRT);
6475 pCard->pPortalData = NULL;
6476 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n");
6478 //calls contigfree() or free()
6479 agtiapi_MemFree(pCardInfo);
6480 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n");
6482 #ifdef HOTPLUG_SUPPORT
6483 if (pCard->flags & AGTIAPI_PORT_INITIALIZED)
6485 // agtiapi_FreeDevWorkList(pCard);
6486 AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n");
6491 * TBD, scsi_unregister may release wrong host data structure
6492 * which cause NULL pointer shows up.
6494 if (pCard->flags & AGTIAPI_SCSI_REGISTERED)
6496 pCard->flags &= ~AGTIAPI_SCSI_REGISTERED;
6499 #ifdef AGTIAPI_LOCAL_LOCK
6504 maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort;
6506 for( i = 0; i < maxLocks; i++ )
6508 mtx_destroy(&pCard->STLock[i]);
6510 free(pCard->STLock, M_PMC_MSTL);
6511 pCard->STLock = NULL;
6518 /* reset agtiapi_1st_time if this is the only card */
6519 if (!ag_card_good && !agtiapi_1st_time)
6521 agtiapi_1st_time = 1;
6524 /* for tiSgl_t memeory */
6525 if (pCard->tisgl_busaddr != 0)
6527 bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map);
6529 if (pCard->tisgl_mem != NULL)
6531 bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map);
6533 if (pCard->tisgl_dmat != NULL)
6535 bus_dma_tag_destroy(pCard->tisgl_dmat);
6538 if (pCard->buffer_dmat != agNULL)
6540 bus_dma_tag_destroy(pCard->buffer_dmat);
6543 if (pCard->sim != NULL)
6545 mtx_lock(&thisCardInst->pmIOLock);
6546 xpt_setup_ccb(&csa.ccb_h, pCard->path, 5);
6547 csa.ccb_h.func_code = XPT_SASYNC_CB;
6548 csa.event_enable = 0;
6549 csa.callback = agtiapi_async;
6550 csa.callback_arg = pCard;
6551 xpt_action((union ccb *)&csa);
6552 xpt_free_path(pCard->path);
6553 // if (pCard->ccbTotal == 0)
6554 if (pCard->ccbTotal <= thisCard)
6557 no link up so that simq has not been released.
6558 In order to remove cam, we call this.
6560 xpt_release_simq(pCard->sim, 1);
6562 xpt_bus_deregister(cam_sim_path(pCard->sim));
6563 cam_sim_free(pCard->sim, FALSE);
6564 mtx_unlock(&thisCardInst->pmIOLock);
6566 if (pCard->devq != NULL)
6568 cam_simq_free(pCard->devq);
6572 mtx_destroy( &thisCardInst->pmIOLock );
6573 mtx_destroy( &pCard->sendLock );
6574 mtx_destroy( &pCard->doneLock );
6575 mtx_destroy( &pCard->sendSMPLock );
6576 mtx_destroy( &pCard->doneSMPLock );
6577 mtx_destroy( &pCard->ccbLock );
6578 mtx_destroy( &pCard->devListLock );
6579 mtx_destroy( &pCard->OS_timer_lock );
6580 mtx_destroy( &pCard->devRmTimerLock );
6581 mtx_destroy( &pCard->memLock );
6582 mtx_destroy( &pCard->freezeLock );
6584 destroy_dev( pCard->my_cdev );
6585 memset((void *)pCardInfo, 0, sizeof(ag_card_info_t));
6590 // Called during system shutdown after sync
6591 static int agtiapi_shutdown( device_t dev )
6593 AGTIAPI_PRINTK( "agtiapi_shutdown\n" );
6597 static int agtiapi_suspend( device_t dev ) // Device suspend routine.
6599 AGTIAPI_PRINTK( "agtiapi_suspend\n" );
6603 static int agtiapi_resume( device_t dev ) // Device resume routine.
6605 AGTIAPI_PRINTK( "agtiapi_resume\n" );
6609 static device_method_t agtiapi_methods[] = { // Device interface
6610 DEVMETHOD( device_probe, agtiapi_probe ),
6611 DEVMETHOD( device_attach, agtiapi_attach ),
6612 DEVMETHOD( device_detach, agtiapi_ReleaseHBA ),
6613 DEVMETHOD( device_shutdown, agtiapi_shutdown ),
6614 DEVMETHOD( device_suspend, agtiapi_suspend ),
6615 DEVMETHOD( device_resume, agtiapi_resume ),
6619 static devclass_t pmspcv_devclass;
6621 static driver_t pmspcv_driver = {
6624 sizeof( struct agtiapi_softc )
6627 DRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 );
6628 MODULE_DEPEND( pmspcv, cam, 1, 1, 1 );
6629 MODULE_DEPEND( pmspcv, pci, 1, 1, 1 );
6631 #include <dev/pms/freebsd/driver/common/lxosapi.c>
6632 #include <dev/pms/freebsd/driver/ini/src/osapi.c>
6633 #include <dev/pms/freebsd/driver/common/lxutil.c>
6634 #include <dev/pms/freebsd/driver/common/lxencrypt.c>