1285809Sscottl/******************************************************************************* 2285809Sscottl** 3285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 4285809Sscottl * 5285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 6285809Sscottl*that the following conditions are met: 7285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10285809Sscottl* 11285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 12285809Sscottl* 13285809Sscottl*INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14285809Sscottl*ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 15285809Sscottl*SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 16285809Sscottl*OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 17285809Sscottl*WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 18285809Sscottl*THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 19285809Sscottl** 20285809Sscottl*******************************************************************************/ 21285809Sscottl 22285809Sscottl#include <sys/cdefs.h> 23285809Sscottl__FBSDID("$FreeBSD$"); 24285809Sscottl#include <dev/pms/config.h> 25285809Sscottl 26285809Sscottl#define MAJOR_REVISION 1 27285809Sscottl#define MINOR_REVISION 3 28285809Sscottl#define BUILD_REVISION 10800 29285809Sscottl 30285809Sscottl#include <sys/param.h> // defines used in kernel.h 31285809Sscottl#include <sys/ioccom.h> 32285809Sscottl#include <sys/module.h> 33285809Sscottl#include <sys/systm.h> 34285809Sscottl#include <sys/errno.h> 35285809Sscottl#include <sys/kernel.h> // types used in module initialization 36285809Sscottl#include <sys/conf.h> // cdevsw struct 37285809Sscottl#include <sys/uio.h> // uio struct 38285809Sscottl#include <sys/types.h> 39285809Sscottl#include <sys/malloc.h> 40285809Sscottl#include <sys/bus.h> // structs, prototypes for pci bus stuff 41285809Sscottl#include <machine/bus.h> 42285809Sscottl#include <sys/rman.h> 43285809Sscottl#include <machine/resource.h> 44285809Sscottl#include <vm/vm.h> // 1. for vtophys 45285809Sscottl#include <vm/pmap.h> // 2. for vtophys 46285809Sscottl#include <machine/pmap.h> // 3. for vtophys (yes, three) 47285809Sscottl#include <dev/pci/pcivar.h> // For pci_get macros 48285809Sscottl#include <dev/pci/pcireg.h> 49285809Sscottl#include <sys/endian.h> 50285809Sscottl#include <sys/lock.h> 51285809Sscottl#include <sys/mutex.h> 52285809Sscottl#include <sys/sema.h> 53285809Sscottl#include <sys/queue.h> 54285809Sscottl#include <sys/taskqueue.h> 55285809Sscottl#include <machine/atomic.h> 56285809Sscottl#include <sys/libkern.h> 57285809Sscottl#include <cam/cam.h> 58285809Sscottl#include <cam/cam_ccb.h> 59285809Sscottl#include <cam/cam_debug.h> 60285809Sscottl#include <cam/cam_periph.h> // 61285809Sscottl#include <cam/cam_sim.h> 62285809Sscottl#include <cam/cam_xpt_sim.h> 63285809Sscottl#include <cam/scsi/scsi_all.h> 64285809Sscottl#include <cam/scsi/scsi_message.h> 65285809Sscottl#include <sys/systm.h> 66285809Sscottl#include <sys/types.h> 67285809Sscottl#include <dev/pms/RefTisa/tisa/api/tiapi.h> 68285809Sscottl#include <dev/pms/freebsd/driver/ini/src/agtiapi.h> 69285809Sscottl#include <dev/pms/freebsd/driver/ini/src/agtiproto.h> 70285809Sscottl#include <dev/pms/RefTisa/tisa/api/ostiapi.h> 71285809Sscottl#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 72285809Sscottl#include <dev/pms/freebsd/driver/common/lxencrypt.h> 73285809Sscottl 74285809SscottlMALLOC_DEFINE( M_PMC_MCCB, "CCB List", "CCB List for PMCS driver" ); 75285809Sscottl 76285809SscottlMALLOC_DEFINE( M_PMC_MSTL, "STLock malloc", 77285809Sscottl "allocated in agtiapi_attach as memory for lock use" ); 78285809SscottlMALLOC_DEFINE( M_PMC_MDVT, "ag_device_t malloc", 79285809Sscottl "allocated in agtiapi_attach as mem for ag_device_t pDevList" ); 80285809SscottlMALLOC_DEFINE( M_PMC_MPRT, "ag_portal_data_t malloc", 81285809Sscottl "allocated in agtiapi_attach as mem for *pPortalData" ); 82285809SscottlMALLOC_DEFINE( M_PMC_MDEV, "tiDeviceHandle_t * malloc", 83285809Sscottl "allocated in agtiapi_GetDevHandle as local mem for **agDev" ); 84285809SscottlMALLOC_DEFINE( M_PMC_MFLG, "lDevFlags * malloc", 85285809Sscottl "allocated in agtiapi_GetDevHandle as local mem for * flags" ); 86285809Sscottl#ifdef LINUX_PERBI_SUPPORT 87285809SscottlMALLOC_DEFINE( M_PMC_MSLR, "ag_slr_map_t malloc", 88285809Sscottl "mem allocated in agtiapi_attach for pSLRList" ); 89285809SscottlMALLOC_DEFINE( M_PMC_MTGT, "ag_tgt_map_t malloc", 90285809Sscottl "mem allocated in agtiapi_attach for pWWNList" ); 91285809Sscottl#endif 92285809SscottlMALLOC_DEFINE(TEMP,"tempbuff","buffer for payload"); 93285809SscottlMALLOC_DEFINE(TEMP2, "tempbuff", "buffer for agtiapi_getdevlist"); 94285809SscottlSTATIC U32 agtiapi_intx_mode = 0; 95285809SscottlSTATIC U08 ag_Perbi = 0; 96285809SscottlSTATIC U32 agtiapi_polling_mode = 0; 97285809SscottlSTATIC U32 ag_card_good = 0; // * total card initialized 98285809SscottlSTATIC U32 ag_option_flag = 0; // * adjustable parameter flag 99285809SscottlSTATIC U32 agtiapi_1st_time = 1; 100285809SscottlSTATIC U32 ag_timeout_secs = 10; //Made timeout equivalent to linux 101285809Sscottl 102285809SscottlU32 gTiDebugLevel = 1; 103285809SscottlS32 ag_encryption_enable = 0; 104285809Sscottlatomic_t outstanding_encrypted_io_count; 105285809Sscottl 106285809Sscottl#define cache_line_size() CACHE_LINE_SIZE 107285809Sscottl 108285809Sscottl#define PMCoffsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 109285809Sscottl 110285809Sscottl#define CPU_TO_LE32(dst, src) \ 111285809Sscottl dst.lower = htole32(LOW_32_BITS(src)); \ 112285809Sscottl dst.upper = htole32(HIGH_32_BITS(src)) 113285809Sscottl 114285809Sscottl#define CMND_TO_CHANNEL( ccb ) ( ccb->ccb_h.path_id ) 115285809Sscottl#define CMND_TO_TARGET( ccb ) ( ccb->ccb_h.target_id ) 116285809Sscottl#define CMND_TO_LUN( ccb ) ( ccb->ccb_h.target_lun ) 117285809Sscottl 118285809SscottlSTATIC U08 agtiapi_AddrModes[AGTIAPI_MAX_CHANNEL_NUM + 1] = 119285809Sscottl { AGTIAPI_PERIPHERAL }; 120285809Sscottl 121285809Sscottl#ifdef LINUX_PERBI_SUPPORT 122285809Sscottl// Holding area for target-WWN mapping assignments on the boot line 123285809Sscottlstatic ag_mapping_t *agMappingList = NULL; // modified by agtiapi_Setup() 124285809Sscottl#endif 125285809Sscottl 126285809Sscottl// * For Debugging Purpose 127285809Sscottl#ifdef AGTIAPI_DEBUG 128285809Sscottl#define AGTIAPI_WWN(name, len) wwnprintk(name, len) 129285809Sscottl#else 130285809Sscottl#define AGTIAPI_WWN(name, len) 131285809Sscottl#endif 132285809Sscottl 133285809Sscottl 134285809Sscottl#define AGTIAPI_WWNPRINTK(name, len, format, a...) \ 135285809Sscottl AGTIAPI_PRINTK(format "name ", a); \ 136285809Sscottl AGTIAPI_WWN((unsigned char*)name, len); 137285809Sscottl 138285809Sscottl#define AGTIAPI_ERR_WWNPRINTK(name, len, format, a...) \ 139285809Sscottl printk(KERN_DEBUG format "name ", ## a); \ 140285809Sscottl wwnprintk((unsigned char*)name, len); 141285809Sscottl#define AGTIAPI_CPY_DEV_INFO(root, dev, pDev) \ 142285809Sscottl tiINIGetDeviceInfo(root, dev, &pDev->devInfo); \ 143285809Sscottl wwncpy(pDev); 144285809Sscottl 145285809Sscottl#ifdef AGTIAPI_LOCAL_LOCK 146285809Sscottl 147285809Sscottl#define AG_CARD_LOCAL_LOCK(lock) ,(lock) 148285809Sscottl#define AG_SPIN_LOCK_IRQ(lock, flags) 149285809Sscottl#define AG_SPIN_UNLOCK_IRQ(lock, flags) 150285809Sscottl#define AG_SPIN_LOCK(lock) 151285809Sscottl#define AG_SPIN_UNLOCK(lock) 152285809Sscottl#define AG_GLOBAL_ARG(arg) 153285809Sscottl#define AG_PERF_SPINLOCK(lock) 154285809Sscottl#define AG_PERF_SPINLOCK_IRQ(lock, flags) 155285809Sscottl 156285809Sscottl 157285809Sscottl#define AG_LOCAL_LOCK(lock) if (lock) \ 158285809Sscottl mtx_lock(lock) 159285809Sscottl#define AG_LOCAL_UNLOCK(lock) if (lock) \ 160285809Sscottl mtx_unlock(lock) 161285809Sscottl#define AG_LOCAL_FLAGS(_flags) unsigned long _flags = 0 162285809Sscottl#endif 163285809Sscottl 164285809Sscottl 165285809Sscottl#define AG_GET_DONE_PCCB(pccb, pmcsc) \ 166285809Sscottl { \ 167285809Sscottl AG_LOCAL_LOCK(&pmcsc->doneLock); \ 168285809Sscottl pccb = pmcsc->ccbDoneHead; \ 169285809Sscottl if (pccb != NULL) \ 170285809Sscottl { \ 171285809Sscottl pmcsc->ccbDoneHead = NULL; \ 172285809Sscottl pmcsc->ccbDoneTail = NULL; \ 173285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->doneLock); \ 174285809Sscottl agtiapi_Done(pmcsc, pccb); \ 175285809Sscottl } \ 176285809Sscottl else \ 177285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->doneLock); \ 178285809Sscottl } 179285809Sscottl 180285809Sscottl#define AG_GET_DONE_SMP_PCCB(pccb, pmcsc) \ 181285809Sscottl { \ 182285809Sscottl AG_LOCAL_LOCK(&pmcsc->doneSMPLock); \ 183285809Sscottl pccb = pmcsc->smpDoneHead; \ 184285809Sscottl if (pccb != NULL) \ 185285809Sscottl { \ 186285809Sscottl pmcsc->smpDoneHead = NULL; \ 187285809Sscottl pmcsc->smpDoneTail = NULL; \ 188285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \ 189285809Sscottl agtiapi_SMPDone(pmcsc, pccb); \ 190285809Sscottl } \ 191285809Sscottl else \ 192285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->doneSMPLock); \ 193285809Sscottl } 194285809Sscottl 195285809Sscottl#ifdef AGTIAPI_DUMP_IO_DEBUG 196285809Sscottl#define AG_IO_DUMPCCB(pccb) agtiapi_DumpCCB(pccb) 197285809Sscottl#else 198285809Sscottl#define AG_IO_DUMPCCB(pccb) 199285809Sscottl#endif 200285809Sscottl 201285809Sscottl#define SCHED_DELAY_JIFFIES 4 /* in seconds */ 202285809Sscottl 203285809Sscottl#ifdef HOTPLUG_SUPPORT 204285809Sscottl#define AG_HOTPLUG_LOCK_INIT(lock) mxt_init(lock) 205285809Sscottl#define AG_LIST_LOCK(lock) mtx_lock(lock) 206285809Sscottl#define AG_LIST_UNLOCK(lock) mtx_unlock(lock) 207285809Sscottl#else 208285809Sscottl#define AG_HOTPLUG_LOCK_INIT(lock) 209285809Sscottl#define AG_LIST_LOCK(lock) 210285809Sscottl#define AG_LIST_UNLOCK(lock) 211285809Sscottl#endif 212285809Sscottl 213285809SscottlSTATIC void agtiapi_CheckIOTimeout(void *data); 214285809Sscottl 215285809Sscottl 216285809Sscottl 217285809Sscottlstatic ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list 218285809Sscottlstatic void agtiapi_cam_action( struct cam_sim *, union ccb * ); 219285809Sscottlstatic void agtiapi_cam_poll( struct cam_sim * ); 220285809Sscottl 221285809Sscottl// Function prototypes 222285809Sscottlstatic d_open_t agtiapi_open; 223285809Sscottlstatic d_close_t agtiapi_close; 224285809Sscottlstatic d_read_t agtiapi_read; 225285809Sscottlstatic d_write_t agtiapi_write; 226285809Sscottlstatic d_ioctl_t agtiapi_CharIoctl; 227285809Sscottlstatic void agtiapi_async(void *callback_arg, u_int32_t code, 228285809Sscottl struct cam_path *path, void *arg); 229285809Sscottlvoid agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth); 230285809Sscottl 231285809Sscottl// Character device entry points 232285809Sscottlstatic struct cdevsw agtiapi_cdevsw = { 233285809Sscottl .d_version = D_VERSION, 234285809Sscottl .d_open = agtiapi_open, 235285809Sscottl .d_close = agtiapi_close, 236285809Sscottl .d_read = agtiapi_read, 237285809Sscottl .d_write = agtiapi_write, 238285809Sscottl .d_ioctl = agtiapi_CharIoctl, 239285809Sscottl .d_name = "pmspcv", 240285809Sscottl}; 241285809Sscottl 242285809SscottlU32 maxTargets = 0; 243285809SscottlU32 ag_portal_count = 0; 244285809Sscottl 245285809Sscottl// In the cdevsw routines, we find our softc by using the si_drv1 member 246285809Sscottl// of struct cdev. We set this variable to point to our softc in our 247285809Sscottl// attach routine when we create the /dev entry. 248285809Sscottl 249285809Sscottlint agtiapi_open( struct cdev *dev, int oflags, int devtype, struct thread *td ) 250285809Sscottl{ 251285809Sscottl struct agtiapi_softc *sc; 252285809Sscottl /* Look up our softc. */ 253285809Sscottl sc = dev->si_drv1; 254285809Sscottl AGTIAPI_PRINTK("agtiapi_open\n"); 255285809Sscottl AGTIAPI_PRINTK("Opened successfully. sc->my_dev %p\n", sc->my_dev); 256285809Sscottl return( 0 ); 257285809Sscottl} 258285809Sscottl 259285809Sscottlint agtiapi_close( struct cdev *dev, int fflag, int devtype, struct thread *td ) 260285809Sscottl{ 261285809Sscottl struct agtiapi_softc *sc; 262285809Sscottl // Look up our softc 263285809Sscottl sc = dev->si_drv1; 264285809Sscottl AGTIAPI_PRINTK("agtiapi_close\n"); 265285809Sscottl AGTIAPI_PRINTK("Closed. sc->my_dev %p\n", sc->my_dev); 266285809Sscottl return( 0 ); 267285809Sscottl} 268285809Sscottl 269285809Sscottlint agtiapi_read( struct cdev *dev, struct uio *uio, int ioflag ) 270285809Sscottl{ 271285809Sscottl struct agtiapi_softc *sc; 272285809Sscottl // Look up our softc 273285809Sscottl sc = dev->si_drv1; 274285809Sscottl AGTIAPI_PRINTK( "agtiapi_read\n" ); 275285809Sscottl AGTIAPI_PRINTK( "Asked to read %lu bytes. sc->my_dev %p\n", 276285809Sscottl uio->uio_resid, sc->my_dev ); 277285809Sscottl return( 0 ); 278285809Sscottl} 279285809Sscottl 280285809Sscottlint agtiapi_write( struct cdev *dev, struct uio *uio, int ioflag ) 281285809Sscottl{ 282285809Sscottl struct agtiapi_softc *sc; 283285809Sscottl // Look up our softc 284285809Sscottl sc = dev->si_drv1; 285285809Sscottl AGTIAPI_PRINTK( "agtiapi_write\n" ); 286285809Sscottl AGTIAPI_PRINTK( "Asked to write %lu bytes. sc->my_dev %p\n", 287285809Sscottl uio->uio_resid, sc->my_dev ); 288285809Sscottl return( 0 ); 289285809Sscottl} 290285809Sscottl 291285809Sscottlint agtiapi_getdevlist( struct agtiapi_softc *pCard, 292285809Sscottl tiIOCTLPayload_t *agIOCTLPayload ) 293285809Sscottl{ 294285809Sscottl tdDeviceListPayload_t *pIoctlPayload = 295285809Sscottl (tdDeviceListPayload_t *) agIOCTLPayload->FunctionSpecificArea; 296285809Sscottl tdDeviceInfoIOCTL_t *pDeviceInfo = NULL; 297285809Sscottl bit8 *pDeviceInfoOrg; 298285809Sscottl tdsaDeviceData_t *pDeviceData = NULL; 299285809Sscottl tiDeviceHandle_t **devList = NULL; 300285809Sscottl tiDeviceHandle_t **devHandleArray = NULL; 301285809Sscottl tiDeviceHandle_t *pDeviceHandle = NULL; 302285809Sscottl bit32 x, memNeeded1; 303285809Sscottl bit32 count, total; 304285809Sscottl bit32 MaxDeviceCount; 305285809Sscottl bit32 ret_val=IOCTL_CALL_INVALID_CODE; 306285809Sscottl ag_portal_data_t *pPortalData; 307285809Sscottl bit8 *pDeviceHandleList = NULL; 308285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: Enter\n" ); 309285809Sscottl 310285809Sscottl pDeviceInfoOrg = pIoctlPayload -> pDeviceInfo; 311285809Sscottl MaxDeviceCount = pCard->devDiscover; 312285809Sscottl if (MaxDeviceCount > pIoctlPayload->deviceLength ) 313285809Sscottl { 314285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength ); 315285809Sscottl MaxDeviceCount = pIoctlPayload->deviceLength; 316285809Sscottl ret_val = IOCTL_CALL_FAIL; 317285809Sscottl } 318285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: MaxDeviceCount: %d > Requested device length: %d\n", MaxDeviceCount, pIoctlPayload->deviceLength ); 319285809Sscottl memNeeded1 = AG_ALIGNSIZE( MaxDeviceCount * sizeof(tiDeviceHandle_t *), 320285809Sscottl sizeof(void *) ); 321285809Sscottl AGTIAPI_PRINTK("agtiapi_getdevlist: portCount %d\n", pCard->portCount); 322285809Sscottl devList = malloc(memNeeded1, TEMP2, M_WAITOK); 323285809Sscottl if (devList == NULL) 324285809Sscottl { 325285809Sscottl AGTIAPI_PRINTK("agtiapi_getdevlist: failed to allocate memory\n"); 326285809Sscottl ret_val = IOCTL_CALL_FAIL; 327285809Sscottl agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR; 328285809Sscottl return ret_val; 329285809Sscottl } 330285809Sscottl osti_memset(devList, 0, memNeeded1); 331285809Sscottl pPortalData = &pCard->pPortalData[0]; 332285809Sscottl pDeviceHandleList = (bit8*)devList; 333285809Sscottl for (total = x = 0; x < pCard->portCount; x++, pPortalData++) 334285809Sscottl { 335285809Sscottl count = tiINIGetDeviceHandlesForWinIOCTL(&pCard->tiRoot, 336285809Sscottl &pPortalData->portalInfo.tiPortalContext, 337285809Sscottl ( tiDeviceHandle_t **)pDeviceHandleList ,MaxDeviceCount ); 338285809Sscottl if (count == DISCOVERY_IN_PROGRESS) 339285809Sscottl { 340285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: DISCOVERY_IN_PROGRESS on " 341285809Sscottl "portal %d\n", x ); 342285809Sscottl free(devList, TEMP2); 343285809Sscottl ret_val = IOCTL_CALL_FAIL; 344285809Sscottl agIOCTLPayload->Status = IOCTL_ERR_STATUS_INTERNAL_ERROR; 345285809Sscottl return ret_val; 346285809Sscottl } 347285809Sscottl total += count; 348285809Sscottl pDeviceHandleList+= count*sizeof(tiDeviceHandle_t *); 349285809Sscottl MaxDeviceCount-= count; 350285809Sscottl } 351285809Sscottl if (total > pIoctlPayload->deviceLength) 352285809Sscottl { 353285809Sscottl total = pIoctlPayload->deviceLength; 354285809Sscottl } 355285809Sscottl // dump device information from device handle list 356285809Sscottl count = 0; 357285809Sscottl 358285809Sscottl devHandleArray = devList; 359285809Sscottl for (x = 0; x < pCard->devDiscover; x++) 360285809Sscottl { 361285809Sscottl pDeviceHandle = (tiDeviceHandle_t*)devHandleArray[x]; 362285809Sscottl if (devList[x] != agNULL) 363285809Sscottl { 364285809Sscottl pDeviceData = devList [x]->tdData; 365285809Sscottl 366285809Sscottl pDeviceInfo = (tdDeviceInfoIOCTL_t*)(pDeviceInfoOrg + sizeof(tdDeviceInfoIOCTL_t) * count); 367285809Sscottl if (pDeviceData != agNULL && pDeviceInfo != agNULL) 368285809Sscottl { 369285809Sscottl osti_memcpy( &pDeviceInfo->sasAddressHi, 370285809Sscottl pDeviceData->agDeviceInfo.sasAddressHi, 371285809Sscottl sizeof(bit32) ); 372285809Sscottl osti_memcpy( &pDeviceInfo->sasAddressLo, 373285809Sscottl pDeviceData->agDeviceInfo.sasAddressLo, 374285809Sscottl sizeof(bit32) ); 375285809Sscottl#if 0 376285809Sscottl pDeviceInfo->sasAddressHi = 377285809Sscottl DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi ); 378285809Sscottl pDeviceInfo->sasAddressLo = 379285809Sscottl DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo ); 380285809Sscottl#endif 381285809Sscottl 382285809Sscottl pDeviceInfo->deviceType = 383285809Sscottl ( pDeviceData->agDeviceInfo.devType_S_Rate & 0x30 ) >> 4; 384285809Sscottl pDeviceInfo->linkRate = 385285809Sscottl pDeviceData->agDeviceInfo.devType_S_Rate & 0x0F; 386285809Sscottl pDeviceInfo->phyId = pDeviceData->phyID; 387285809Sscottl pDeviceInfo->ishost = pDeviceData->target_ssp_stp_smp; 388285809Sscottl pDeviceInfo->DeviceHandle= (unsigned long)pDeviceHandle; 389285809Sscottl if(pDeviceInfo->deviceType == 0x02) 390285809Sscottl { 391285809Sscottl bit8 *sasAddressHi; 392285809Sscottl bit8 *sasAddressLo; 393285809Sscottl tiIniGetDirectSataSasAddr(&pCard->tiRoot, pDeviceData->phyID, &sasAddressHi, &sasAddressLo); 394285809Sscottl pDeviceInfo->sasAddressHi = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressHi); 395285809Sscottl pDeviceInfo->sasAddressLo = DMA_BEBIT32_TO_BIT32(*(bit32*)sasAddressLo) + pDeviceData->phyID + 16; 396285809Sscottl } 397285809Sscottl else 398285809Sscottl { 399285809Sscottl pDeviceInfo->sasAddressHi = 400285809Sscottl DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressHi ); 401285809Sscottl pDeviceInfo->sasAddressLo = 402285809Sscottl DMA_BEBIT32_TO_BIT32( pDeviceInfo->sasAddressLo ); 403285809Sscottl } 404285809Sscottl 405285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: devicetype %x\n", 406285809Sscottl pDeviceInfo->deviceType ); 407285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: linkrate %x\n", 408285809Sscottl pDeviceInfo->linkRate ); 409285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: phyID %x\n", 410285809Sscottl pDeviceInfo->phyId ); 411285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: addresshi %x\n", 412285809Sscottl pDeviceInfo->sasAddressHi ); 413285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: addresslo %x\n", 414285809Sscottl pDeviceInfo->sasAddressHi ); 415285809Sscottl } 416285809Sscottl else 417285809Sscottl { 418285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: pDeviceData %p or pDeviceInfo " 419285809Sscottl "%p is NULL %d\n", pDeviceData, pDeviceInfo, x ); 420285809Sscottl } 421285809Sscottl count++; 422285809Sscottl } 423285809Sscottl } 424285809Sscottl pIoctlPayload->realDeviceCount = count; 425285809Sscottl AGTIAPI_PRINTK( "agtiapi_getdevlist: Exit RealDeviceCount = %d\n", count ); 426285809Sscottl if (devList) 427285809Sscottl { 428285809Sscottl free(devList, TEMP2); 429285809Sscottl } 430285809Sscottl if(ret_val != IOCTL_CALL_FAIL) 431285809Sscottl { 432285809Sscottl ret_val = IOCTL_CALL_SUCCESS; 433285809Sscottl } 434285809Sscottl agIOCTLPayload->Status = IOCTL_ERR_STATUS_OK; 435285809Sscottl return ret_val; 436285809Sscottl} 437285809Sscottl 438285809Sscottl/****************************************************************************** 439285809Sscottlagtiapi_getCardInfo() 440285809Sscottl 441285809SscottlPurpose: 442285809Sscottl This function retrives the Card information 443285809SscottlParameters: 444285809Sscottl 445285809SscottlReturn: 446285809Sscottl A number - error 447285809Sscottl 0 - HBA has been detected 448285809SscottlNote: 449285809Sscottl******************************************************************************/ 450285809Sscottlint agtiapi_getCardInfo ( struct agtiapi_softc *pCard, 451285809Sscottl U32_64 size, 452285809Sscottl void *buffer ) 453285809Sscottl{ 454285809Sscottl CardInfo_t *pCardInfo; 455285809Sscottl 456285809Sscottl pCardInfo = (CardInfo_t *)buffer; 457285809Sscottl 458285809Sscottl pCardInfo->deviceId = pci_get_device(pCard->my_dev); 459285809Sscottl pCardInfo->vendorId =pci_get_vendor(pCard->my_dev) ; 460285809Sscottl memcpy( pCardInfo->pciMemBaseSpc, 461285809Sscottl pCard->pCardInfo->pciMemBaseSpc, 462285809Sscottl ((sizeof(U32_64))*PCI_NUMBER_BARS) ); 463285809Sscottl pCardInfo->deviceNum = pci_get_slot(pCard->my_dev); 464285809Sscottl pCardInfo->pciMemBase = pCard->pCardInfo->pciMemBase; 465285809Sscottl pCardInfo->pciIOAddrLow = pCard->pCardInfo->pciIOAddrLow; 466285809Sscottl pCardInfo->pciIOAddrUp = pCard->pCardInfo->pciIOAddrUp; 467285809Sscottl pCardInfo->busNum =pci_get_bus(pCard->my_dev); 468285809Sscottl return 0; 469285809Sscottl} 470285809Sscottl 471285809Sscottlvoid agtiapi_adjust_queue_depth(struct cam_path *path, bit32 QueueDepth) 472285809Sscottl{ 473285809Sscottl struct ccb_relsim crs; 474285809Sscottl xpt_setup_ccb(&crs.ccb_h, path, 5); 475285809Sscottl crs.ccb_h.func_code = XPT_REL_SIMQ; 476285809Sscottl crs.ccb_h.flags = CAM_DEV_QFREEZE; 477285809Sscottl crs.release_flags = RELSIM_ADJUST_OPENINGS; 478285809Sscottl crs.openings = QueueDepth; 479285809Sscottl xpt_action((union ccb *)&crs); 480285809Sscottl if(crs.ccb_h.status != CAM_REQ_CMP) { 481285809Sscottl printf("XPT_REL_SIMQ failed\n"); 482285809Sscottl } 483285809Sscottl} 484285809Sscottlstatic void 485285809Sscottlagtiapi_async(void *callback_arg, u_int32_t code, 486285809Sscottl struct cam_path *path, void *arg) 487285809Sscottl{ 488285809Sscottl struct agtiapi_softc *pmsc; 489285809Sscottl U32 TID; 490285809Sscottl ag_device_t *targ; 491285809Sscottl pmsc = (struct agtiapi_softc*)callback_arg; 492285809Sscottl switch (code) { 493285809Sscottl case AC_FOUND_DEVICE: 494285809Sscottl { 495285809Sscottl struct ccb_getdev *cgd; 496285809Sscottl cgd = (struct ccb_getdev *)arg; 497285809Sscottl if (cgd == NULL) { 498285809Sscottl break; 499285809Sscottl } 500285809Sscottl TID = cgd->ccb_h.target_id; 501285809Sscottl if (TID >= 0 && TID < maxTargets){ 502285809Sscottl if (pmsc != NULL){ 503285809Sscottl TID = INDEX(pmsc, TID); 504285809Sscottl targ = &pmsc->pDevList[TID]; 505285809Sscottl agtiapi_adjust_queue_depth(path, targ->qdepth); 506285809Sscottl } 507285809Sscottl } 508285809Sscottl break; 509285809Sscottl } 510285809Sscottl default: 511285809Sscottl break; 512285809Sscottl } 513285809Sscottl} 514285809Sscottl/****************************************************************************** 515285809Sscottlagtiapi_CharIoctl() 516285809Sscottl 517285809SscottlPurpose: 518285809Sscottl This function handles the ioctl from application layer 519285809SscottlParameters: 520285809Sscottl 521285809SscottlReturn: 522285809Sscottl A number - error 523285809Sscottl 0 - HBA has been detected 524285809SscottlNote: 525285809Sscottl******************************************************************************/ 526285809Sscottlstatic int agtiapi_CharIoctl( struct cdev *dev, 527285809Sscottl u_long cmd, 528285809Sscottl caddr_t data, 529285809Sscottl int fflag, 530285809Sscottl struct thread *td ) 531285809Sscottl{ 532285809Sscottl struct sema mx; 533285809Sscottl datatosend *load; // structure defined in lxcommon.h 534285809Sscottl tiIOCTLPayload_t *pIoctlPayload; 535285809Sscottl struct agtiapi_softc *pCard; 536285809Sscottl pCard=dev->si_drv1; 537285809Sscottl void *param1 = NULL; 538285809Sscottl void *param2 = NULL; 539285809Sscottl void *param3 = NULL; 540285809Sscottl U32 status = 0; 541285809Sscottl U32 retValue; 542285809Sscottl int err = 0; 543285809Sscottl int error = 0; 544285809Sscottl tdDeviceListPayload_t *pDeviceList = NULL; 545285809Sscottl unsigned long flags; 546285809Sscottl 547285809Sscottl switch (cmd) 548285809Sscottl { 549285809Sscottl case AGTIAPI_IOCTL: 550285809Sscottl load=(datatosend*)data; 551285809Sscottl pIoctlPayload = malloc(load->datasize,TEMP,M_WAITOK); 552285809Sscottl AGTIAPI_PRINTK( "agtiapi_CharIoctl: old load->datasize = %d\n", load->datasize ); 553285809Sscottl //Copy payload to kernel buffer, on success it returns 0 554285809Sscottl err = copyin(load->data,pIoctlPayload,load->datasize); 555285809Sscottl if (err) 556285809Sscottl { 557285809Sscottl status = IOCTL_CALL_FAIL; 558285809Sscottl return status; 559285809Sscottl } 560285809Sscottl sema_init(&mx,0,"sem"); 561285809Sscottl pCard->pIoctlSem =&mx; 562285809Sscottl pCard->up_count = pCard->down_count = 0; 563285809Sscottl if ( pIoctlPayload->MajorFunction == IOCTL_MJ_GET_DEVICE_LIST ) 564285809Sscottl { 565285809Sscottl retValue = agtiapi_getdevlist(pCard, pIoctlPayload); 566285809Sscottl if (retValue == 0) 567285809Sscottl { 568285809Sscottl pIoctlPayload->Status = IOCTL_CALL_SUCCESS; 569285809Sscottl status = IOCTL_CALL_SUCCESS; 570285809Sscottl } 571285809Sscottl else 572285809Sscottl { 573285809Sscottl pIoctlPayload->Status = IOCTL_CALL_FAIL; 574285809Sscottl status = IOCTL_CALL_FAIL; 575285809Sscottl } 576285809Sscottl //update new device length 577285809Sscottl pDeviceList = (tdDeviceListPayload_t*)pIoctlPayload->FunctionSpecificArea; 578285809Sscottl load->datasize =load->datasize - sizeof(tdDeviceInfoIOCTL_t) * (pDeviceList->deviceLength - pDeviceList->realDeviceCount); 579285809Sscottl AGTIAPI_PRINTK( "agtiapi_CharIoctl: new load->datasize = %d\n", load->datasize ); 580285809Sscottl 581285809Sscottl } 582285809Sscottl else if (pIoctlPayload->MajorFunction == IOCTL_MN_GET_CARD_INFO) 583285809Sscottl { 584285809Sscottl retValue = agtiapi_getCardInfo( pCard, 585285809Sscottl pIoctlPayload->Length, 586285809Sscottl (pIoctlPayload->FunctionSpecificArea) ); 587285809Sscottl if (retValue == 0) 588285809Sscottl { 589285809Sscottl pIoctlPayload->Status = IOCTL_CALL_SUCCESS; 590285809Sscottl status = IOCTL_CALL_SUCCESS; 591285809Sscottl } 592285809Sscottl else 593285809Sscottl { 594285809Sscottl pIoctlPayload->Status = IOCTL_CALL_FAIL; 595285809Sscottl status = IOCTL_CALL_FAIL; 596285809Sscottl } 597285809Sscottl } 598285809Sscottl else if ( pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_DPMC_EVENT ) 599285809Sscottl { 600285809Sscottl if ( pCard->flags & AGTIAPI_PORT_PANIC ) 601285809Sscottl { 602285809Sscottl strcpy ( pIoctlPayload->FunctionSpecificArea, "DPMC LEAN\n" ); 603285809Sscottl } 604285809Sscottl else 605285809Sscottl { 606285809Sscottl strcpy ( pIoctlPayload->FunctionSpecificArea, "do not dpmc lean\n" ); 607285809Sscottl } 608285809Sscottl pIoctlPayload->Status = IOCTL_CALL_SUCCESS; 609285809Sscottl status = IOCTL_CALL_SUCCESS; 610285809Sscottl } 611285809Sscottl else if (pIoctlPayload->MajorFunction == IOCTL_MJ_CHECK_FATAL_ERROR ) 612285809Sscottl { 613285809Sscottl AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_CHECK_FATAL_ERROR call received for card %d\n", pCard->cardNo); 614285809Sscottl //read port status to see if there is a fatal event 615285809Sscottl if(pCard->flags & AGTIAPI_PORT_PANIC) 616285809Sscottl { 617285809Sscottl printf("agtiapi_CharIoctl: Port Panic Status For Card %d is True\n",pCard->cardNo); 618285809Sscottl pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_TRUE; 619285809Sscottl } 620285809Sscottl else 621285809Sscottl { 622285809Sscottl AGTIAPI_PRINTK("agtiapi_CharIoctl: Port Panic Status For Card %d is False\n",pCard->cardNo); 623285809Sscottl pIoctlPayload->Status = IOCTL_MJ_FATAL_ERR_CHK_SEND_FALSE; 624285809Sscottl } 625285809Sscottl status = IOCTL_CALL_SUCCESS; 626285809Sscottl } 627285809Sscottl else if (pIoctlPayload->MajorFunction == IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE) 628285809Sscottl { 629285809Sscottl AGTIAPI_PRINTK("agtiapi_CharIoctl: IOCTL_MJ_FATAL_ERROR_DUMP_COMPLETE call received for card %d\n", pCard->cardNo); 630285809Sscottl //set flags bit status to be a soft reset 631285809Sscottl pCard->flags |= AGTIAPI_SOFT_RESET; 632285809Sscottl //trigger soft reset for the card 633285809Sscottl retValue = agtiapi_ResetCard (pCard, &flags); 634285809Sscottl 635285809Sscottl if(retValue == AGTIAPI_SUCCESS) 636285809Sscottl { 637285809Sscottl //clear port panic status 638285809Sscottl pCard->flags &= ~AGTIAPI_PORT_PANIC; 639285809Sscottl pIoctlPayload->Status = IOCTL_MJ_FATAL_ERROR_SOFT_RESET_TRIG; 640285809Sscottl status = IOCTL_CALL_SUCCESS; 641285809Sscottl } 642285809Sscottl else 643285809Sscottl { 644285809Sscottl pIoctlPayload->Status = IOCTL_CALL_FAIL; 645285809Sscottl status = IOCTL_CALL_FAIL; 646285809Sscottl } 647285809Sscottl } 648285809Sscottl else 649285809Sscottl { 650285809Sscottl status = tiCOMMgntIOCTL( &pCard->tiRoot, 651285809Sscottl pIoctlPayload, 652285809Sscottl pCard, 653285809Sscottl param2, 654285809Sscottl param3 ); 655285809Sscottl if (status == IOCTL_CALL_PENDING) 656285809Sscottl { 657285809Sscottl ostiIOCTLWaitForSignal(&pCard->tiRoot,NULL, NULL, NULL); 658285809Sscottl status = IOCTL_CALL_SUCCESS; 659285809Sscottl } 660285809Sscottl } 661285809Sscottl pCard->pIoctlSem = NULL; 662285809Sscottl err = 0; 663285809Sscottl 664285809Sscottl //copy kernel buffer to userland buffer 665285809Sscottl err=copyout(pIoctlPayload,load->data,load->datasize); 666285809Sscottl if (err) 667285809Sscottl { 668285809Sscottl status = IOCTL_CALL_FAIL; 669285809Sscottl return status; 670285809Sscottl } 671285809Sscottl free(pIoctlPayload,TEMP); 672285809Sscottl pIoctlPayload=NULL; 673285809Sscottl break; 674285809Sscottl default: 675285809Sscottl error = ENOTTY; 676285809Sscottl break; 677285809Sscottl } 678285809Sscottl return(status); 679285809Sscottl} 680285809Sscottl 681285809Sscottl/****************************************************************************** 682285809Sscottlagtiapi_probe() 683285809Sscottl 684285809SscottlPurpose: 685285809Sscottl This function initialize and registere all detected HBAs. 686285809Sscottl The first function being called in driver after agtiapi_probe() 687285809SscottlParameters: 688285809Sscottl device_t dev (IN) - device pointer 689285809SscottlReturn: 690285809Sscottl A number - error 691285809Sscottl 0 - HBA has been detected 692285809SscottlNote: 693285809Sscottl******************************************************************************/ 694285809Sscottlstatic int agtiapi_probe( device_t dev ) 695285809Sscottl{ 696285809Sscottl int retVal; 697286263Simp int thisCard; 698286263Simp ag_card_info_t *thisCardInst; 699286263Simp 700286263Simp thisCard = device_get_unit( dev ); 701286263Simp if ( thisCard >= AGTIAPI_MAX_CARDS ) 702285809Sscottl { 703286263Simp device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" ); 704286263Simp return (ENXIO); // maybe change to different return value? 705285809Sscottl } 706286263Simp thisCardInst = &agCardInfoList[ thisCard ]; 707286263Simp retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard ); 708286263Simp if ( retVal ) 709286263Simp return (ENXIO); // maybe change to different return value? 710286263Simp return( BUS_PROBE_DEFAULT ); // successful probe 711285809Sscottl} 712285809Sscottl 713285809Sscottl 714285809Sscottl/****************************************************************************** 715285809Sscottlagtiapi_attach() 716285809Sscottl 717285809SscottlPurpose: 718285809Sscottl This function initialize and registere all detected HBAs. 719285809Sscottl The first function being called in driver after agtiapi_probe() 720285809SscottlParameters: 721285809Sscottl device_t dev (IN) - device pointer 722285809SscottlReturn: 723285809Sscottl A number - error 724285809Sscottl 0 - HBA has been detected 725285809SscottlNote: 726285809Sscottl******************************************************************************/ 727285809Sscottlstatic int agtiapi_attach( device_t devx ) 728285809Sscottl{ 729285809Sscottl // keeping get_unit call to once 730285809Sscottl int thisCard = device_get_unit( devx ); 731285809Sscottl struct agtiapi_softc *pmsc; 732285809Sscottl ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ]; 733285809Sscottl ag_resource_info_t *pRscInfo; 734285809Sscottl int idx; 735285809Sscottl int lenRecv; 736285809Sscottl char buffer [256], *pLastUsedChar; 737285809Sscottl union ccb *ccb; 738285809Sscottl int bus, tid, lun; 739285809Sscottl struct ccb_setasync csa; 740285809Sscottl 741285809Sscottl AGTIAPI_PRINTK("agtiapi_attach: start dev %p thisCard %d\n", devx, thisCard); 742285809Sscottl // AGTIAPI_PRINTK( "agtiapi_attach: entry pointer values A %p / %p\n", 743285809Sscottl // thisCardInst->pPCIDev, thisCardInst ); 744285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: deviceID: 0x%x\n", pci_get_devid( devx ) ); 745285809Sscottl 746285809Sscottl TUNABLE_INT_FETCH( "DPMC_TIMEOUT_SECS", &ag_timeout_secs ); 747285809Sscottl TUNABLE_INT_FETCH( "DPMC_TIDEBUG_LEVEL", &gTiDebugLevel ); 748285809Sscottl // printf( "agtiapi_attach: debugLevel %d, timeout %d\n", 749285809Sscottl // gTiDebugLevel, ag_timeout_secs ); 750285809Sscottl if ( ag_timeout_secs < 1 ) 751285809Sscottl { 752285809Sscottl ag_timeout_secs = 1; // set minimum timeout value of 1 second 753285809Sscottl } 754285809Sscottl ag_timeout_secs = (ag_timeout_secs * 1000); // convert to millisecond notation 755285809Sscottl 756285809Sscottl // Look up our softc and initialize its fields. 757285809Sscottl pmsc = device_get_softc( devx ); 758285809Sscottl pmsc->my_dev = devx; 759285809Sscottl 760285809Sscottl /* Get NumberOfPortals */ 761285809Sscottl if ((ostiGetTransportParam( 762285809Sscottl &pmsc->tiRoot, 763285809Sscottl "Global", 764285809Sscottl "CardDefault", 765285809Sscottl agNULL, 766285809Sscottl agNULL, 767285809Sscottl agNULL, 768285809Sscottl agNULL, 769285809Sscottl "NumberOfPortals", 770285809Sscottl buffer, 771285809Sscottl 255, 772285809Sscottl &lenRecv 773285809Sscottl ) == tiSuccess) && (lenRecv != 0)) 774285809Sscottl { 775285809Sscottl if (osti_strncmp(buffer, "0x", 2) == 0) 776285809Sscottl { 777285809Sscottl ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 0); 778285809Sscottl } 779285809Sscottl else 780285809Sscottl { 781285809Sscottl ag_portal_count = osti_strtoul (buffer, &pLastUsedChar, 10); 782285809Sscottl } 783285809Sscottl if (ag_portal_count > AGTIAPI_MAX_PORTALS) 784285809Sscottl ag_portal_count = AGTIAPI_MAX_PORTALS; 785285809Sscottl } 786285809Sscottl else 787285809Sscottl { 788285809Sscottl ag_portal_count = AGTIAPI_MAX_PORTALS; 789285809Sscottl } 790285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: ag_portal_count=%d\n", ag_portal_count ); 791285809Sscottl // initialize hostdata structure 792285809Sscottl pmsc->flags |= AGTIAPI_INIT_TIME | AGTIAPI_SCSI_REGISTERED | 793285809Sscottl AGTIAPI_INITIATOR; 794285809Sscottl pmsc->cardNo = thisCard; 795285809Sscottl pmsc->ccbTotal = 0; 796285809Sscottl pmsc->portCount = ag_portal_count; 797285809Sscottl pmsc->pCardInfo = thisCardInst; 798285809Sscottl pmsc->tiRoot.osData = pmsc; 799285809Sscottl pmsc->pCardInfo->pCard = (void *)pmsc; 800285809Sscottl pmsc->VidDid = ( pci_get_vendor(devx) << 16 ) | pci_get_device( devx ); 801285809Sscottl pmsc->SimQFrozen = agFALSE; 802285809Sscottl pmsc->devq_flag = agFALSE; 803285809Sscottl pRscInfo = &thisCardInst->tiRscInfo; 804285809Sscottl 805285809Sscottl osti_memset(buffer, 0, 256); 806285809Sscottl lenRecv = 0; 807285809Sscottl 808285809Sscottl /* Get MaxTargets */ 809285809Sscottl if ((ostiGetTransportParam( 810285809Sscottl &pmsc->tiRoot, 811285809Sscottl "Global", 812285809Sscottl "InitiatorParms", 813285809Sscottl agNULL, 814285809Sscottl agNULL, 815285809Sscottl agNULL, 816285809Sscottl agNULL, 817285809Sscottl "MaxTargets", 818285809Sscottl buffer, 819285809Sscottl sizeof(buffer), 820285809Sscottl &lenRecv 821285809Sscottl ) == tiSuccess) && (lenRecv != 0)) 822285809Sscottl { 823285809Sscottl if (osti_strncmp(buffer, "0x", 2) == 0) 824285809Sscottl { 825285809Sscottl maxTargets = osti_strtoul (buffer, &pLastUsedChar, 0); 826285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 0 \n" ); 827285809Sscottl } 828285809Sscottl else 829285809Sscottl { 830285809Sscottl maxTargets = osti_strtoul (buffer, &pLastUsedChar, 10); 831285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: maxTargets = osti_strtoul 10\n" ); 832285809Sscottl } 833285809Sscottl } 834285809Sscottl else 835285809Sscottl 836285809Sscottl { 837285809Sscottl if(Is_ADP8H(pmsc)) 838285809Sscottl maxTargets = AGTIAPI_MAX_DEVICE_8H; 839285809Sscottl else if(Is_ADP7H(pmsc)) 840285809Sscottl maxTargets = AGTIAPI_MAX_DEVICE_7H; 841285809Sscottl else 842285809Sscottl maxTargets = AGTIAPI_MAX_DEVICE; 843285809Sscottl } 844285809Sscottl 845285809Sscottl if (maxTargets > AGTIAPI_HW_LIMIT_DEVICE) 846285809Sscottl { 847285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: maxTargets: %d > AGTIAPI_HW_LIMIT_DEVICE: %d\n", maxTargets, AGTIAPI_HW_LIMIT_DEVICE ); 848285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: change maxTargets = AGTIAPI_HW_LIMIT_DEVICE\n" ); 849285809Sscottl maxTargets = AGTIAPI_HW_LIMIT_DEVICE; 850285809Sscottl } 851285809Sscottl pmsc->devDiscover = maxTargets ; 852285809Sscottl 853285809Sscottl #ifdef HIALEAH_ENCRYPTION 854285809Sscottl ag_encryption_enable = 1; 855285809Sscottl if(ag_encryption_enable && pci_get_device(pmsc->pCardInfo->pPCIDev) == 856285809Sscottl PCI_DEVICE_ID_HIALEAH_HBA_SPCVE) 857285809Sscottl { 858285809Sscottl pmsc->encrypt = 1; 859285809Sscottl pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE; 860285809Sscottl printf("agtiapi_attach: Encryption Enabled\n" ); 861285809Sscottl } 862285809Sscottl#endif 863285809Sscottl // ## for now, skip calls to ostiGetTransportParam(...) 864285809Sscottl // ## for now, skip references to DIF & EDC 865285809Sscottl 866285809Sscottl // Create a /dev entry for this device. The kernel will assign us 867285809Sscottl // a major number automatically. We use the unit number of this 868285809Sscottl // device as the minor number and name the character device 869285809Sscottl // "agtiapi<unit>". 870285809Sscottl pmsc->my_cdev = make_dev( &agtiapi_cdevsw, thisCard, UID_ROOT, GID_WHEEL, 871285809Sscottl 0600, "spcv%u", thisCard ); 872285809Sscottl pmsc->my_cdev->si_drv1 = pmsc; 873285809Sscottl 874285809Sscottl mtx_init( &thisCardInst->pmIOLock, "pmc SAS I/O lock", 875285809Sscottl NULL, MTX_DEF|MTX_RECURSE ); 876285809Sscottl 877285809Sscottl struct cam_devq *devq; 878285809Sscottl 879285809Sscottl /* set the maximum number of pending IOs */ 880285809Sscottl devq = cam_simq_alloc( AGTIAPI_MAX_CAM_Q_DEPTH ); 881285809Sscottl if (devq == NULL) 882285809Sscottl { 883285809Sscottl AGTIAPI_PRINTK("agtiapi_attach: cam_simq_alloc is NULL\n" ); 884285809Sscottl return( EIO ); 885285809Sscottl } 886285809Sscottl 887285809Sscottl struct cam_sim *lsim; 888285809Sscottl lsim = cam_sim_alloc( agtiapi_cam_action, 889285809Sscottl agtiapi_cam_poll, 890285809Sscottl "pmspcbsd", 891285809Sscottl pmsc, 892285809Sscottl thisCard, 893285809Sscottl &thisCardInst->pmIOLock, 894285809Sscottl 1, // queued per target 895285809Sscottl AGTIAPI_MAX_CAM_Q_DEPTH, // max tag depth 896285809Sscottl devq ); 897285809Sscottl if ( lsim == NULL ) { 898285809Sscottl cam_simq_free( devq ); 899285809Sscottl AGTIAPI_PRINTK("agtiapi_attach: cam_sim_alloc is NULL\n" ); 900285809Sscottl return( EIO ); 901285809Sscottl } 902285809Sscottl 903285809Sscottl pmsc->dev_scan = agFALSE; 904285809Sscottl //one cam sim per scsi bus 905285809Sscottl mtx_lock( &thisCardInst->pmIOLock ); 906285809Sscottl if ( xpt_bus_register( lsim, devx, 0 ) != CAM_SUCCESS ) 907285809Sscottl { // bus 0 908285809Sscottl cam_sim_free( lsim, TRUE ); 909285809Sscottl mtx_unlock( &thisCardInst->pmIOLock ); 910285809Sscottl AGTIAPI_PRINTK("agtiapi_attach: xpt_bus_register fails\n" ); 911285809Sscottl return( EIO ); 912285809Sscottl } 913285809Sscottl 914285809Sscottl pmsc->sim = lsim; 915285809Sscottl bus = cam_sim_path(pmsc->sim); 916285809Sscottl tid = CAM_TARGET_WILDCARD; 917285809Sscottl lun = CAM_LUN_WILDCARD; 918285809Sscottl ccb = xpt_alloc_ccb_nowait(); 919285809Sscottl if (ccb == agNULL) 920285809Sscottl { 921285809Sscottl mtx_unlock( &thisCardInst->pmIOLock ); 922285809Sscottl cam_sim_free( lsim, TRUE ); 923285809Sscottl cam_simq_free( devq ); 924285809Sscottl return ( EIO ); 925285809Sscottl } 926285809Sscottl if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid, 927285809Sscottl CAM_LUN_WILDCARD) != CAM_REQ_CMP) 928285809Sscottl { 929285809Sscottl mtx_unlock( &thisCardInst->pmIOLock ); 930285809Sscottl cam_sim_free( lsim, TRUE ); 931285809Sscottl cam_simq_free( devq ); 932285809Sscottl xpt_free_ccb(ccb); 933285809Sscottl return( EIO ); 934285809Sscottl } 935285809Sscottl pmsc->path = ccb->ccb_h.path; 936285809Sscottl xpt_setup_ccb(&csa.ccb_h, pmsc->path, 5); 937285809Sscottl csa.ccb_h.func_code = XPT_SASYNC_CB; 938285809Sscottl csa.event_enable = AC_FOUND_DEVICE; 939285809Sscottl csa.callback = agtiapi_async; 940285809Sscottl csa.callback_arg = pmsc; 941285809Sscottl xpt_action((union ccb *)&csa); 942285809Sscottl if (csa.ccb_h.status != CAM_REQ_CMP) { 943285809Sscottl AGTIAPI_PRINTK("agtiapi_attach: Unable to register AC_FOUND_DEVICE\n" ); 944285809Sscottl } 945285809Sscottl lsim->devq = devq; 946285809Sscottl mtx_unlock( &thisCardInst->pmIOLock ); 947285809Sscottl 948285809Sscottl 949285809Sscottl 950285809Sscottl 951285809Sscottl // get TD and lower layer memory requirements 952285809Sscottl tiCOMGetResource( &pmsc->tiRoot, 953285809Sscottl &pRscInfo->tiLoLevelResource, 954285809Sscottl &pRscInfo->tiInitiatorResource, 955285809Sscottl NULL, 956285809Sscottl &pRscInfo->tiSharedMem ); 957285809Sscottl 958285809Sscottl agtiapi_ScopeDMARes( thisCardInst ); 959285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: size from the call agtiapi_ScopeDMARes" 960285809Sscottl " 0x%x \n", pmsc->typhn ); 961285809Sscottl 962285809Sscottl // initialize card information and get resource ready 963285809Sscottl if( agtiapi_InitResource( thisCardInst ) == AGTIAPI_FAIL ) { 964285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: Card %d initialize resource ERROR\n", 965285809Sscottl thisCard ); 966285809Sscottl } 967285809Sscottl 968285809Sscottl // begin: allocate and initialize card portal info resource 969285809Sscottl ag_portal_data_t *pPortalData; 970285809Sscottl if (pmsc->portCount == 0) 971285809Sscottl { 972285809Sscottl pmsc->pPortalData = NULL; 973285809Sscottl } 974285809Sscottl else 975285809Sscottl { 976285809Sscottl pmsc->pPortalData = (ag_portal_data_t *) 977285809Sscottl malloc( sizeof(ag_portal_data_t) * pmsc->portCount, 978285809Sscottl M_PMC_MPRT, M_ZERO | M_WAITOK ); 979285809Sscottl if (pmsc->pPortalData == NULL) 980285809Sscottl { 981285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: Portal memory allocation ERROR\n" ); 982285809Sscottl } 983285809Sscottl } 984285809Sscottl 985285809Sscottl pPortalData = pmsc->pPortalData; 986285809Sscottl for( idx = 0; idx < pmsc->portCount; idx++ ) { 987285809Sscottl pPortalData->pCard = pmsc; 988285809Sscottl pPortalData->portalInfo.portID = idx; 989285809Sscottl pPortalData->portalInfo.tiPortalContext.osData = (void *)pPortalData; 990285809Sscottl pPortalData++; 991285809Sscottl } 992285809Sscottl // end: allocate and initialize card portal info resource 993285809Sscottl 994285809Sscottl // begin: enable msix 995285809Sscottl 996285809Sscottl // setup msix 997285809Sscottl // map to interrupt handler 998285809Sscottl int error = 0; 999285809Sscottl int mesgs = MAX_MSIX_NUM_VECTOR; 1000285809Sscottl int i, cnt; 1001285809Sscottl 1002285809Sscottl void (*intrHandler[MAX_MSIX_NUM_ISR])(void *arg) = 1003285809Sscottl { 1004285809Sscottl agtiapi_IntrHandler0, 1005285809Sscottl agtiapi_IntrHandler1, 1006285809Sscottl agtiapi_IntrHandler2, 1007285809Sscottl agtiapi_IntrHandler3, 1008285809Sscottl agtiapi_IntrHandler4, 1009285809Sscottl agtiapi_IntrHandler5, 1010285809Sscottl agtiapi_IntrHandler6, 1011285809Sscottl agtiapi_IntrHandler7, 1012285809Sscottl agtiapi_IntrHandler8, 1013285809Sscottl agtiapi_IntrHandler9, 1014285809Sscottl agtiapi_IntrHandler10, 1015285809Sscottl agtiapi_IntrHandler11, 1016285809Sscottl agtiapi_IntrHandler12, 1017285809Sscottl agtiapi_IntrHandler13, 1018285809Sscottl agtiapi_IntrHandler14, 1019285809Sscottl agtiapi_IntrHandler15 1020285809Sscottl 1021285809Sscottl }; 1022285809Sscottl 1023285809Sscottl cnt = pci_msix_count(devx); 1024285809Sscottl AGTIAPI_PRINTK("supported MSIX %d\n", cnt); //this should be 64 1025285809Sscottl mesgs = MIN(mesgs, cnt); 1026285809Sscottl error = pci_alloc_msix(devx, &mesgs); 1027285809Sscottl if (error != 0) { 1028285809Sscottl printf( "pci_alloc_msix error %d\n", error ); 1029285809Sscottl AGTIAPI_PRINTK("error %d\n", error); 1030285809Sscottl return( EIO ); 1031285809Sscottl } 1032285809Sscottl 1033285809Sscottl for(i=0; i < mesgs; i++) { 1034285809Sscottl pmsc->rscID[i] = i + 1; 1035285809Sscottl pmsc->irq[i] = bus_alloc_resource_any( devx, 1036285809Sscottl SYS_RES_IRQ, 1037285809Sscottl &pmsc->rscID[i], 1038285809Sscottl RF_ACTIVE ); 1039285809Sscottl if( pmsc->irq[i] == NULL ) { 1040285809Sscottl printf( "RES_IRQ went terribly bad at %d\n", i ); 1041285809Sscottl return( EIO ); 1042285809Sscottl } 1043285809Sscottl 1044285809Sscottl if ( (error = bus_setup_intr( devx, pmsc->irq[i], 1045285809Sscottl INTR_TYPE_CAM | INTR_MPSAFE, 1046285809Sscottl NULL, 1047285809Sscottl intrHandler[i], 1048285809Sscottl pmsc, 1049285809Sscottl &pmsc->intrcookie[i] ) 1050285809Sscottl ) != 0 ) { 1051285809Sscottl device_printf( devx, "Failed to register handler" ); 1052285809Sscottl return( EIO ); 1053285809Sscottl } 1054285809Sscottl } 1055285809Sscottl pmsc->flags |= AGTIAPI_IRQ_REQUESTED; 1056285809Sscottl pmsc->pCardInfo->maxInterruptVectors = MAX_MSIX_NUM_VECTOR; 1057285809Sscottl // end: enable msix 1058285809Sscottl 1059285809Sscottl int ret = 0; 1060285809Sscottl ret = agtiapi_InitCardSW(pmsc); 1061285809Sscottl if (ret == AGTIAPI_FAIL || ret == AGTIAPI_UNKNOWN) 1062285809Sscottl { 1063285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardSW failure %d\n", 1064285809Sscottl ret ); 1065285809Sscottl return( EIO ); 1066285809Sscottl } 1067285809Sscottl 1068285809Sscottl pmsc->ccbFreeList = NULL; 1069285809Sscottl pmsc->ccbChainList = NULL; 1070285809Sscottl pmsc->ccbAllocList = NULL; 1071285809Sscottl 1072285809Sscottl pmsc->flags |= ( AGTIAPI_INSTALLED ); 1073285809Sscottl 1074285809Sscottl ret = agtiapi_alloc_requests( pmsc ); 1075285809Sscottl if( ret != 0 ) { 1076285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_requests failure %d\n", 1077285809Sscottl ret ); 1078285809Sscottl return( EIO ); 1079285809Sscottl } 1080285809Sscottl 1081285809Sscottl ret = agtiapi_alloc_ostimem( pmsc ); 1082285809Sscottl if (ret != AGTIAPI_SUCCESS) 1083285809Sscottl { 1084285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_alloc_ostimem failure %d\n", 1085285809Sscottl ret ); 1086285809Sscottl return( EIO ); 1087285809Sscottl } 1088285809Sscottl 1089285809Sscottl ret = agtiapi_InitCardHW( pmsc ); 1090285809Sscottl if (ret != 0) 1091285809Sscottl { 1092285809Sscottl AGTIAPI_PRINTK( "agtiapi_attach: agtiapi_InitCardHW failure %d\n", 1093285809Sscottl ret ); 1094285809Sscottl return( EIO ); 1095285809Sscottl } 1096285809Sscottl 1097285809Sscottl#ifdef HIALEAH_ENCRYPTION 1098285809Sscottl if(pmsc->encrypt) 1099285809Sscottl { 1100285809Sscottl if((agtiapi_SetupEncryption(pmsc)) < 0) 1101285809Sscottl AGTIAPI_PRINTK("SetupEncryption returned less than 0\n"); 1102285809Sscottl } 1103285809Sscottl#endif 1104285809Sscottl 1105285809Sscottl pmsc->flags &= ~AGTIAPI_INIT_TIME; 1106285809Sscottl return( 0 ); 1107285809Sscottl} 1108285809Sscottl 1109285809Sscottl/****************************************************************************** 1110285809Sscottlagtiapi_InitCardSW() 1111285809Sscottl 1112285809SscottlPurpose: 1113285809Sscottl Host Bus Adapter Initialization 1114285809SscottlParameters: 1115285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 1116285809SscottlReturn: 1117285809Sscottl AGTIAPI_SUCCESS - success 1118285809Sscottl AGTIAPI_FAIL - fail 1119285809SscottlNote: 1120285809Sscottl TBD, need chip register information 1121285809Sscottl******************************************************************************/ 1122285809SscottlSTATIC agBOOLEAN agtiapi_InitCardSW( struct agtiapi_softc *pmsc ) 1123285809Sscottl{ 1124285809Sscottl ag_card_info_t *thisCardInst = pmsc->pCardInfo; 1125285809Sscottl ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo; 1126285809Sscottl int initSWIdx; 1127285809Sscottl 1128285809Sscottl // begin: agtiapi_InitCardSW() 1129285809Sscottl // now init some essential locks n agtiapi_InitCardSW 1130285809Sscottl mtx_init( &pmsc->sendLock, "local q send lock", NULL, MTX_DEF ); 1131285809Sscottl mtx_init( &pmsc->doneLock, "local q done lock", NULL, MTX_DEF ); 1132285809Sscottl mtx_init( &pmsc->sendSMPLock, "local q send lock", NULL, MTX_DEF ); 1133285809Sscottl mtx_init( &pmsc->doneSMPLock, "local q done lock", NULL, MTX_DEF ); 1134285809Sscottl mtx_init( &pmsc->ccbLock, "ccb list lock", NULL, MTX_DEF ); 1135285809Sscottl mtx_init( &pmsc->devListLock, "hotP devListLock", NULL, MTX_DEF ); 1136285809Sscottl mtx_init( &pmsc->memLock, "dynamic memory lock", NULL, MTX_DEF ); 1137285809Sscottl mtx_init( &pmsc->freezeLock, "sim freeze lock", NULL, MTX_DEF | MTX_RECURSE); 1138285809Sscottl 1139285809Sscottl // initialize lower layer resources 1140285809Sscottl //## if (pCard->flags & AGTIAPI_INIT_TIME) { 1141285809Sscottl#ifdef HIALEAH_ENCRYPTION 1142285809Sscottl /* Enable encryption if chip supports it */ 1143285809Sscottl if (pci_get_device(pmsc->pCardInfo->pPCIDev) == 1144285809Sscottl PCI_DEVICE_ID_HIALEAH_HBA_SPCVE) 1145285809Sscottl pmsc->encrypt = 1; 1146285809Sscottl 1147285809Sscottl if (pmsc->encrypt) 1148285809Sscottl pRscInfo->tiLoLevelResource.loLevelOption.encryption = agTRUE; 1149285809Sscottl#endif 1150285809Sscottl pmsc->flags &= ~(AGTIAPI_PORT_INITIALIZED | AGTIAPI_SYS_INTR_ON); 1151285809Sscottl 1152285809Sscottl 1153285809Sscottl // For now, up to 16 MSIX vectors are supported 1154285809Sscottl thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption. 1155285809Sscottl maxInterruptVectors = pmsc->pCardInfo->maxInterruptVectors; 1156285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardSW: maxInterruptVectors set to %d", 1157285809Sscottl pmsc->pCardInfo->maxInterruptVectors ); 1158285809Sscottl thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.max_MSI_InterruptVectors = 0; 1159285809Sscottl thisCardInst->tiRscInfo.tiLoLevelResource.loLevelOption.flag = 0; 1160285809Sscottl pRscInfo->tiLoLevelResource.loLevelOption.maxNumOSLocks = 0; 1161285809Sscottl 1162285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit root %p, dev %p, pmsc %p\n", 1163285809Sscottl &pmsc->tiRoot, pmsc->my_dev, pmsc ); 1164285809Sscottl if( tiCOMInit( &pmsc->tiRoot, 1165285809Sscottl &thisCardInst->tiRscInfo.tiLoLevelResource, 1166285809Sscottl &thisCardInst->tiRscInfo.tiInitiatorResource, 1167285809Sscottl NULL, 1168285809Sscottl &thisCardInst->tiRscInfo.tiSharedMem ) != tiSuccess ) { 1169285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMInit ERROR\n" ); 1170285809Sscottl return AGTIAPI_FAIL; 1171285809Sscottl } 1172285809Sscottl int maxLocks; 1173285809Sscottl maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort; 1174285809Sscottl pmsc->STLock = malloc( ( maxLocks * sizeof(struct mtx) ), M_PMC_MSTL, 1175285809Sscottl M_ZERO | M_WAITOK ); 1176285809Sscottl 1177285809Sscottl for( initSWIdx = 0; initSWIdx < maxLocks; initSWIdx++ ) 1178285809Sscottl { 1179285809Sscottl // init all indexes 1180285809Sscottl mtx_init( &pmsc->STLock[initSWIdx], "LL & TD lock", NULL, MTX_DEF ); 1181285809Sscottl } 1182285809Sscottl 1183285809Sscottl if( tiCOMPortInit( &pmsc->tiRoot, agFALSE ) != tiSuccess ) { 1184285809Sscottl printf( "agtiapi_InitCardSW: tiCOMPortInit ERROR -- AGTIAPI_FAIL\n" ); 1185285809Sscottl return AGTIAPI_FAIL; 1186285809Sscottl } 1187285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardSW: tiCOMPortInit" 1188285809Sscottl " root %p, dev %p, pmsc %p\n", 1189285809Sscottl &pmsc->tiRoot, pmsc->my_dev, pmsc ); 1190285809Sscottl 1191285809Sscottl pmsc->flags |= AGTIAPI_PORT_INITIALIZED; 1192285809Sscottl pmsc->freezeSim = agFALSE; 1193285809Sscottl 1194285809Sscottl#ifdef HIALEAH_ENCRYPTION 1195285809Sscottl atomic_set(&outstanding_encrypted_io_count, 0); 1196285809Sscottl /*fix below*/ 1197285809Sscottl /*if(pmsc->encrypt && (pmsc->flags & AGTIAPI_INIT_TIME)) 1198285809Sscottl if((agtiapi_SetupEncryptionPools(pmsc)) != 0) 1199285809Sscottl printf("SetupEncryptionPools failed\n"); */ 1200285809Sscottl#endif 1201285809Sscottl return AGTIAPI_SUCCESS; 1202285809Sscottl // end: agtiapi_InitCardSW() 1203285809Sscottl} 1204285809Sscottl 1205285809Sscottl/****************************************************************************** 1206285809Sscottlagtiapi_InitCardHW() 1207285809Sscottl 1208285809SscottlPurpose: 1209285809Sscottl Host Bus Adapter Initialization 1210285809SscottlParameters: 1211285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 1212285809SscottlReturn: 1213285809Sscottl AGTIAPI_SUCCESS - success 1214285809Sscottl AGTIAPI_FAIL - fail 1215285809SscottlNote: 1216285809Sscottl TBD, need chip register information 1217285809Sscottl******************************************************************************/ 1218285809SscottlSTATIC agBOOLEAN agtiapi_InitCardHW( struct agtiapi_softc *pmsc ) 1219285809Sscottl{ 1220285809Sscottl U32 numVal; 1221285809Sscottl U32 count; 1222285809Sscottl U32 loop; 1223285809Sscottl // begin: agtiapi_InitCardHW() 1224285809Sscottl 1225285809Sscottl ag_portal_info_t *pPortalInfo = NULL; 1226285809Sscottl ag_portal_data_t *pPortalData; 1227285809Sscottl 1228285809Sscottl // ISR is registered, enable chip interrupt. 1229285809Sscottl tiCOMSystemInterruptsActive( &pmsc->tiRoot, agTRUE ); 1230285809Sscottl pmsc->flags |= AGTIAPI_SYS_INTR_ON; 1231285809Sscottl 1232285809Sscottl numVal = sizeof(ag_device_t) * pmsc->devDiscover; 1233285809Sscottl pmsc->pDevList = 1234285809Sscottl (ag_device_t *)malloc( numVal, M_PMC_MDVT, M_ZERO | M_WAITOK ); 1235285809Sscottl if( !pmsc->pDevList ) { 1236285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d DevList ERROR\n", numVal ); 1237285809Sscottl panic( "agtiapi_InitCardHW\n" ); 1238285809Sscottl return AGTIAPI_FAIL; 1239285809Sscottl } 1240285809Sscottl 1241285809Sscottl#ifdef LINUX_PERBI_SUPPORT 1242285809Sscottl numVal = sizeof(ag_slr_map_t) * pmsc->devDiscover; 1243285809Sscottl pmsc->pSLRList = 1244285809Sscottl (ag_slr_map_t *)malloc( numVal, M_PMC_MSLR, M_ZERO | M_WAITOK ); 1245285809Sscottl if( !pmsc->pSLRList ) { 1246285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d SLRList ERROR\n", numVal ); 1247285809Sscottl panic( "agtiapi_InitCardHW SLRL\n" ); 1248285809Sscottl return AGTIAPI_FAIL; 1249285809Sscottl } 1250285809Sscottl 1251285809Sscottl numVal = sizeof(ag_tgt_map_t) * pmsc->devDiscover; 1252285809Sscottl pmsc->pWWNList = 1253285809Sscottl (ag_tgt_map_t *)malloc( numVal, M_PMC_MTGT, M_ZERO | M_WAITOK ); 1254285809Sscottl if( !pmsc->pWWNList ) { 1255285809Sscottl AGTIAPI_PRINTK( "agtiapi_InitCardHW: kmalloc %d WWNList ERROR\n", numVal ); 1256285809Sscottl panic( "agtiapi_InitCardHW WWNL\n" ); 1257285809Sscottl return AGTIAPI_FAIL; 1258285809Sscottl } 1259285809Sscottl 1260285809Sscottl // Get the WWN_to_target_ID mappings from the 1261285809Sscottl // holding area which contains the input of the 1262285809Sscottl // system configuration file. 1263285809Sscottl if( ag_Perbi ) 1264285809Sscottl agtiapi_GetWWNMappings( pmsc, agMappingList ); 1265285809Sscottl else { 1266285809Sscottl agtiapi_GetWWNMappings( pmsc, 0 ); 1267285809Sscottl if( agMappingList ) 1268285809Sscottl printf( "agtiapi_InitCardHW: WWN PERBI disabled WARN\n" ); 1269285809Sscottl } 1270285809Sscottl#endif 1271285809Sscottl 1272285809Sscottl //agtiapi_DelaySec(5); 1273285809Sscottl DELAY( 500000 ); 1274285809Sscottl 1275285809Sscottl pmsc->tgtCount = 0; 1276285809Sscottl 1277285809Sscottl pmsc->flags &= ~AGTIAPI_CB_DONE; 1278285809Sscottl pPortalData = pmsc->pPortalData; 1279285809Sscottl 1280285809Sscottl //start port 1281285809Sscottl 1282285809Sscottl for (count = 0; count < pmsc->portCount; count++) 1283285809Sscottl { 1284285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags ); 1285285809Sscottl 1286285809Sscottl pPortalInfo = &pPortalData->portalInfo; 1287285809Sscottl pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START | 1288285809Sscottl AGTIAPI_PORT_DISC_READY | 1289285809Sscottl AGTIAPI_DISC_DONE | 1290285809Sscottl AGTIAPI_DISC_COMPLETE ); 1291285809Sscottl 1292285809Sscottl for (loop = 0; loop < AGTIAPI_LOOP_MAX; loop++) 1293285809Sscottl { 1294285809Sscottl AGTIAPI_PRINTK( "tiCOMPortStart entry data %p / %d / %p\n", 1295285809Sscottl &pmsc->tiRoot, 1296285809Sscottl pPortalInfo->portID, 1297285809Sscottl &pPortalInfo->tiPortalContext ); 1298285809Sscottl 1299285809Sscottl if( tiCOMPortStart( &pmsc->tiRoot, 1300285809Sscottl pPortalInfo->portID, 1301285809Sscottl &pPortalInfo->tiPortalContext, 1302285809Sscottl 0 ) 1303285809Sscottl != tiSuccess ) { 1304285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 1305285809Sscottl agtiapi_DelayMSec( AGTIAPI_EXTRA_DELAY ); 1306285809Sscottl AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags); 1307285809Sscottl AGTIAPI_PRINTK( "tiCOMPortStart failed -- no loop, portalData %p\n", 1308285809Sscottl pPortalData ); 1309285809Sscottl } 1310285809Sscottl else { 1311285809Sscottl AGTIAPI_PRINTK( "tiCOMPortStart success no loop, portalData %p\n", 1312285809Sscottl pPortalData ); 1313285809Sscottl break; 1314285809Sscottl } 1315285809Sscottl } // end of for loop 1316285809Sscottl /* release lock */ 1317285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 1318285809Sscottl 1319285809Sscottl if( loop >= AGTIAPI_LOOP_MAX ) { 1320285809Sscottl return AGTIAPI_FAIL; 1321285809Sscottl } 1322285809Sscottl tiCOMGetPortInfo( &pmsc->tiRoot, 1323285809Sscottl &pPortalInfo->tiPortalContext, 1324285809Sscottl &pPortalInfo->tiPortInfo ); 1325285809Sscottl pPortalData++; 1326285809Sscottl } 1327285809Sscottl 1328285809Sscottl /* discover target device */ 1329285809Sscottl#ifndef HOTPLUG_SUPPORT 1330285809Sscottl agtiapi_DiscoverTgt( pCard ); 1331285809Sscottl#endif 1332285809Sscottl 1333285809Sscottl 1334285809Sscottl pmsc->flags |= AGTIAPI_INSTALLED; 1335285809Sscottl 1336285809Sscottl if( pmsc->flags & AGTIAPI_INIT_TIME ) { 1337285809Sscottl agtiapi_TITimer( (void *)pmsc ); 1338285809Sscottl pmsc->flags |= AGTIAPI_TIMER_ON; 1339285809Sscottl } 1340285809Sscottl 1341285809Sscottl return 0; 1342285809Sscottl} 1343285809Sscottl 1344285809Sscottl 1345285809Sscottl 1346285809Sscottl/****************************************************************************** 1347285809Sscottlagtiapi_IntrHandlerx_() 1348285809Sscottl 1349285809SscottlPurpose: 1350285809Sscottl Interrupt service routine. 1351285809SscottlParameters: 1352285809Sscottl void arg (IN) Pointer to the HBA data structure 1353285809Sscottl bit32 idx (IN) Vector index 1354285809Sscottl******************************************************************************/ 1355285809Sscottlvoid agtiapi_IntrHandlerx_( void *arg, int index ) 1356285809Sscottl{ 1357285809Sscottl 1358285809Sscottl struct agtiapi_softc *pCard; 1359285809Sscottl int rv; 1360285809Sscottl 1361285809Sscottl pCard = (struct agtiapi_softc *)arg; 1362285809Sscottl 1363285809Sscottl#ifndef AGTIAPI_DPC 1364285809Sscottl ccb_t *pccb; 1365285809Sscottl#endif 1366285809Sscottl 1367285809Sscottl AG_LOCAL_LOCK(&(pCard->pCardInfo->pmIOLock)); 1368285809Sscottl AG_PERF_SPINLOCK(agtiapi_host_lock); 1369285809Sscottl if (pCard->flags & AGTIAPI_SHUT_DOWN) 1370285809Sscottl goto ext; 1371285809Sscottl 1372285809Sscottl rv = tiCOMInterruptHandler(&pCard->tiRoot, index); 1373285809Sscottl if (rv == agFALSE) 1374285809Sscottl { 1375285809Sscottl /* not our irq */ 1376285809Sscottl AG_SPIN_UNLOCK(agtiapi_host_lock); 1377285809Sscottl AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock)); 1378285809Sscottl return; 1379285809Sscottl } 1380285809Sscottl 1381285809Sscottl 1382285809Sscottl#ifdef AGTIAPI_DPC 1383285809Sscottl tasklet_hi_schedule(&pCard->tasklet_dpc[idx]); 1384285809Sscottl#else 1385285809Sscottl /* consume all completed entries, 100 is random number to be big enough */ 1386285809Sscottl tiCOMDelayedInterruptHandler(&pCard->tiRoot, index, 100, tiInterruptContext); 1387285809Sscottl AG_GET_DONE_PCCB(pccb, pCard); 1388285809Sscottl AG_GET_DONE_SMP_PCCB(pccb, pCard); 1389285809Sscottl#endif 1390285809Sscottl 1391285809Sscottlext: 1392285809Sscottl AG_SPIN_UNLOCK(agtiapi_host_lock); 1393285809Sscottl AG_LOCAL_UNLOCK(&(pCard->pCardInfo->pmIOLock)); 1394285809Sscottl return; 1395285809Sscottl 1396285809Sscottl} 1397285809Sscottl 1398285809Sscottl/****************************************************************************** 1399285809Sscottlagtiapi_IntrHandler0() 1400285809SscottlPurpose: Interrupt service routine for interrupt vector index 0. 1401285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1402285809Sscottl******************************************************************************/ 1403285809Sscottlvoid agtiapi_IntrHandler0( void *arg ) 1404285809Sscottl{ 1405285809Sscottl agtiapi_IntrHandlerx_( arg, 0 ); 1406285809Sscottl return; 1407285809Sscottl} 1408285809Sscottl 1409285809Sscottl/****************************************************************************** 1410285809Sscottlagtiapi_IntrHandler1() 1411285809SscottlPurpose: Interrupt service routine for interrupt vector index 1. 1412285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1413285809Sscottl******************************************************************************/ 1414285809Sscottlvoid agtiapi_IntrHandler1( void *arg ) 1415285809Sscottl{ 1416285809Sscottl agtiapi_IntrHandlerx_( arg, 1 ); 1417285809Sscottl return; 1418285809Sscottl} 1419285809Sscottl 1420285809Sscottl/****************************************************************************** 1421285809Sscottlagtiapi_IntrHandler2() 1422285809SscottlPurpose: Interrupt service routine for interrupt vector index 2. 1423285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1424285809Sscottl******************************************************************************/ 1425285809Sscottlvoid agtiapi_IntrHandler2( void *arg ) 1426285809Sscottl{ 1427285809Sscottl agtiapi_IntrHandlerx_( arg, 2 ); 1428285809Sscottl return; 1429285809Sscottl} 1430285809Sscottl 1431285809Sscottl/****************************************************************************** 1432285809Sscottlagtiapi_IntrHandler3() 1433285809SscottlPurpose: Interrupt service routine for interrupt vector index 3. 1434285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1435285809Sscottl******************************************************************************/ 1436285809Sscottlvoid agtiapi_IntrHandler3( void *arg ) 1437285809Sscottl{ 1438285809Sscottl agtiapi_IntrHandlerx_( arg, 3 ); 1439285809Sscottl return; 1440285809Sscottl} 1441285809Sscottl 1442285809Sscottl/****************************************************************************** 1443285809Sscottlagtiapi_IntrHandler4() 1444285809SscottlPurpose: Interrupt service routine for interrupt vector index 4. 1445285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1446285809Sscottl******************************************************************************/ 1447285809Sscottlvoid agtiapi_IntrHandler4( void *arg ) 1448285809Sscottl{ 1449285809Sscottl agtiapi_IntrHandlerx_( arg, 4 ); 1450285809Sscottl return; 1451285809Sscottl} 1452285809Sscottl 1453285809Sscottl/****************************************************************************** 1454285809Sscottlagtiapi_IntrHandler5() 1455285809SscottlPurpose: Interrupt service routine for interrupt vector index 5. 1456285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1457285809Sscottl******************************************************************************/ 1458285809Sscottlvoid agtiapi_IntrHandler5( void *arg ) 1459285809Sscottl{ 1460285809Sscottl agtiapi_IntrHandlerx_( arg, 5 ); 1461285809Sscottl return; 1462285809Sscottl} 1463285809Sscottl 1464285809Sscottl/****************************************************************************** 1465285809Sscottlagtiapi_IntrHandler6() 1466285809SscottlPurpose: Interrupt service routine for interrupt vector index 6. 1467285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1468285809Sscottl******************************************************************************/ 1469285809Sscottlvoid agtiapi_IntrHandler6( void *arg ) 1470285809Sscottl{ 1471285809Sscottl agtiapi_IntrHandlerx_( arg, 6 ); 1472285809Sscottl return; 1473285809Sscottl} 1474285809Sscottl 1475285809Sscottl/****************************************************************************** 1476285809Sscottlagtiapi_IntrHandler7() 1477285809SscottlPurpose: Interrupt service routine for interrupt vector index 7. 1478285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1479285809Sscottl******************************************************************************/ 1480285809Sscottlvoid agtiapi_IntrHandler7( void *arg ) 1481285809Sscottl{ 1482285809Sscottl agtiapi_IntrHandlerx_( arg, 7 ); 1483285809Sscottl return; 1484285809Sscottl} 1485285809Sscottl 1486285809Sscottl/****************************************************************************** 1487285809Sscottlagtiapi_IntrHandler8() 1488285809SscottlPurpose: Interrupt service routine for interrupt vector index 8. 1489285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1490285809Sscottl******************************************************************************/ 1491285809Sscottlvoid agtiapi_IntrHandler8( void *arg ) 1492285809Sscottl{ 1493285809Sscottl agtiapi_IntrHandlerx_( arg, 8 ); 1494285809Sscottl return; 1495285809Sscottl} 1496285809Sscottl 1497285809Sscottl/****************************************************************************** 1498285809Sscottlagtiapi_IntrHandler9() 1499285809SscottlPurpose: Interrupt service routine for interrupt vector index 9. 1500285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1501285809Sscottl******************************************************************************/ 1502285809Sscottlvoid agtiapi_IntrHandler9( void *arg ) 1503285809Sscottl{ 1504285809Sscottl agtiapi_IntrHandlerx_( arg, 9 ); 1505285809Sscottl return; 1506285809Sscottl} 1507285809Sscottl 1508285809Sscottl/****************************************************************************** 1509285809Sscottlagtiapi_IntrHandler10() 1510285809SscottlPurpose: Interrupt service routine for interrupt vector index 10. 1511285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1512285809Sscottl******************************************************************************/ 1513285809Sscottlvoid agtiapi_IntrHandler10( void *arg ) 1514285809Sscottl{ 1515285809Sscottl agtiapi_IntrHandlerx_( arg, 10 ); 1516285809Sscottl return; 1517285809Sscottl} 1518285809Sscottl 1519285809Sscottl/****************************************************************************** 1520285809Sscottlagtiapi_IntrHandler11() 1521285809SscottlPurpose: Interrupt service routine for interrupt vector index 11. 1522285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1523285809Sscottl******************************************************************************/ 1524285809Sscottlvoid agtiapi_IntrHandler11( void *arg ) 1525285809Sscottl{ 1526285809Sscottl agtiapi_IntrHandlerx_( arg, 11 ); 1527285809Sscottl return; 1528285809Sscottl} 1529285809Sscottl 1530285809Sscottl/****************************************************************************** 1531285809Sscottlagtiapi_IntrHandler12() 1532285809SscottlPurpose: Interrupt service routine for interrupt vector index 12. 1533285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1534285809Sscottl******************************************************************************/ 1535285809Sscottlvoid agtiapi_IntrHandler12( void *arg ) 1536285809Sscottl{ 1537285809Sscottl agtiapi_IntrHandlerx_( arg, 12 ); 1538285809Sscottl return; 1539285809Sscottl} 1540285809Sscottl 1541285809Sscottl/****************************************************************************** 1542285809Sscottlagtiapi_IntrHandler13() 1543285809SscottlPurpose: Interrupt service routine for interrupt vector index 13. 1544285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1545285809Sscottl******************************************************************************/ 1546285809Sscottlvoid agtiapi_IntrHandler13( void *arg ) 1547285809Sscottl{ 1548285809Sscottl agtiapi_IntrHandlerx_( arg, 13 ); 1549285809Sscottl return; 1550285809Sscottl} 1551285809Sscottl 1552285809Sscottl/****************************************************************************** 1553285809Sscottlagtiapi_IntrHandler14() 1554285809SscottlPurpose: Interrupt service routine for interrupt vector index 14. 1555285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1556285809Sscottl******************************************************************************/ 1557285809Sscottlvoid agtiapi_IntrHandler14( void *arg ) 1558285809Sscottl{ 1559285809Sscottl agtiapi_IntrHandlerx_( arg, 14 ); 1560285809Sscottl return; 1561285809Sscottl} 1562285809Sscottl 1563285809Sscottl/****************************************************************************** 1564285809Sscottlagtiapi_IntrHandler15() 1565285809SscottlPurpose: Interrupt service routine for interrupt vector index 15. 1566285809SscottlParameters: void arg (IN) Pointer to the HBA data structure 1567285809Sscottl******************************************************************************/ 1568285809Sscottlvoid agtiapi_IntrHandler15( void *arg ) 1569285809Sscottl{ 1570285809Sscottl agtiapi_IntrHandlerx_( arg, 15 ); 1571285809Sscottl return; 1572285809Sscottl} 1573285809Sscottl 1574285809Sscottlstatic void agtiapi_SglMemoryCB( void *arg, 1575285809Sscottl bus_dma_segment_t *dm_segs, 1576285809Sscottl int nseg, 1577285809Sscottl int error ) 1578285809Sscottl{ 1579285809Sscottl bus_addr_t *addr; 1580285809Sscottl AGTIAPI_PRINTK("agtiapi_SglMemoryCB: start\n"); 1581285809Sscottl if (error != 0) 1582285809Sscottl { 1583285809Sscottl AGTIAPI_PRINTK("agtiapi_SglMemoryCB: error %d\n", error); 1584285809Sscottl panic("agtiapi_SglMemoryCB: error %d\n", error); 1585285809Sscottl return; 1586285809Sscottl } 1587285809Sscottl addr = arg; 1588285809Sscottl *addr = dm_segs[0].ds_addr; 1589285809Sscottl return; 1590285809Sscottl} 1591285809Sscottl 1592285809Sscottlstatic void agtiapi_MemoryCB( void *arg, 1593285809Sscottl bus_dma_segment_t *dm_segs, 1594285809Sscottl int nseg, 1595285809Sscottl int error ) 1596285809Sscottl{ 1597285809Sscottl bus_addr_t *addr; 1598285809Sscottl AGTIAPI_PRINTK("agtiapi_MemoryCB: start\n"); 1599285809Sscottl if (error != 0) 1600285809Sscottl { 1601285809Sscottl AGTIAPI_PRINTK("agtiapi_MemoryCB: error %d\n", error); 1602285809Sscottl panic("agtiapi_MemoryCB: error %d\n", error); 1603285809Sscottl return; 1604285809Sscottl } 1605285809Sscottl addr = arg; 1606285809Sscottl *addr = dm_segs[0].ds_addr; 1607285809Sscottl return; 1608285809Sscottl} 1609285809Sscottl 1610285809Sscottl/****************************************************************************** 1611285809Sscottlagtiapi_alloc_requests() 1612285809Sscottl 1613285809SscottlPurpose: 1614285809Sscottl Allocates resources such as dma tag and timer 1615285809SscottlParameters: 1616285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 1617285809SscottlReturn: 1618285809Sscottl AGTIAPI_SUCCESS - success 1619285809Sscottl AGTIAPI_FAIL - fail 1620285809SscottlNote: 1621285809Sscottl******************************************************************************/ 1622285809Sscottlint agtiapi_alloc_requests( struct agtiapi_softc *pmcsc ) 1623285809Sscottl{ 1624285809Sscottl 1625285809Sscottl int rsize, nsegs; 1626285809Sscottl U32 next_tick; 1627285809Sscottl 1628285809Sscottl nsegs = AGTIAPI_NSEGS; 1629285809Sscottl rsize = AGTIAPI_MAX_DMA_SEGS; // 128 1630285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: MAXPHYS 0x%x PAGE_SIZE 0x%x \n", 1631285809Sscottl MAXPHYS, PAGE_SIZE ); 1632285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: nsegs %d rsize %d \n", 1633285809Sscottl nsegs, rsize ); // 32, 128 1634285809Sscottl // This is for csio->data_ptr 1635285809Sscottl if( bus_dma_tag_create( agNULL, // parent 1636285809Sscottl 1, // alignment 1637285809Sscottl 0, // boundary 1638285809Sscottl BUS_SPACE_MAXADDR, // lowaddr 1639285809Sscottl BUS_SPACE_MAXADDR, // highaddr 1640285809Sscottl NULL, // filter 1641285809Sscottl NULL, // filterarg 1642285809Sscottl BUS_SPACE_MAXSIZE_32BIT, // maxsize 1643285809Sscottl nsegs, // nsegments 1644285809Sscottl BUS_SPACE_MAXSIZE_32BIT, // maxsegsize 1645285809Sscottl BUS_DMA_ALLOCNOW, // flags 1646285809Sscottl busdma_lock_mutex, // lockfunc 1647285809Sscottl &pmcsc->pCardInfo->pmIOLock, // lockarg 1648285809Sscottl &pmcsc->buffer_dmat ) ) { 1649285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" ); 1650285809Sscottl return( ENOMEM ); 1651285809Sscottl } 1652285809Sscottl 1653285809Sscottl // This is for tiSgl_t of pccb in agtiapi_PrepCCBs() 1654285809Sscottl rsize = 1655285809Sscottl (sizeof(tiSgl_t) * AGTIAPI_NSEGS) * 1656285809Sscottl AGTIAPI_CCB_PER_DEVICE * maxTargets; 1657285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: rsize %d \n", rsize ); // 32, 128 1658285809Sscottl if( bus_dma_tag_create( agNULL, // parent 1659285809Sscottl 32, // alignment 1660285809Sscottl 0, // boundary 1661285809Sscottl BUS_SPACE_MAXADDR_32BIT, // lowaddr 1662285809Sscottl BUS_SPACE_MAXADDR, // highaddr 1663285809Sscottl NULL, // filter 1664285809Sscottl NULL, // filterarg 1665285809Sscottl rsize, // maxsize 1666285809Sscottl 1, // nsegments 1667285809Sscottl rsize, // maxsegsize 1668285809Sscottl BUS_DMA_ALLOCNOW, // flags 1669285809Sscottl NULL, // lockfunc 1670285809Sscottl NULL, // lockarg 1671285809Sscottl &pmcsc->tisgl_dmat ) ) { 1672285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot alloc request DMA tag\n" ); 1673285809Sscottl return( ENOMEM ); 1674285809Sscottl } 1675285809Sscottl 1676285809Sscottl if( bus_dmamem_alloc( pmcsc->tisgl_dmat, 1677285809Sscottl (void **)&pmcsc->tisgl_mem, 1678285809Sscottl BUS_DMA_NOWAIT, 1679285809Sscottl &pmcsc->tisgl_map ) ) { 1680285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: Cannot allocate SGL memory\n" ); 1681285809Sscottl return( ENOMEM ); 1682285809Sscottl } 1683285809Sscottl 1684285809Sscottl bzero( pmcsc->tisgl_mem, rsize ); 1685285809Sscottl bus_dmamap_load( pmcsc->tisgl_dmat, 1686285809Sscottl pmcsc->tisgl_map, 1687285809Sscottl pmcsc->tisgl_mem, 1688285809Sscottl rsize, 1689285809Sscottl agtiapi_SglMemoryCB, 1690285809Sscottl &pmcsc->tisgl_busaddr, 1691285809Sscottl BUS_DMA_NOWAIT /* 0 */ ); 1692285809Sscottl 1693285809Sscottl mtx_init( &pmcsc->OS_timer_lock, "OS timer lock", NULL, MTX_DEF ); 1694285809Sscottl mtx_init( &pmcsc->IO_timer_lock, "IO timer lock", NULL, MTX_DEF ); 1695285809Sscottl mtx_init( &pmcsc->devRmTimerLock, "targ rm timer lock", NULL, MTX_DEF ); 1696285809Sscottl callout_init_mtx( &pmcsc->OS_timer, &pmcsc->OS_timer_lock, 0 ); 1697285809Sscottl callout_init_mtx( &pmcsc->IO_timer, &pmcsc->IO_timer_lock, 0 ); 1698285809Sscottl callout_init_mtx( &pmcsc->devRmTimer, 1699285809Sscottl &pmcsc->devRmTimerLock, 0); 1700285809Sscottl 1701285809Sscottl next_tick = pmcsc->pCardInfo->tiRscInfo.tiLoLevelResource. 1702285809Sscottl loLevelOption.usecsPerTick / USEC_PER_TICK; 1703285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_requests: before callout_reset, " 1704285809Sscottl "next_tick 0x%x\n", next_tick ); 1705285809Sscottl callout_reset( &pmcsc->OS_timer, next_tick, agtiapi_TITimer, pmcsc ); 1706285809Sscottl return 0; 1707285809Sscottl} 1708285809Sscottl 1709285809Sscottl/****************************************************************************** 1710285809Sscottlagtiapi_alloc_ostimem() 1711285809Sscottl 1712285809SscottlPurpose: 1713285809Sscottl Allocates memory used later in ostiAllocMemory 1714285809SscottlParameters: 1715285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to the HBA data structure 1716285809SscottlReturn: 1717285809Sscottl AGTIAPI_SUCCESS - success 1718285809Sscottl AGTIAPI_FAIL - fail 1719285809SscottlNote: 1720285809Sscottl This is a pre-allocation for ostiAllocMemory() "non-cacheable" function calls 1721285809Sscottl******************************************************************************/ 1722285809Sscottlint agtiapi_alloc_ostimem( struct agtiapi_softc *pmcsc ) { 1723285809Sscottl int rsize, nomsize; 1724285809Sscottl 1725285809Sscottl nomsize = 4096; 1726285809Sscottl rsize = AGTIAPI_DYNAMIC_MAX * nomsize; // 8M 1727285809Sscottl AGTIAPI_PRINTK("agtiapi_alloc_ostimem: rsize %d \n", rsize); 1728285809Sscottl 1729285809Sscottl if( bus_dma_tag_create( agNULL, // parent 1730285809Sscottl 32, // alignment 1731285809Sscottl 0, // boundary 1732285809Sscottl BUS_SPACE_MAXADDR, // lowaddr 1733285809Sscottl BUS_SPACE_MAXADDR, // highaddr 1734285809Sscottl NULL, // filter 1735285809Sscottl NULL, // filterarg 1736285809Sscottl rsize, // maxsize (size) 1737285809Sscottl 1, // number of segments 1738285809Sscottl rsize, // maxsegsize 1739285809Sscottl 0, // flags 1740285809Sscottl NULL, // lockfunc 1741285809Sscottl NULL, // lockarg 1742285809Sscottl &pmcsc->osti_dmat ) ) { 1743285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Can't create no-cache mem tag\n" ); 1744285809Sscottl return AGTIAPI_FAIL; 1745285809Sscottl } 1746285809Sscottl 1747285809Sscottl 1748285809Sscottl if( bus_dmamem_alloc( pmcsc->osti_dmat, 1749285809Sscottl &pmcsc->osti_mem, 1750285809Sscottl BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, 1751285809Sscottl &pmcsc->osti_mapp ) ) { 1752285809Sscottl AGTIAPI_PRINTK( "agtiapi_alloc_ostimem: Cannot allocate cache mem %d\n", 1753285809Sscottl rsize ); 1754285809Sscottl return AGTIAPI_FAIL; 1755285809Sscottl } 1756285809Sscottl 1757285809Sscottl 1758285809Sscottl bus_dmamap_load( pmcsc->osti_dmat, 1759285809Sscottl pmcsc->osti_mapp, 1760285809Sscottl pmcsc->osti_mem, 1761285809Sscottl rsize, 1762285809Sscottl agtiapi_MemoryCB, // try reuse of CB for same goal 1763285809Sscottl &pmcsc->osti_busaddr, 1764285809Sscottl BUS_DMA_NOWAIT ); 1765285809Sscottl 1766285809Sscottl // populate all the ag_dma_addr_t osti_busaddr/mem fields with addresses for 1767285809Sscottl // handy reference when driver is in motion 1768285809Sscottl int idx; 1769285809Sscottl ag_card_info_t *pCardInfo = pmcsc->pCardInfo; 1770285809Sscottl ag_dma_addr_t *pMem; 1771285809Sscottl 1772285809Sscottl for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) { 1773285809Sscottl pMem = &pCardInfo->dynamicMem[idx]; 1774285809Sscottl pMem->nocache_busaddr = pmcsc->osti_busaddr + ( idx * nomsize ); 1775285809Sscottl pMem->nocache_mem = (void*)((U64)pmcsc->osti_mem + ( idx * nomsize )); 1776285809Sscottl pCardInfo->freeDynamicMem[idx] = &pCardInfo->dynamicMem[idx]; 1777285809Sscottl } 1778285809Sscottl 1779285809Sscottl pCardInfo->topOfFreeDynamicMem = AGTIAPI_DYNAMIC_MAX; 1780285809Sscottl 1781285809Sscottl return AGTIAPI_SUCCESS; 1782285809Sscottl} 1783285809Sscottl 1784285809Sscottl 1785285809Sscottl/****************************************************************************** 1786285809Sscottlagtiapi_cam_action() 1787285809Sscottl 1788285809SscottlPurpose: 1789285809Sscottl Parses CAM frames and triggers a corresponding action 1790285809SscottlParameters: 1791285809Sscottl struct cam_sim *sim (IN) Pointer to SIM data structure 1792285809Sscottl union ccb * ccb (IN) Pointer to CAM ccb data structure 1793285809SscottlReturn: 1794285809SscottlNote: 1795285809Sscottl******************************************************************************/ 1796285809Sscottlstatic void agtiapi_cam_action( struct cam_sim *sim, union ccb * ccb ) 1797285809Sscottl{ 1798285809Sscottl struct agtiapi_softc *pmcsc; 1799285809Sscottl tiDeviceHandle_t *pDevHandle = NULL; // acts as flag as well 1800285809Sscottl tiDeviceInfo_t devInfo; 1801285809Sscottl int pathID, targetID, lunID; 1802285809Sscottl int lRetVal; 1803285809Sscottl U32 TID; 1804285809Sscottl U32 speed = 150000; 1805285809Sscottl 1806285809Sscottl pmcsc = cam_sim_softc( sim ); 1807285809Sscottl AGTIAPI_IO( "agtiapi_cam_action: start pmcs %p\n", pmcsc ); 1808285809Sscottl 1809285809Sscottl if (pmcsc == agNULL) 1810285809Sscottl { 1811285809Sscottl AGTIAPI_PRINTK( "agtiapi_cam_action: start pmcs is NULL\n" ); 1812285809Sscottl return; 1813285809Sscottl } 1814285809Sscottl mtx_assert( &(pmcsc->pCardInfo->pmIOLock), MA_OWNED ); 1815285809Sscottl 1816285809Sscottl AGTIAPI_IO( "agtiapi_cam_action: cardNO %d func_code 0x%x\n", pmcsc->cardNo, ccb->ccb_h.func_code ); 1817285809Sscottl 1818285809Sscottl pathID = xpt_path_path_id( ccb->ccb_h.path ); 1819285809Sscottl targetID = xpt_path_target_id( ccb->ccb_h.path ); 1820285809Sscottl lunID = xpt_path_lun_id( ccb->ccb_h.path ); 1821285809Sscottl 1822285809Sscottl AGTIAPI_IO( "agtiapi_cam_action: P 0x%x T 0x%x L 0x%x\n", 1823285809Sscottl pathID, targetID, lunID ); 1824285809Sscottl 1825285809Sscottl switch (ccb->ccb_h.func_code) 1826285809Sscottl { 1827285809Sscottl case XPT_PATH_INQ: 1828285809Sscottl { 1829285809Sscottl struct ccb_pathinq *cpi; 1830285809Sscottl 1831285809Sscottl /* See architecure book p180*/ 1832285809Sscottl cpi = &ccb->cpi; 1833285809Sscottl cpi->version_num = 1; 1834285809Sscottl cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16; 1835285809Sscottl cpi->target_sprt = 0; 1836285809Sscottl cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; 1837285809Sscottl cpi->hba_eng_cnt = 0; 1838285809Sscottl cpi->max_target = maxTargets - 1; 1839285809Sscottl cpi->max_lun = AGTIAPI_MAX_LUN; 1840285809Sscottl cpi->maxio = 1024 *1024; /* Max supported I/O size, in bytes. */ 1841285809Sscottl cpi->initiator_id = 255; 1842285809Sscottl strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1843285809Sscottl strncpy(cpi->hba_vid, "PMC", HBA_IDLEN); 1844285809Sscottl strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1845285809Sscottl cpi->unit_number = cam_sim_unit(sim); 1846285809Sscottl cpi->bus_id = cam_sim_bus(sim); 1847285809Sscottl // rate is set when XPT_GET_TRAN_SETTINGS is processed 1848285809Sscottl cpi->base_transfer_speed = 150000; 1849285809Sscottl cpi->transport = XPORT_SAS; 1850285809Sscottl cpi->transport_version = 0; 1851285809Sscottl cpi->protocol = PROTO_SCSI; 1852285809Sscottl cpi->protocol_version = SCSI_REV_SPC3; 1853285809Sscottl cpi->ccb_h.status = CAM_REQ_CMP; 1854285809Sscottl break; 1855285809Sscottl } 1856285809Sscottl case XPT_GET_TRAN_SETTINGS: 1857285809Sscottl { 1858285809Sscottl struct ccb_trans_settings *cts; 1859285809Sscottl struct ccb_trans_settings_sas *sas; 1860285809Sscottl struct ccb_trans_settings_scsi *scsi; 1861285809Sscottl 1862285809Sscottl if ( pmcsc->flags & AGTIAPI_SHUT_DOWN ) 1863285809Sscottl { 1864285809Sscottl return; 1865285809Sscottl } 1866285809Sscottl 1867285809Sscottl cts = &ccb->cts; 1868285809Sscottl sas = &ccb->cts.xport_specific.sas; 1869285809Sscottl scsi = &cts->proto_specific.scsi; 1870285809Sscottl 1871285809Sscottl cts->protocol = PROTO_SCSI; 1872285809Sscottl cts->protocol_version = SCSI_REV_SPC3; 1873285809Sscottl cts->transport = XPORT_SAS; 1874285809Sscottl cts->transport_version = 0; 1875285809Sscottl 1876285809Sscottl sas->valid = CTS_SAS_VALID_SPEED; 1877285809Sscottl 1878285809Sscottl /* this sets the "MB/s transfers" */ 1879285809Sscottl if (pmcsc != NULL && targetID >= 0 && targetID < maxTargets) 1880285809Sscottl { 1881285809Sscottl if (pmcsc->pWWNList != NULL) 1882285809Sscottl { 1883285809Sscottl TID = INDEX(pmcsc, targetID); 1884285809Sscottl if (TID < maxTargets) 1885285809Sscottl { 1886285809Sscottl pDevHandle = pmcsc->pDevList[TID].pDevHandle; 1887285809Sscottl } 1888285809Sscottl } 1889285809Sscottl } 1890285809Sscottl if (pDevHandle) 1891285809Sscottl { 1892285809Sscottl tiINIGetDeviceInfo( &pmcsc->tiRoot, pDevHandle, &devInfo ); 1893285809Sscottl switch (devInfo.info.devType_S_Rate & 0xF) 1894285809Sscottl { 1895285809Sscottl case 0x8: speed = 150000; 1896285809Sscottl break; 1897285809Sscottl case 0x9: speed = 300000; 1898285809Sscottl break; 1899285809Sscottl case 0xA: speed = 600000; 1900285809Sscottl break; 1901285809Sscottl case 0xB: speed = 1200000; 1902285809Sscottl break; 1903285809Sscottl default: speed = 150000; 1904285809Sscottl break; 1905285809Sscottl } 1906285809Sscottl } 1907285809Sscottl sas->bitrate = speed; 1908285809Sscottl scsi->valid = CTS_SCSI_VALID_TQ; 1909285809Sscottl scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 1910285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 1911285809Sscottl break; 1912285809Sscottl } 1913285809Sscottl case XPT_RESET_BUS: 1914285809Sscottl { 1915285809Sscottl lRetVal = agtiapi_eh_HostReset( pmcsc, ccb ); // usually works first time 1916285809Sscottl if ( SUCCESS == lRetVal ) 1917285809Sscottl { 1918285809Sscottl AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset success.\n" ); 1919285809Sscottl } 1920285809Sscottl else 1921285809Sscottl { 1922285809Sscottl AGTIAPI_PRINTK( "agtiapi_cam_action: bus reset failed.\n" ); 1923285809Sscottl } 1924285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 1925285809Sscottl break; 1926285809Sscottl } 1927285809Sscottl case XPT_RESET_DEV: 1928285809Sscottl { 1929285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 1930285809Sscottl break; 1931285809Sscottl } 1932285809Sscottl case XPT_ABORT: 1933285809Sscottl { 1934285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 1935285809Sscottl break; 1936285809Sscottl } 1937285809Sscottl#if __FreeBSD_version >= 900026 1938285809Sscottl case XPT_SMP_IO: 1939285809Sscottl { 1940285809Sscottl agtiapi_QueueSMP( pmcsc, ccb ); 1941285809Sscottl return; 1942285809Sscottl } 1943285809Sscottl#endif /* __FreeBSD_version >= 900026 */ 1944285809Sscottl case XPT_SCSI_IO: 1945285809Sscottl { 1946285809Sscottl if(pmcsc->dev_scan == agFALSE) 1947285809Sscottl { 1948285809Sscottl ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1949285809Sscottl break; 1950285809Sscottl } 1951285809Sscottl if (pmcsc->flags & AGTIAPI_SHUT_DOWN) 1952285809Sscottl { 1953285809Sscottl AGTIAPI_PRINTK( "agtiapi_cam_action: shutdown, XPT_SCSI_IO 0x%x\n", 1954285809Sscottl XPT_SCSI_IO ); 1955285809Sscottl ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1956285809Sscottl break; 1957285809Sscottl } 1958285809Sscottl else 1959285809Sscottl { 1960285809Sscottl AGTIAPI_IO( "agtiapi_cam_action: Zero XPT_SCSI_IO 0x%x, doing IOs\n", 1961285809Sscottl XPT_SCSI_IO ); 1962285809Sscottl agtiapi_QueueCmnd_( pmcsc, ccb ); 1963285809Sscottl return; 1964285809Sscottl } 1965285809Sscottl } 1966285809Sscottl 1967285809Sscottl case XPT_CALC_GEOMETRY: 1968285809Sscottl { 1969285809Sscottl cam_calc_geometry(&ccb->ccg, 1); 1970285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 1971285809Sscottl break; 1972285809Sscottl } 1973285809Sscottl default: 1974285809Sscottl { 1975285809Sscottl /* 1976285809Sscottl XPT_SET_TRAN_SETTINGS 1977285809Sscottl */ 1978285809Sscottl AGTIAPI_IO( "agtiapi_cam_action: default function code 0x%x\n", 1979285809Sscottl ccb->ccb_h.func_code ); 1980285809Sscottl ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1981285809Sscottl break; 1982285809Sscottl } 1983285809Sscottl } /* switch */ 1984285809Sscottl xpt_done(ccb); 1985285809Sscottl} 1986285809Sscottl 1987285809Sscottl 1988285809Sscottl/****************************************************************************** 1989285809Sscottlagtiapi_GetCCB() 1990285809Sscottl 1991285809SscottlPurpose: 1992285809Sscottl Get a ccb from free list or allocate a new one 1993285809SscottlParameters: 1994285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA structure 1995285809SscottlReturn: 1996285809Sscottl Pointer to a ccb structure, or NULL if not available 1997285809SscottlNote: 1998285809Sscottl******************************************************************************/ 1999285809SscottlSTATIC pccb_t agtiapi_GetCCB( struct agtiapi_softc *pmcsc ) 2000285809Sscottl{ 2001285809Sscottl pccb_t pccb; 2002285809Sscottl 2003285809Sscottl AGTIAPI_IO( "agtiapi_GetCCB: start\n" ); 2004285809Sscottl 2005285809Sscottl AG_LOCAL_LOCK( &pmcsc->ccbLock ); 2006285809Sscottl 2007285809Sscottl /* get the ccb from the head of the free list */ 2008285809Sscottl if ((pccb = (pccb_t)pmcsc->ccbFreeList) != NULL) 2009285809Sscottl { 2010285809Sscottl pmcsc->ccbFreeList = (caddr_t *)pccb->pccbNext; 2011285809Sscottl pccb->pccbNext = NULL; 2012285809Sscottl pccb->flags = ACTIVE; 2013285809Sscottl pccb->startTime = 0; 2014285809Sscottl pmcsc->activeCCB++; 2015285809Sscottl AGTIAPI_IO( "agtiapi_GetCCB: re-allocated ccb %p\n", pccb ); 2016285809Sscottl } 2017285809Sscottl else 2018285809Sscottl { 2019285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetCCB: kmalloc ERROR - no ccb allocated\n" ); 2020285809Sscottl } 2021285809Sscottl 2022285809Sscottl AG_LOCAL_UNLOCK( &pmcsc->ccbLock ); 2023285809Sscottl return pccb; 2024285809Sscottl} 2025285809Sscottl 2026285809Sscottl/****************************************************************************** 2027285809Sscottlagtiapi_QueueCmnd_() 2028285809Sscottl 2029285809SscottlPurpose: 2030285809Sscottl Calls for sending CCB and excuting on HBA. 2031285809SscottlParameters: 2032285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 2033285809Sscottl union ccb * ccb (IN) Pointer to CAM ccb data structure 2034285809SscottlReturn: 2035285809Sscottl 0 - Command is pending to execute 2036285809Sscottl 1 - Command returned without further process 2037285809SscottlNote: 2038285809Sscottl******************************************************************************/ 2039285809Sscottlint agtiapi_QueueCmnd_(struct agtiapi_softc *pmcsc, union ccb * ccb) 2040285809Sscottl{ 2041285809Sscottl struct ccb_scsiio *csio = &ccb->csio; 2042285809Sscottl pccb_t pccb = agNULL; // call dequeue 2043285809Sscottl int status = tiSuccess; 2044285809Sscottl U32 Channel = CMND_TO_CHANNEL(ccb); 2045285809Sscottl U32 TID = CMND_TO_TARGET(ccb); 2046285809Sscottl U32 LUN = CMND_TO_LUN(ccb); 2047285809Sscottl 2048285809Sscottl AGTIAPI_IO( "agtiapi_QueueCmnd_: start\n" ); 2049285809Sscottl 2050285809Sscottl /* no support for CBD > 16 */ 2051285809Sscottl if (csio->cdb_len > 16) 2052285809Sscottl { 2053285809Sscottl AGTIAPI_PRINTK( "agtiapi_QueueCmnd_: unsupported CDB length %d\n", 2054285809Sscottl csio->cdb_len ); 2055285809Sscottl ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 2056285809Sscottl ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2057285809Sscottl ccb->ccb_h.status |= CAM_REQ_INVALID;//CAM_REQ_CMP; 2058285809Sscottl xpt_done(ccb); 2059285809Sscottl return tiError; 2060285809Sscottl } 2061285809Sscottl if (TID < 0 || TID >= maxTargets) 2062285809Sscottl { 2063285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueCmnd_: INVALID TID ERROR\n"); 2064285809Sscottl ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 2065285809Sscottl ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2066285809Sscottl ccb->ccb_h.status |= CAM_DEV_NOT_THERE;//CAM_REQ_CMP; 2067285809Sscottl xpt_done(ccb); 2068285809Sscottl return tiError; 2069285809Sscottl } 2070285809Sscottl /* get a ccb */ 2071285809Sscottl if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL) 2072285809Sscottl { 2073285809Sscottl ag_device_t *targ; 2074285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueCmnd_: GetCCB ERROR\n"); 2075285809Sscottl if (pmcsc != NULL) 2076285809Sscottl { 2077285809Sscottl TID = INDEX(pmcsc, TID); 2078285809Sscottl targ = &pmcsc->pDevList[TID]; 2079285809Sscottl } 2080285809Sscottl if (targ != NULL) 2081285809Sscottl { 2082285809Sscottl agtiapi_adjust_queue_depth(ccb->ccb_h.path,targ->qdepth); 2083285809Sscottl } 2084285809Sscottl ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 2085285809Sscottl ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2086285809Sscottl ccb->ccb_h.status |= CAM_REQUEUE_REQ; 2087285809Sscottl xpt_done(ccb); 2088285809Sscottl return tiBusy; 2089285809Sscottl } 2090285809Sscottl pccb->pmcsc = pmcsc; 2091285809Sscottl /* initialize Command Control Block (CCB) */ 2092285809Sscottl pccb->targetId = TID; 2093285809Sscottl pccb->lun = LUN; 2094285809Sscottl pccb->channel = Channel; 2095285809Sscottl pccb->ccb = ccb; /* for struct scsi_cmnd */ 2096285809Sscottl pccb->senseLen = csio->sense_len; 2097285809Sscottl pccb->startTime = ticks; 2098285809Sscottl pccb->pSenseData = (caddr_t) &csio->sense_data; 2099285809Sscottl pccb->tiSuperScsiRequest.flags = 0; 2100285809Sscottl 2101285809Sscottl /* each channel is reserved for different addr modes */ 2102285809Sscottl pccb->addrMode = agtiapi_AddrModes[Channel]; 2103285809Sscottl 2104285809Sscottl status = agtiapi_PrepareSGList(pmcsc, pccb); 2105285809Sscottl if (status != tiSuccess) 2106285809Sscottl { 2107285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueCmnd_: agtiapi_PrepareSGList failure\n"); 2108285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 2109285809Sscottl if (status == tiReject) 2110285809Sscottl { 2111285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 2112285809Sscottl } 2113285809Sscottl else 2114285809Sscottl { 2115285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 2116285809Sscottl } 2117285809Sscottl xpt_done( ccb ); 2118285809Sscottl return tiError; 2119285809Sscottl } 2120285809Sscottl return status; 2121285809Sscottl} 2122285809Sscottl 2123285809Sscottl/****************************************************************************** 2124285809Sscottlagtiapi_DumpCDB() 2125285809Sscottl 2126285809SscottlPurpose: 2127285809Sscottl Prints out CDB 2128285809SscottlParameters: 2129285809Sscottl const char *ptitle (IN) A string to be printed 2130285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 2131285809SscottlReturn: 2132285809SscottlNote: 2133285809Sscottl******************************************************************************/ 2134285809SscottlSTATIC void agtiapi_DumpCDB(const char *ptitle, ccb_t *pccb) 2135285809Sscottl{ 2136285809Sscottl union ccb *ccb; 2137285809Sscottl struct ccb_scsiio *csio; 2138285809Sscottl bit8 cdb[64]; 2139285809Sscottl int len; 2140285809Sscottl 2141285809Sscottl if (pccb == NULL) 2142285809Sscottl { 2143285809Sscottl printf( "agtiapi_DumpCDB: no pccb here \n" ); 2144285809Sscottl panic("agtiapi_DumpCDB: pccb is NULL. called from %s\n", ptitle); 2145285809Sscottl return; 2146285809Sscottl } 2147285809Sscottl ccb = pccb->ccb; 2148285809Sscottl if (ccb == NULL) 2149285809Sscottl { 2150285809Sscottl printf( "agtiapi_DumpCDB: no ccb here \n" ); 2151285809Sscottl panic( "agtiapi_DumpCDB: pccb %p ccb %p flags %d ccb NULL! " 2152285809Sscottl "called from %s\n", 2153285809Sscottl pccb, pccb->ccb, pccb->flags, ptitle ); 2154285809Sscottl return; 2155285809Sscottl } 2156285809Sscottl csio = &ccb->csio; 2157285809Sscottl if (csio == NULL) 2158285809Sscottl { 2159285809Sscottl printf( "agtiapi_DumpCDB: no csio here \n" ); 2160285809Sscottl panic( "agtiapi_DumpCDB: pccb%p ccb%p flags%d csio NULL! called from %s\n", 2161285809Sscottl pccb, pccb->ccb, pccb->flags, ptitle ); 2162285809Sscottl return; 2163285809Sscottl } 2164285809Sscottl len = MIN(64, csio->cdb_len); 2165285809Sscottl if (csio->ccb_h.flags & CAM_CDB_POINTER) 2166285809Sscottl { 2167285809Sscottl bcopy(csio->cdb_io.cdb_ptr, &cdb[0], len); 2168285809Sscottl } 2169285809Sscottl else 2170285809Sscottl { 2171285809Sscottl bcopy(csio->cdb_io.cdb_bytes, &cdb[0], len); 2172285809Sscottl } 2173285809Sscottl 2174285809Sscottl AGTIAPI_IO( "agtiapi_DumpCDB: pccb%p CDB0x%x csio->cdb_len %d" 2175285809Sscottl " len %d from %s\n", 2176285809Sscottl pccb, cdb[0], 2177285809Sscottl csio->cdb_len, 2178285809Sscottl len, 2179285809Sscottl ptitle ); 2180285809Sscottl return; 2181285809Sscottl} 2182285809Sscottl 2183285809Sscottl/****************************************************************************** 2184285809Sscottlagtiapi_DoSoftReset() 2185285809Sscottl 2186285809SscottlPurpose: 2187285809Sscottl Do card reset 2188285809SscottlParameters: 2189285809Sscottl *data (IN) point to pmcsc (struct agtiapi_softc *) 2190285809SscottlReturn: 2191285809SscottlNote: 2192285809Sscottl******************************************************************************/ 2193285809Sscottlint agtiapi_DoSoftReset (struct agtiapi_softc *pmcsc) 2194285809Sscottl{ 2195285809Sscottl int ret; 2196285809Sscottl unsigned long flags; 2197285809Sscottl 2198285809Sscottl pmcsc->flags |= AGTIAPI_SOFT_RESET; 2199285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags ); 2200285809Sscottl ret = agtiapi_ResetCard( pmcsc, &flags ); 2201285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 2202285809Sscottl 2203285809Sscottl if( ret != AGTIAPI_SUCCESS ) 2204285809Sscottl return tiError; 2205285809Sscottl 2206285809Sscottl return SUCCESS; 2207285809Sscottl} 2208285809Sscottl 2209285809Sscottl/****************************************************************************** 2210285809Sscottlagtiapi_CheckIOTimeout() 2211285809Sscottl 2212285809SscottlPurpose: 2213285809Sscottl Timeout function for SCSI IO or TM 2214285809SscottlParameters: 2215285809Sscottl *data (IN) point to pCard (ag_card_t *) 2216285809SscottlReturn: 2217285809SscottlNote: 2218285809Sscottl******************************************************************************/ 2219285809SscottlSTATIC void agtiapi_CheckIOTimeout(void *data) 2220285809Sscottl{ 2221285809Sscottl U32 status = AGTIAPI_SUCCESS; 2222285809Sscottl ccb_t *pccb; 2223285809Sscottl struct agtiapi_softc *pmcsc; 2224285809Sscottl pccb_t pccb_curr; 2225285809Sscottl pccb_t pccb_next; 2226285809Sscottl pmcsc = (struct agtiapi_softc *)data; 2227285809Sscottl 2228285809Sscottl //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Enter\n"); 2229285809Sscottl 2230285809Sscottl //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Active CCB %d\n", pmcsc->activeCCB); 2231285809Sscottl 2232285809Sscottl pccb = (pccb_t)pmcsc->ccbChainList; 2233285809Sscottl 2234285809Sscottl /* if link is down, do nothing */ 2235285809Sscottl if ((pccb == NULL) || (pmcsc->activeCCB == 0)) 2236285809Sscottl { 2237285809Sscottl //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: goto restart_timer\n"); 2238285809Sscottl goto restart_timer; 2239285809Sscottl } 2240285809Sscottl 2241285809Sscottl AG_SPIN_LOCK_IRQ(agtiapi_host_lock, flags); 2242285809Sscottl if (pmcsc->flags & AGTIAPI_SHUT_DOWN) 2243285809Sscottl goto ext; 2244285809Sscottl 2245285809Sscottl pccb_curr = pccb; 2246285809Sscottl 2247285809Sscottl /* Walk thorugh the IO Chain linked list to find the pending io */ 2248285809Sscottl /* Set the TM flag based on the pccb type, i.e SCSI IO or TM cmd */ 2249285809Sscottl while (pccb_curr != NULL) 2250285809Sscottl { 2251285809Sscottl /* start from 1st ccb in the chain */ 2252285809Sscottl pccb_next = pccb_curr->pccbChainNext; 2253285809Sscottl if( (pccb_curr->flags == 0) || (pccb_curr->tiIORequest.tdData == NULL) || 2254285809Sscottl (pccb_curr->startTime == 0) /* && (pccb->startTime == 0) */) 2255285809Sscottl { 2256285809Sscottl //AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: move to next element\n"); 2257285809Sscottl } 2258285809Sscottl else if ( ( (ticks-pccb_curr->startTime) >= ag_timeout_secs ) && 2259285809Sscottl !(pccb_curr->flags & TIMEDOUT) ) 2260285809Sscottl { 2261285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: pccb %p timed out, call TM " 2262285809Sscottl "function -- flags=%x startTime=%ld tdData = %p\n", 2263285809Sscottl pccb_curr, pccb_curr->flags, pccb->startTime, 2264285809Sscottl pccb_curr->tiIORequest.tdData ); 2265285809Sscottl pccb_curr->flags |= TIMEDOUT; 2266285809Sscottl status = agtiapi_StartTM(pmcsc, pccb_curr); 2267285809Sscottl if (status == AGTIAPI_SUCCESS) 2268285809Sscottl { 2269285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout: TM Request sent with " 2270285809Sscottl "success\n" ); 2271285809Sscottl goto restart_timer; 2272285809Sscottl } 2273285809Sscottl else 2274285809Sscottl { 2275285809Sscottl#ifdef AGTIAPI_LOCAL_RESET 2276285809Sscottl /* abort request did not go through */ 2277285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckIOTimeout: Abort request failed\n"); 2278285809Sscottl /* TODO: call Soft reset here */ 2279285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckIOTimeout:in agtiapi_CheckIOTimeout() " 2280285809Sscottl "abort request did not go thru ==> soft reset#7, then " 2281285809Sscottl "restart timer\n" ); 2282285809Sscottl agtiapi_DoSoftReset (pmcsc); 2283285809Sscottl goto restart_timer; 2284285809Sscottl#endif 2285285809Sscottl } 2286285809Sscottl } 2287285809Sscottl pccb_curr = pccb_next; 2288285809Sscottl } 2289285809Sscottlrestart_timer: 2290285809Sscottl callout_reset(&pmcsc->IO_timer, 1*hz, agtiapi_CheckIOTimeout, pmcsc); 2291285809Sscottl 2292285809Sscottlext: 2293285809Sscottl AG_SPIN_UNLOCK_IRQ(agtiapi_host_lock, flags); 2294285809Sscottl return; 2295285809Sscottl} 2296285809Sscottl 2297285809Sscottl/****************************************************************************** 2298285809Sscottlagtiapi_StartTM() 2299285809Sscottl 2300285809SscottlPurpose: 2301285809Sscottl DDI calls for aborting outstanding IO command 2302285809SscottlParameters: 2303285809Sscottl struct scsi_cmnd *pccb (IN) Pointer to the command to be aborted 2304285809Sscottl unsigned long flags (IN/out) spinlock flags used in locking from 2305285809Sscottl calling layers 2306285809SscottlReturn: 2307285809Sscottl AGTIAPI_SUCCESS - success 2308285809Sscottl AGTIAPI_FAIL - fail 2309285809Sscottl******************************************************************************/ 2310285809Sscottlint 2311285809Sscottlagtiapi_StartTM(struct agtiapi_softc *pCard, ccb_t *pccb) 2312285809Sscottl{ 2313285809Sscottl ccb_t *pTMccb = NULL; 2314285809Sscottl U32 status = AGTIAPI_SUCCESS; 2315285809Sscottl ag_device_t *pDevice = NULL; 2316285809Sscottl U32 TMstatus = tiSuccess; 2317285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: pccb %p, pccb->flags %x\n", 2318285809Sscottl pccb, pccb->flags ); 2319285809Sscottl if (pccb == NULL) 2320285809Sscottl { 2321285809Sscottl AGTIAPI_PRINTK("agtiapi_StartTM: %p not found\n",pccb); 2322285809Sscottl status = AGTIAPI_SUCCESS; 2323285809Sscottl goto ext; 2324285809Sscottl } 2325285809Sscottl if (!pccb->tiIORequest.tdData) 2326285809Sscottl { 2327285809Sscottl /* should not be the case */ 2328285809Sscottl AGTIAPI_PRINTK("agtiapi_StartTM: ccb %p flag 0x%x tid %d no tdData " 2329285809Sscottl "ERROR\n", pccb, pccb->flags, pccb->targetId); 2330285809Sscottl status = AGTIAPI_FAIL; 2331285809Sscottl } 2332285809Sscottl else 2333285809Sscottl { 2334285809Sscottl /* If timedout CCB is TM_ABORT_TASK command, issue LocalAbort first to 2335285809Sscottl clear pending TM_ABORT_TASK */ 2336285809Sscottl /* Else Device State will not be put back to Operational, (refer FW) */ 2337285809Sscottl if (pccb->flags & TASK_MANAGEMENT) 2338285809Sscottl { 2339285809Sscottl if (tiINIIOAbort(&pCard->tiRoot, &pccb->tiIORequest) != tiSuccess) 2340285809Sscottl { 2341285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort Request for Abort_TASK " 2342285809Sscottl "TM failed\n" ); 2343285809Sscottl /* TODO: call Soft reset here */ 2344285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: in agtiapi_StartTM() abort " 2345285809Sscottl "tiINIIOAbort() failed ==> soft reset#8\n" ); 2346285809Sscottl agtiapi_DoSoftReset( pCard ); 2347285809Sscottl } 2348285809Sscottl else 2349285809Sscottl { 2350285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: LocalAbort for Abort_TASK TM " 2351285809Sscottl "Request sent\n" ); 2352285809Sscottl status = AGTIAPI_SUCCESS; 2353285809Sscottl } 2354285809Sscottl } 2355285809Sscottl else 2356285809Sscottl { 2357285809Sscottl /* get a ccb */ 2358285809Sscottl if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL) 2359285809Sscottl { 2360285809Sscottl AGTIAPI_PRINTK("agtiapi_StartTM: TM resource unavailable!\n"); 2361285809Sscottl status = AGTIAPI_FAIL; 2362285809Sscottl goto ext; 2363285809Sscottl } 2364285809Sscottl pTMccb->pmcsc = pCard; 2365285809Sscottl pTMccb->targetId = pccb->targetId; 2366285809Sscottl pTMccb->devHandle = pccb->devHandle; 2367285809Sscottl if (pTMccb->targetId >= pCard->devDiscover) 2368285809Sscottl { 2369285809Sscottl AGTIAPI_PRINTK("agtiapi_StartTM: Incorrect dev Id in TM!\n"); 2370285809Sscottl status = AGTIAPI_FAIL; 2371285809Sscottl goto ext; 2372285809Sscottl } 2373285809Sscottl if (pTMccb->targetId < 0 || pTMccb->targetId >= maxTargets) 2374285809Sscottl { 2375285809Sscottl return AGTIAPI_FAIL; 2376285809Sscottl } 2377285809Sscottl if (INDEX(pCard, pTMccb->targetId) >= maxTargets) 2378285809Sscottl { 2379285809Sscottl return AGTIAPI_FAIL; 2380285809Sscottl } 2381285809Sscottl pDevice = &pCard->pDevList[INDEX(pCard, pTMccb->targetId)]; 2382285809Sscottl if ((pDevice == NULL) || !(pDevice->flags & ACTIVE)) 2383285809Sscottl { 2384285809Sscottl return AGTIAPI_FAIL; 2385285809Sscottl } 2386285809Sscottl 2387285809Sscottl /* save pending io to issue local abort at Task mgmt CB */ 2388285809Sscottl pTMccb->pccbIO = pccb; 2389285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: pTMccb %p flag %x tid %d via TM " 2390285809Sscottl "request !\n", 2391285809Sscottl pTMccb, pTMccb->flags, pTMccb->targetId ); 2392285809Sscottl pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE); 2393285809Sscottl pTMccb->flags |= TASK_MANAGEMENT; 2394285809Sscottl TMstatus = tiINITaskManagement(&pCard->tiRoot, 2395285809Sscottl pccb->devHandle, 2396285809Sscottl AG_ABORT_TASK, 2397285809Sscottl &pccb->tiSuperScsiRequest.scsiCmnd.lun, 2398285809Sscottl &pccb->tiIORequest, 2399285809Sscottl &pTMccb->tiIORequest); 2400285809Sscottl if (TMstatus == tiSuccess) 2401285809Sscottl { 2402285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request success ccb " 2403285809Sscottl "%p, pTMccb %p\n", 2404285809Sscottl pccb, pTMccb ); 2405285809Sscottl pTMccb->startTime = ticks; 2406285809Sscottl status = AGTIAPI_SUCCESS; 2407285809Sscottl } 2408285809Sscottl else if (TMstatus == tiIONoDevice) 2409285809Sscottl { 2410285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request tiIONoDevice ccb " 2411285809Sscottl "%p, pTMccb %p\n", 2412285809Sscottl pccb, pTMccb ); 2413285809Sscottl status = AGTIAPI_SUCCESS; 2414285809Sscottl } 2415285809Sscottl else 2416285809Sscottl { 2417285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartTM: TM_ABORT_TASK request failed ccb %p, " 2418285809Sscottl "pTMccb %p\n", 2419285809Sscottl pccb, pTMccb ); 2420285809Sscottl status = AGTIAPI_FAIL; 2421285809Sscottl agtiapi_FreeTMCCB(pCard, pTMccb); 2422285809Sscottl /* TODO */ 2423285809Sscottl /* call TM_TARGET_RESET */ 2424285809Sscottl } 2425285809Sscottl } 2426285809Sscottl } 2427285809Sscottl ext: 2428285809Sscottl AGTIAPI_PRINTK("agtiapi_StartTM: return %d flgs %x\n", status, 2429285809Sscottl (pccb) ? pccb->flags : -1); 2430285809Sscottl return status; 2431285809Sscottl} /* agtiapi_StartTM */ 2432285809Sscottl 2433285809Sscottl#if __FreeBSD_version > 901000 2434285809Sscottl/****************************************************************************** 2435285809Sscottlagtiapi_PrepareSGList() 2436285809Sscottl 2437285809SscottlPurpose: 2438285809Sscottl This function prepares scatter-gather list for the given ccb 2439285809SscottlParameters: 2440285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 2441285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 2442285809SscottlReturn: 2443285809Sscottl 0 - success 2444285809Sscottl 1 - failure 2445285809Sscottl 2446285809SscottlNote: 2447285809Sscottl******************************************************************************/ 2448285809Sscottlstatic int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb) 2449285809Sscottl{ 2450285809Sscottl union ccb *ccb = pccb->ccb; 2451285809Sscottl struct ccb_scsiio *csio = &ccb->csio; 2452285809Sscottl struct ccb_hdr *ccbh = &ccb->ccb_h; 2453285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" ); 2454285809Sscottl 2455285809Sscottl// agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb); 2456285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len ); 2457285809Sscottl 2458285809Sscottl if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) 2459285809Sscottl { 2460285809Sscottl switch((ccbh->flags & CAM_DATA_MASK)) 2461285809Sscottl { 2462285809Sscottl int error; 2463285809Sscottl struct bus_dma_segment seg; 2464285809Sscottl case CAM_DATA_VADDR: 2465285809Sscottl /* Virtual address that needs to translated into one or more physical address ranges. */ 2466285809Sscottl // int error; 2467285809Sscottl // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock)); 2468285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" ); 2469285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 2470285809Sscottl pccb->CCB_dmamap, 2471285809Sscottl csio->data_ptr, 2472285809Sscottl csio->dxfer_len, 2473285809Sscottl agtiapi_PrepareSGListCB, 2474285809Sscottl pccb, 2475285809Sscottl BUS_DMA_NOWAIT/* 0 */ ); 2476285809Sscottl // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) ); 2477285809Sscottl 2478285809Sscottl if (error == EINPROGRESS) 2479285809Sscottl { 2480285809Sscottl /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */ 2481285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n"); 2482285809Sscottl xpt_freeze_simq(pmcsc->sim, 1); 2483285809Sscottl pmcsc->SimQFrozen = agTRUE; 2484285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 2485285809Sscottl } 2486285809Sscottl break; 2487285809Sscottl case CAM_DATA_PADDR: 2488285809Sscottl /* We have been given a pointer to single physical buffer. */ 2489285809Sscottl /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */ 2490285809Sscottl //struct bus_dma_segment seg; 2491285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n"); 2492285809Sscottl seg.ds_addr = 2493285809Sscottl (bus_addr_t)(vm_offset_t)csio->data_ptr; 2494285809Sscottl seg.ds_len = csio->dxfer_len; 2495285809Sscottl // * 0xFF to be defined 2496285809Sscottl agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD); 2497285809Sscottl break; 2498285809Sscottl default: 2499285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n"); 2500285809Sscottl return tiReject; 2501285809Sscottl } 2502285809Sscottl } 2503285809Sscottl else 2504285809Sscottl { 2505285809Sscottl agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA); 2506285809Sscottl } 2507285809Sscottl return tiSuccess; 2508285809Sscottl} 2509285809Sscottl#else 2510285809Sscottl/****************************************************************************** 2511285809Sscottlagtiapi_PrepareSGList() 2512285809Sscottl 2513285809SscottlPurpose: 2514285809Sscottl This function prepares scatter-gather list for the given ccb 2515285809SscottlParameters: 2516285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 2517285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 2518285809SscottlReturn: 2519285809Sscottl 0 - success 2520285809Sscottl 1 - failure 2521285809Sscottl 2522285809SscottlNote: 2523285809Sscottl******************************************************************************/ 2524285809Sscottlstatic int agtiapi_PrepareSGList(struct agtiapi_softc *pmcsc, ccb_t *pccb) 2525285809Sscottl{ 2526285809Sscottl union ccb *ccb = pccb->ccb; 2527285809Sscottl struct ccb_scsiio *csio = &ccb->csio; 2528285809Sscottl struct ccb_hdr *ccbh = &ccb->ccb_h; 2529285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: start\n" ); 2530285809Sscottl// agtiapi_DumpCDB("agtiapi_PrepareSGList", pccb); 2531285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: dxfer_len %d\n", csio->dxfer_len ); 2532285809Sscottl 2533285809Sscottl if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) 2534285809Sscottl { 2535285809Sscottl if ((ccbh->flags & CAM_SCATTER_VALID) == 0) 2536285809Sscottl { 2537285809Sscottl /* We've been given a pointer to a single buffer. */ 2538285809Sscottl if ((ccbh->flags & CAM_DATA_PHYS) == 0) 2539285809Sscottl { 2540285809Sscottl /* Virtual address that needs to translated into one or more physical address ranges. */ 2541285809Sscottl int error; 2542285809Sscottl // AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock)); 2543285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGList: virtual address\n" ); 2544285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 2545285809Sscottl pccb->CCB_dmamap, 2546285809Sscottl csio->data_ptr, 2547285809Sscottl csio->dxfer_len, 2548285809Sscottl agtiapi_PrepareSGListCB, 2549285809Sscottl pccb, 2550285809Sscottl BUS_DMA_NOWAIT/* 0 */ ); 2551285809Sscottl // AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) ); 2552285809Sscottl 2553285809Sscottl if (error == EINPROGRESS) 2554285809Sscottl { 2555285809Sscottl /* So as to maintain ordering, freeze the controller queue until our mapping is returned. */ 2556285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: EINPROGRESS\n"); 2557285809Sscottl xpt_freeze_simq(pmcsc->sim, 1); 2558285809Sscottl pmcsc->SimQFrozen = agTRUE; 2559285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 2560285809Sscottl } 2561285809Sscottl } 2562285809Sscottl else 2563285809Sscottl { 2564285809Sscottl /* We have been given a pointer to single physical buffer. */ 2565285809Sscottl /* pccb->tiSuperScsiRequest.sglVirtualAddr = seg.ds_addr; */ 2566285809Sscottl struct bus_dma_segment seg; 2567285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: physical address\n"); 2568285809Sscottl seg.ds_addr = 2569285809Sscottl (bus_addr_t)(vm_offset_t)csio->data_ptr; 2570285809Sscottl seg.ds_len = csio->dxfer_len; 2571285809Sscottl // * 0xFF to be defined 2572285809Sscottl agtiapi_PrepareSGListCB(pccb, &seg, 1, 0xAABBCCDD); 2573285809Sscottl } 2574285809Sscottl } 2575285809Sscottl else 2576285809Sscottl { 2577285809Sscottl 2578285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: unexpected case\n"); 2579285809Sscottl return tiReject; 2580285809Sscottl } 2581285809Sscottl } 2582285809Sscottl else 2583285809Sscottl { 2584285809Sscottl agtiapi_PrepareSGListCB(pccb, NULL, 0, 0xAAAAAAAA); 2585285809Sscottl } 2586285809Sscottl return tiSuccess; 2587285809Sscottl} 2588285809Sscottl 2589285809Sscottl#endif 2590285809Sscottl/****************************************************************************** 2591285809Sscottlagtiapi_PrepareSGListCB() 2592285809Sscottl 2593285809SscottlPurpose: 2594285809Sscottl Callback function for bus_dmamap_load() 2595285809Sscottl This fuctions sends IO to LL layer. 2596285809SscottlParameters: 2597285809Sscottl void *arg (IN) Pointer to the HBA data structure 2598285809Sscottl bus_dma_segment_t *segs (IN) Pointer to dma segment 2599285809Sscottl int nsegs (IN) number of dma segment 2600285809Sscottl int error (IN) error 2601285809SscottlReturn: 2602285809SscottlNote: 2603285809Sscottl******************************************************************************/ 2604285809Sscottlstatic void agtiapi_PrepareSGListCB( void *arg, 2605285809Sscottl bus_dma_segment_t *segs, 2606285809Sscottl int nsegs, 2607285809Sscottl int error ) 2608285809Sscottl{ 2609285809Sscottl pccb_t pccb = arg; 2610285809Sscottl union ccb *ccb = pccb->ccb; 2611285809Sscottl struct ccb_scsiio *csio = &ccb->csio; 2612285809Sscottl 2613285809Sscottl struct agtiapi_softc *pmcsc; 2614285809Sscottl tiIniScsiCmnd_t *pScsiCmnd; 2615285809Sscottl bit32 i; 2616285809Sscottl bus_dmasync_op_t op; 2617285809Sscottl U32_64 phys_addr; 2618285809Sscottl U08 *CDB; 2619285809Sscottl int io_is_encryptable = 0; 2620285809Sscottl unsigned long long start_lba = 0; 2621285809Sscottl ag_device_t *pDev; 2622285809Sscottl U32 TID = CMND_TO_TARGET(ccb); 2623285809Sscottl 2624285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGListCB: start, nsegs %d error 0x%x\n", 2625285809Sscottl nsegs, error ); 2626285809Sscottl pmcsc = pccb->pmcsc; 2627285809Sscottl 2628285809Sscottl if (error != tiSuccess) 2629285809Sscottl { 2630285809Sscottl if (error == 0xAABBCCDD || error == 0xAAAAAAAA) 2631285809Sscottl { 2632285809Sscottl // do nothing 2633285809Sscottl } 2634285809Sscottl else 2635285809Sscottl { 2636285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: error status 0x%x\n", error); 2637285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 2638285809Sscottl bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap); 2639285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 2640285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 2641285809Sscottl xpt_done(ccb); 2642285809Sscottl return; 2643285809Sscottl } 2644285809Sscottl } 2645285809Sscottl 2646285809Sscottl if (nsegs > AGTIAPI_MAX_DMA_SEGS) 2647285809Sscottl { 2648285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: over the limit. nsegs %d" 2649285809Sscottl " AGTIAPI_MAX_DMA_SEGS %d\n", 2650285809Sscottl nsegs, AGTIAPI_MAX_DMA_SEGS ); 2651285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 2652285809Sscottl bus_dmamap_destroy(pmcsc->buffer_dmat, pccb->CCB_dmamap); 2653285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 2654285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 2655285809Sscottl xpt_done(ccb); 2656285809Sscottl return; 2657285809Sscottl } 2658285809Sscottl 2659285809Sscottl 2660285809Sscottl /* fill in IO information */ 2661285809Sscottl pccb->dataLen = csio->dxfer_len; 2662285809Sscottl 2663285809Sscottl /* start fill in sgl structure */ 2664285809Sscottl if (nsegs == 1 && error == 0xAABBCCDD) 2665285809Sscottl { 2666285809Sscottl /* to be tested */ 2667285809Sscottl /* A single physical buffer */ 2668285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: nsegs is 1\n"); 2669285809Sscottl CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr); 2670285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen); 2671285809Sscottl pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl); 2672285809Sscottl pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)segs->ds_addr; 2673285809Sscottl pccb->numSgElements = 1; 2674285809Sscottl } 2675285809Sscottl else if (nsegs == 0 && error == 0xAAAAAAAA) 2676285809Sscottl { 2677285809Sscottl /* no data transfer */ 2678285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGListCB: no data transfer\n" ); 2679285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = 0; 2680285809Sscottl pccb->dataLen = 0; 2681285809Sscottl pccb->numSgElements = 0; 2682285809Sscottl } 2683285809Sscottl else 2684285809Sscottl { 2685285809Sscottl /* virtual/logical buffer */ 2686285809Sscottl if (nsegs == 1) 2687285809Sscottl { 2688285809Sscottl pccb->dataLen = segs[0].ds_len; 2689285809Sscottl 2690285809Sscottl CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, segs[0].ds_addr); 2691285809Sscottl pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl); 2692285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = htole32(segs[0].ds_len); 2693285809Sscottl pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr; 2694285809Sscottl pccb->numSgElements = nsegs; 2695285809Sscottl 2696285809Sscottl } 2697285809Sscottl else 2698285809Sscottl { 2699285809Sscottl pccb->dataLen = 0; 2700285809Sscottl /* loop */ 2701285809Sscottl for (i = 0; i < nsegs; i++) 2702285809Sscottl { 2703285809Sscottl pccb->sgList[i].len = htole32(segs[i].ds_len); 2704285809Sscottl CPU_TO_LE32(pccb->sgList[i], segs[i].ds_addr); 2705285809Sscottl pccb->sgList[i].type = htole32(tiSgl); 2706285809Sscottl pccb->dataLen += segs[i].ds_len; 2707285809Sscottl 2708285809Sscottl } /* for */ 2709285809Sscottl pccb->numSgElements = nsegs; 2710285809Sscottl /* set up sgl buffer address */ 2711285809Sscottl CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, pccb->tisgl_busaddr); 2712285809Sscottl pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSglList); 2713285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->dataLen); 2714285809Sscottl pccb->tiSuperScsiRequest.sglVirtualAddr = (void *)csio->data_ptr; 2715285809Sscottl pccb->numSgElements = nsegs; 2716285809Sscottl } /* else */ 2717285809Sscottl } 2718285809Sscottl 2719285809Sscottl /* set data transfer direction */ 2720285809Sscottl if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 2721285809Sscottl { 2722285809Sscottl op = BUS_DMASYNC_PREWRITE; 2723285809Sscottl pccb->tiSuperScsiRequest.dataDirection = tiDirectionOut; 2724285809Sscottl } 2725285809Sscottl else 2726285809Sscottl { 2727285809Sscottl op = BUS_DMASYNC_PREREAD; 2728285809Sscottl pccb->tiSuperScsiRequest.dataDirection = tiDirectionIn; 2729285809Sscottl } 2730285809Sscottl 2731285809Sscottl pScsiCmnd = &pccb->tiSuperScsiRequest.scsiCmnd; 2732285809Sscottl 2733285809Sscottl pScsiCmnd->expDataLength = pccb->dataLen; 2734285809Sscottl 2735285809Sscottl if (csio->ccb_h.flags & CAM_CDB_POINTER) 2736285809Sscottl { 2737285809Sscottl bcopy(csio->cdb_io.cdb_ptr, &pScsiCmnd->cdb[0], csio->cdb_len); 2738285809Sscottl } 2739285809Sscottl else 2740285809Sscottl { 2741285809Sscottl bcopy(csio->cdb_io.cdb_bytes, &pScsiCmnd->cdb[0],csio->cdb_len); 2742285809Sscottl } 2743285809Sscottl 2744285809Sscottl CDB = &pScsiCmnd->cdb[0]; 2745285809Sscottl 2746285809Sscottl switch (CDB[0]) 2747285809Sscottl { 2748285809Sscottl case REQUEST_SENSE: /* requires different buffer */ 2749285809Sscottl /* This code should not be excercised because SAS support auto sense 2750285809Sscottl For the completeness, vtophys() is still used here. 2751285809Sscottl */ 2752285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGListCB: QueueCmnd - REQUEST SENSE new\n"); 2753285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = htole32(pccb->senseLen); 2754285809Sscottl phys_addr = vtophys(&csio->sense_data); 2755285809Sscottl CPU_TO_LE32(pccb->tiSuperScsiRequest.agSgl1, phys_addr); 2756285809Sscottl pccb->tiSuperScsiRequest.agSgl1.type = htole32(tiSgl); 2757285809Sscottl pccb->dataLen = pccb->senseLen; 2758285809Sscottl pccb->numSgElements = 1; 2759285809Sscottl break; 2760285809Sscottl case INQUIRY: 2761285809Sscottl /* only using lun 0 for device type detection */ 2762285809Sscottl pccb->flags |= AGTIAPI_INQUIRY; 2763285809Sscottl break; 2764285809Sscottl case TEST_UNIT_READY: 2765285809Sscottl case RESERVE: 2766285809Sscottl case RELEASE: 2767285809Sscottl case START_STOP: 2768285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len = 0; 2769285809Sscottl pccb->dataLen = 0; 2770285809Sscottl break; 2771285809Sscottl case READ_6: 2772285809Sscottl case WRITE_6: 2773285809Sscottl /* Extract LBA */ 2774285809Sscottl start_lba = ((CDB[1] & 0x1f) << 16) | 2775285809Sscottl (CDB[2] << 8) | 2776285809Sscottl (CDB[3]); 2777285809Sscottl#ifdef HIALEAH_ENCRYPTION 2778285809Sscottl io_is_encryptable = 1; 2779285809Sscottl#endif 2780285809Sscottl break; 2781285809Sscottl case READ_10: 2782285809Sscottl case WRITE_10: 2783285809Sscottl case READ_12: 2784285809Sscottl case WRITE_12: 2785285809Sscottl /* Extract LBA */ 2786285809Sscottl start_lba = (CDB[2] << 24) | 2787285809Sscottl (CDB[3] << 16) | 2788285809Sscottl (CDB[4] << 8) | 2789285809Sscottl (CDB[5]); 2790285809Sscottl#ifdef HIALEAH_ENCRYPTION 2791285809Sscottl io_is_encryptable = 1; 2792285809Sscottl#endif 2793285809Sscottl break; 2794285809Sscottl case READ_16: 2795285809Sscottl case WRITE_16: 2796285809Sscottl /* Extract LBA */ 2797285809Sscottl start_lba = (CDB[2] << 24) | 2798285809Sscottl (CDB[3] << 16) | 2799285809Sscottl (CDB[4] << 8) | 2800285809Sscottl (CDB[5]); 2801285809Sscottl start_lba <<= 32; 2802285809Sscottl start_lba |= ((CDB[6] << 24) | 2803285809Sscottl (CDB[7] << 16) | 2804285809Sscottl (CDB[8] << 8) | 2805285809Sscottl (CDB[9])); 2806285809Sscottl#ifdef HIALEAH_ENCRYPTION 2807285809Sscottl io_is_encryptable = 1; 2808285809Sscottl#endif 2809285809Sscottl break; 2810285809Sscottl default: 2811285809Sscottl break; 2812285809Sscottl } 2813285809Sscottl 2814285809Sscottl /* fill device lun based one address mode */ 2815285809Sscottl agtiapi_SetLunField(pccb); 2816285809Sscottl 2817285809Sscottl if (pccb->targetId < 0 || pccb->targetId >= maxTargets) 2818285809Sscottl { 2819285809Sscottl pccb->ccbStatus = tiIOFailed; 2820285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 2821285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 2822285809Sscottl ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL 2823285809Sscottl xpt_done(ccb); 2824285809Sscottl pccb->ccb = NULL; 2825285809Sscottl return; 2826285809Sscottl } 2827285809Sscottl if (INDEX(pmcsc, pccb->targetId) >= maxTargets) 2828285809Sscottl { 2829285809Sscottl pccb->ccbStatus = tiIOFailed; 2830285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 2831285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 2832285809Sscottl ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL 2833285809Sscottl xpt_done(ccb); 2834285809Sscottl pccb->ccb = NULL; 2835285809Sscottl return; 2836285809Sscottl } 2837285809Sscottl pDev = &pmcsc->pDevList[INDEX(pmcsc, pccb->targetId)]; 2838285809Sscottl 2839285809Sscottl#if 1 2840285809Sscottl if ((pmcsc->flags & EDC_DATA) && 2841285809Sscottl (pDev->flags & EDC_DATA)) 2842285809Sscottl { 2843285809Sscottl /* 2844285809Sscottl * EDC support: 2845285809Sscottl * 2846285809Sscottl * Possible command supported - 2847285809Sscottl * READ_6, READ_10, READ_12, READ_16, READ_LONG, READ_BUFFER, 2848285809Sscottl * READ_DEFECT_DATA, etc. 2849285809Sscottl * WRITE_6, WRITE_10, WRITE_12, WRITE_16, WRITE_LONG, WRITE_LONG2, 2850285809Sscottl * WRITE_BUFFER, WRITE_VERIFY, WRITE_VERIFY_12, etc. 2851285809Sscottl * 2852285809Sscottl * Do some data length adjustment and set chip operation instruction. 2853285809Sscottl */ 2854285809Sscottl switch (CDB[0]) 2855285809Sscottl { 2856285809Sscottl case READ_6: 2857285809Sscottl case READ_10: 2858285809Sscottl case READ_12: 2859285809Sscottl case READ_16: 2860285809Sscottl // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT); 2861285809Sscottl#ifdef AGTIAPI_TEST_DIF 2862285809Sscottl pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF; 2863285809Sscottl#endif 2864285809Sscottl pccb->flags |= EDC_DATA; 2865285809Sscottl 2866285809Sscottl#ifdef TEST_VERIFY_AND_FORWARD 2867285809Sscottl pccb->tiSuperScsiRequest.Dif.flags = 2868285809Sscottl DIF_VERIFY_FORWARD | DIF_UDT_REF_BLOCK_COUNT; 2869285809Sscottl if(pDev->sector_size == 520) { 2870285809Sscottl pScsiCmnd->expDataLength += (pccb->dataLen / 512) * 8; 2871285809Sscottl } else if(pDev->sector_size == 4104) { 2872285809Sscottl pScsiCmnd->expDataLength += (pccb->dataLen / 4096) * 8; 2873285809Sscottl } 2874285809Sscottl#else 2875285809Sscottl#ifdef AGTIAPI_TEST_DIF 2876285809Sscottl pccb->tiSuperScsiRequest.Dif.flags = 2877285809Sscottl DIF_VERIFY_DELETE | DIF_UDT_REF_BLOCK_COUNT; 2878285809Sscottl#endif 2879285809Sscottl#endif 2880285809Sscottl#ifdef AGTIAPI_TEST_DIF 2881285809Sscottl switch(pDev->sector_size) { 2882285809Sscottl case 528: 2883285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2884285809Sscottl ( DIF_BLOCK_SIZE_520 << 16 ); 2885285809Sscottl break; 2886285809Sscottl case 4104: 2887285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2888285809Sscottl ( DIF_BLOCK_SIZE_4096 << 16 ); 2889285809Sscottl break; 2890285809Sscottl case 4168: 2891285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2892285809Sscottl ( DIF_BLOCK_SIZE_4160 << 16 ); 2893285809Sscottl break; 2894285809Sscottl } 2895285809Sscottl 2896285809Sscottl if(pCard->flags & EDC_DATA_CRC) 2897285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= DIF_CRC_VERIFICATION; 2898285809Sscottl 2899285809Sscottl /* Turn on upper 4 bits of UVM */ 2900285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 0x03c00000; 2901285809Sscottl 2902285809Sscottl#endif 2903285809Sscottl#ifdef AGTIAPI_TEST_DPL 2904285809Sscottl if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) { 2905285809Sscottl printk(KERN_ERR "SetupDifPerLA Failed.\n"); 2906285809Sscottl cmnd->result = SCSI_HOST(DID_ERROR); 2907285809Sscottl goto err; 2908285809Sscottl } 2909285809Sscottl pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE; 2910285809Sscottl#endif 2911285809Sscottl#ifdef AGTIAPI_TEST_DIF 2912285809Sscottl /* Set App Tag */ 2913285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa; 2914285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb; 2915285809Sscottl 2916285809Sscottl /* Set LBA in UDT array */ 2917285809Sscottl if(CDB[0] == READ_6) { 2918285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3]; 2919285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2]; 2920285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f; 2921285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[5] = 0; 2922285809Sscottl } else if(CDB[0] == READ_10 || CDB[0] == READ_12) { 2923285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5]; 2924285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4]; 2925285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3]; 2926285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2]; 2927285809Sscottl } else if(CDB[0] == READ_16) { 2928285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[9]; 2929285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[8]; 2930285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[7]; 2931285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[6]; 2932285809Sscottl /* Note: 32 bits lost */ 2933285809Sscottl } 2934285809Sscottl#endif 2935285809Sscottl 2936285809Sscottl break; 2937285809Sscottl case WRITE_6: 2938285809Sscottl case WRITE_10: 2939285809Sscottl case WRITE_12: 2940285809Sscottl case WRITE_16: 2941285809Sscottl // BUG_ON(pccb->tiSuperScsiRequest.flags & TI_SCSI_INITIATOR_ENCRYPT); 2942285809Sscottl pccb->flags |= EDC_DATA; 2943285809Sscottl#ifdef AGTIAPI_TEST_DIF 2944285809Sscottl pccb->tiSuperScsiRequest.flags |= TI_SCSI_INITIATOR_DIF; 2945285809Sscottl pccb->tiSuperScsiRequest.Dif.flags = 2946285809Sscottl DIF_INSERT | DIF_UDT_REF_BLOCK_COUNT; 2947285809Sscottl switch(pDev->sector_size) { 2948285809Sscottl case 528: 2949285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2950285809Sscottl (DIF_BLOCK_SIZE_520 << 16); 2951285809Sscottl break; 2952285809Sscottl case 4104: 2953285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2954285809Sscottl ( DIF_BLOCK_SIZE_4096 << 16 ); 2955285809Sscottl break; 2956285809Sscottl case 4168: 2957285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 2958285809Sscottl ( DIF_BLOCK_SIZE_4160 << 16 ); 2959285809Sscottl break; 2960285809Sscottl } 2961285809Sscottl 2962285809Sscottl /* Turn on upper 4 bits of UUM */ 2963285809Sscottl pccb->tiSuperScsiRequest.Dif.flags |= 0xf0000000; 2964285809Sscottl#endif 2965285809Sscottl#ifdef AGTIAPI_TEST_DPL 2966285809Sscottl if(agtiapi_SetupDifPerLA(pCard, pccb, start_lba) < 0) { 2967285809Sscottl printk(KERN_ERR "SetupDifPerLA Failed.\n"); 2968285809Sscottl cmnd->result = SCSI_HOST(DID_ERROR); 2969285809Sscottl goto err; 2970285809Sscottl } 2971285809Sscottl pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = TRUE; 2972285809Sscottl#endif 2973285809Sscottl#ifdef AGTIAPI_TEST_DIF 2974285809Sscottl /* Set App Tag */ 2975285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[0] = 0xaa; 2976285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[1] = 0xbb; 2977285809Sscottl 2978285809Sscottl /* Set LBA in UDT array */ 2979285809Sscottl if(CDB[0] == WRITE_6) { 2980285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[3]; 2981285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[2]; 2982285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[1] & 0x1f; 2983285809Sscottl } else if(CDB[0] == WRITE_10 || CDB[0] == WRITE_12) { 2984285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5]; 2985285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4]; 2986285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3]; 2987285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2]; 2988285809Sscottl } else if(CDB[0] == WRITE_16) { 2989285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[2] = CDB[5]; 2990285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[3] = CDB[4]; 2991285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[4] = CDB[3]; 2992285809Sscottl pccb->tiSuperScsiRequest.Dif.udtArray[5] = CDB[2]; 2993285809Sscottl /* Note: 32 bits lost */ 2994285809Sscottl } 2995285809Sscottl#endif 2996285809Sscottl break; 2997285809Sscottl } 2998285809Sscottl } 2999285809Sscottl#endif /* end of DIF */ 3000285809Sscottl 3001285809Sscottl if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) 3002285809Sscottl { 3003285809Sscottl switch(csio->tag_action) 3004285809Sscottl { 3005285809Sscottl case MSG_HEAD_OF_Q_TAG: 3006285809Sscottl pScsiCmnd->taskAttribute = TASK_HEAD_OF_QUEUE; 3007285809Sscottl break; 3008285809Sscottl case MSG_ACA_TASK: 3009285809Sscottl pScsiCmnd->taskAttribute = TASK_ACA; 3010285809Sscottl break; 3011285809Sscottl case MSG_ORDERED_Q_TAG: 3012285809Sscottl pScsiCmnd->taskAttribute = TASK_ORDERED; 3013285809Sscottl break; 3014285809Sscottl case MSG_SIMPLE_Q_TAG: /* fall through */ 3015285809Sscottl default: 3016285809Sscottl pScsiCmnd->taskAttribute = TASK_SIMPLE; 3017285809Sscottl break; 3018285809Sscottl } 3019285809Sscottl } 3020285809Sscottl 3021285809Sscottl if (pccb->tiSuperScsiRequest.agSgl1.len != 0 && pccb->dataLen != 0) 3022285809Sscottl { 3023285809Sscottl /* should be just before start IO */ 3024285809Sscottl bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op); 3025285809Sscottl } 3026285809Sscottl 3027285809Sscottl /* 3028285809Sscottl * If assigned pDevHandle is not available 3029285809Sscottl * then there is no need to send it to StartIO() 3030285809Sscottl */ 3031285809Sscottl if (pccb->targetId < 0 || pccb->targetId >= maxTargets) 3032285809Sscottl { 3033285809Sscottl pccb->ccbStatus = tiIOFailed; 3034285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 3035285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 3036285809Sscottl ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL 3037285809Sscottl xpt_done(ccb); 3038285809Sscottl pccb->ccb = NULL; 3039285809Sscottl return; 3040285809Sscottl } 3041285809Sscottl TID = INDEX(pmcsc, pccb->targetId); 3042285809Sscottl if ((TID >= pmcsc->devDiscover) || 3043285809Sscottl !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle)) 3044285809Sscottl { 3045285809Sscottl /* 3046285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGListCB: not sending ccb devH %p," 3047285809Sscottl " target %d tid %d/%d card %p ERROR pccb %p\n", 3048285809Sscottl pccb->devHandle, pccb->targetId, TID, 3049285809Sscottl pmcsc->devDiscover, pmcsc, pccb ); 3050285809Sscottl */ 3051285809Sscottl pccb->ccbStatus = tiIOFailed; 3052285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 3053285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 3054285809Sscottl ccb->ccb_h.status = CAM_DEV_NOT_THERE; // ## v. CAM_FUNC_NOTAVAIL 3055285809Sscottl xpt_done(ccb); 3056285809Sscottl pccb->ccb = NULL; 3057285809Sscottl return; 3058285809Sscottl } 3059285809Sscottl AGTIAPI_IO( "agtiapi_PrepareSGListCB: send ccb pccb->devHandle %p, " 3060285809Sscottl "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n", 3061285809Sscottl pccb->devHandle, pccb->targetId, TID, pmcsc->devDiscover, 3062285809Sscottl pmcsc ); 3063285809Sscottl#ifdef HIALEAH_ENCRYPTION 3064285809Sscottl if(pmcsc->encrypt && io_is_encryptable) { 3065285809Sscottl agtiapi_SetupEncryptedIO(pmcsc, pccb, start_lba); 3066285809Sscottl } else{ 3067285809Sscottl io_is_encryptable = 0; 3068285809Sscottl pccb->tiSuperScsiRequest.flags = 0; 3069285809Sscottl } 3070285809Sscottl#endif 3071285809Sscottl // put the request in send queue 3072285809Sscottl agtiapi_QueueCCB( pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail 3073285809Sscottl AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb ); 3074285809Sscottl agtiapi_StartIO(pmcsc); 3075285809Sscottl return; 3076285809Sscottl} 3077285809Sscottl 3078285809Sscottl/****************************************************************************** 3079285809Sscottlagtiapi_StartIO() 3080285809Sscottl 3081285809SscottlPurpose: 3082285809Sscottl Send IO request down for processing. 3083285809SscottlParameters: 3084285809Sscottl (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 3085285809SscottlReturn: 3086285809SscottlNote: 3087285809Sscottl******************************************************************************/ 3088285809SscottlSTATIC void agtiapi_StartIO( struct agtiapi_softc *pmcsc ) 3089285809Sscottl{ 3090285809Sscottl ccb_t *pccb; 3091285809Sscottl int TID; 3092285809Sscottl ag_device_t *targ; 3093285809Sscottl struct ccb_relsim crs; 3094285809Sscottl 3095285809Sscottl AGTIAPI_IO( "agtiapi_StartIO: start\n" ); 3096285809Sscottl 3097285809Sscottl AG_LOCAL_LOCK( &pmcsc->sendLock ); 3098285809Sscottl pccb = pmcsc->ccbSendHead; 3099285809Sscottl 3100285809Sscottl /* if link is down, do nothing */ 3101285809Sscottl if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET) 3102285809Sscottl { 3103285809Sscottl AG_LOCAL_UNLOCK( &pmcsc->sendLock ); 3104285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: goto ext\n" ); 3105285809Sscottl goto ext; 3106285809Sscottl } 3107285809Sscottl 3108285809Sscottl 3109285809Sscottl if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets) 3110285809Sscottl { 3111285809Sscottl TID = INDEX(pmcsc, pccb->targetId); 3112285809Sscottl targ = &pmcsc->pDevList[TID]; 3113285809Sscottl } 3114285809Sscottl 3115285809Sscottl 3116285809Sscottl /* clear send queue */ 3117285809Sscottl pmcsc->ccbSendHead = NULL; 3118285809Sscottl pmcsc->ccbSendTail = NULL; 3119285809Sscottl AG_LOCAL_UNLOCK( &pmcsc->sendLock ); 3120285809Sscottl 3121285809Sscottl /* send all ccbs down */ 3122285809Sscottl while (pccb) 3123285809Sscottl { 3124285809Sscottl pccb_t pccb_next; 3125285809Sscottl U32 status; 3126285809Sscottl 3127285809Sscottl pccb_next = pccb->pccbNext; 3128285809Sscottl pccb->pccbNext = NULL; 3129285809Sscottl 3130285809Sscottl if (!pccb->ccb) 3131285809Sscottl { 3132285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: pccb->ccb is NULL ERROR!\n" ); 3133285809Sscottl pccb = pccb_next; 3134285809Sscottl continue; 3135285809Sscottl } 3136285809Sscottl AG_IO_DUMPCCB( pccb ); 3137285809Sscottl 3138285809Sscottl if (!pccb->devHandle) 3139285809Sscottl { 3140285809Sscottl agtiapi_DumpCCB( pccb ); 3141285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: ccb NULL device ERROR!\n" ); 3142285809Sscottl pccb = pccb_next; 3143285809Sscottl continue; 3144285809Sscottl } 3145285809Sscottl AGTIAPI_IO( "agtiapi_StartIO: ccb %p retry %d\n", pccb, pccb->retryCount ); 3146285809Sscottl 3147285809Sscottl#ifndef ABORT_TEST 3148285809Sscottl if( !pccb->devHandle || !pccb->devHandle->osData || /* in rmmod case */ 3149285809Sscottl !(((ag_device_t *)(pccb->devHandle->osData))->flags & ACTIVE)) 3150285809Sscottl { 3151285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: device %p not active! ERROR\n", 3152285809Sscottl pccb->devHandle ); 3153285809Sscottl if( pccb->devHandle ) { 3154285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: device not active detail" 3155285809Sscottl " -- osData:%p\n", 3156285809Sscottl pccb->devHandle->osData ); 3157285809Sscottl if( pccb->devHandle->osData ) { 3158285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: more device not active detail" 3159285809Sscottl " -- active flag:%d\n", 3160285809Sscottl ( (ag_device_t *) 3161285809Sscottl (pccb->devHandle->osData))->flags & ACTIVE ); 3162285809Sscottl } 3163285809Sscottl } 3164285809Sscottl pccb->ccbStatus = tiIOFailed; 3165285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 3166285809Sscottl agtiapi_Done( pmcsc, pccb ); 3167285809Sscottl pccb = pccb_next; 3168285809Sscottl continue; 3169285809Sscottl } 3170285809Sscottl#endif 3171285809Sscottl 3172285809Sscottl#ifdef FAST_IO_TEST 3173285809Sscottl status = agtiapi_FastIOTest( pmcsc, pccb ); 3174285809Sscottl#else 3175285809Sscottl status = tiINISuperIOStart( &pmcsc->tiRoot, 3176285809Sscottl &pccb->tiIORequest, 3177285809Sscottl pccb->devHandle, 3178285809Sscottl &pccb->tiSuperScsiRequest, 3179285809Sscottl (void *)&pccb->tdIOReqBody, 3180285809Sscottl tiInterruptContext ); 3181285809Sscottl#endif 3182285809Sscottl switch( status ) 3183285809Sscottl { 3184285809Sscottl case tiSuccess: 3185285809Sscottl /* 3186285809Sscottl static int squelchCount = 0; 3187285809Sscottl if ( 200000 == squelchCount++ ) // squelch prints 3188285809Sscottl { 3189285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart stat tiSuccess %p\n", 3190285809Sscottl pccb ); 3191285809Sscottl squelchCount = 0; // reset count 3192285809Sscottl } 3193285809Sscottl */ 3194285809Sscottl 3195285809Sscottl 3196285809Sscottl break; 3197285809Sscottl case tiDeviceBusy: 3198285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiDeviceBusy %p\n", 3199285809Sscottl pccb->ccb ); 3200285809Sscottl#ifdef LOGEVENT 3201285809Sscottl agtiapi_LogEvent( pmcsc, 3202285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 3203285809Sscottl 0, 3204285809Sscottl agNULL, 3205285809Sscottl 0, 3206285809Sscottl "tiINIIOStart tiDeviceBusy " ); 3207285809Sscottl#endif 3208285809Sscottl pccb->ccbStatus = tiIOFailed; 3209285809Sscottl pccb->scsiStatus = tiDeviceBusy; 3210285809Sscottl agtiapi_Done(pmcsc, pccb); 3211285809Sscottl break; 3212285809Sscottl case tiBusy: 3213285809Sscottl 3214285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiBusy %p\n", 3215285809Sscottl pccb->ccb ); 3216285809Sscottl#ifdef LOGEVENT 3217285809Sscottl agtiapi_LogEvent( pmcsc, 3218285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 3219285809Sscottl 0, 3220285809Sscottl agNULL, 3221285809Sscottl 0, 3222285809Sscottl "tiINIIOStart tiBusy " ); 3223285809Sscottl#endif 3224285809Sscottl 3225285809Sscottl pccb->ccbStatus = tiIOFailed; 3226285809Sscottl pccb->scsiStatus = tiBusy; 3227285809Sscottl agtiapi_Done(pmcsc, pccb); 3228285809Sscottl 3229285809Sscottl break; 3230285809Sscottl case tiIONoDevice: 3231285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartIO: tiINIIOStart status tiNoDevice %p " 3232285809Sscottl "ERROR\n", pccb->ccb ); 3233285809Sscottl#ifdef LOGEVENT 3234285809Sscottl agtiapi_LogEvent( pmcsc, 3235285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 3236285809Sscottl 0, 3237285809Sscottl agNULL, 3238285809Sscottl 0, 3239285809Sscottl "tiINIIOStart invalid device handle " ); 3240285809Sscottl#endif 3241285809Sscottl#ifndef ABORT_TEST 3242285809Sscottl /* return command back to OS due to no device available */ 3243285809Sscottl ((ag_device_t *)(pccb->devHandle->osData))->flags &= ~ACTIVE; 3244285809Sscottl pccb->ccbStatus = tiIOFailed; 3245285809Sscottl pccb->scsiStatus = tiDetailNoLogin; 3246285809Sscottl agtiapi_Done(pmcsc, pccb); 3247285809Sscottl#else 3248285809Sscottl /* for short cable pull, we want IO retried - 3-18-2005 */ 3249285809Sscottl agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail 3250285809Sscottl AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb); 3251285809Sscottl#endif 3252285809Sscottl break; 3253285809Sscottl case tiError: 3254285809Sscottl AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n", 3255285809Sscottl pccb->ccb); 3256285809Sscottl#ifdef LOGEVENT 3257285809Sscottl agtiapi_LogEvent(pmcsc, 3258285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 3259285809Sscottl 0, 3260285809Sscottl agNULL, 3261285809Sscottl 0, 3262285809Sscottl "tiINIIOStart tiError "); 3263285809Sscottl#endif 3264285809Sscottl pccb->ccbStatus = tiIOFailed; 3265285809Sscottl pccb->scsiStatus = tiDetailOtherError; 3266285809Sscottl agtiapi_Done(pmcsc, pccb); 3267285809Sscottl break; 3268285809Sscottl default: 3269285809Sscottl AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n", 3270285809Sscottl status, pccb->ccb); 3271285809Sscottl#ifdef LOGEVENT 3272285809Sscottl agtiapi_LogEvent(pmcsc, 3273285809Sscottl IOCTL_EVT_SEV_ERROR, 3274285809Sscottl 0, 3275285809Sscottl agNULL, 3276285809Sscottl 0, 3277285809Sscottl "tiINIIOStart unexpected status "); 3278285809Sscottl#endif 3279285809Sscottl pccb->ccbStatus = tiIOFailed; 3280285809Sscottl pccb->scsiStatus = tiDetailOtherError; 3281285809Sscottl agtiapi_Done(pmcsc, pccb); 3282285809Sscottl } 3283285809Sscottl 3284285809Sscottl pccb = pccb_next; 3285285809Sscottl } 3286285809Sscottlext: 3287285809Sscottl /* some IO requests might have been completed */ 3288285809Sscottl AG_GET_DONE_PCCB(pccb, pmcsc); 3289285809Sscottl return; 3290285809Sscottl} 3291285809Sscottl 3292285809Sscottl/****************************************************************************** 3293285809Sscottlagtiapi_StartSMP() 3294285809Sscottl 3295285809SscottlPurpose: 3296285809Sscottl Send SMP request down for processing. 3297285809SscottlParameters: 3298285809Sscottl (struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 3299285809SscottlReturn: 3300285809SscottlNote: 3301285809Sscottl******************************************************************************/ 3302285809SscottlSTATIC void agtiapi_StartSMP(struct agtiapi_softc *pmcsc) 3303285809Sscottl{ 3304285809Sscottl ccb_t *pccb; 3305285809Sscottl 3306285809Sscottl AGTIAPI_PRINTK("agtiapi_StartSMP: start\n"); 3307285809Sscottl 3308285809Sscottl AG_LOCAL_LOCK(&pmcsc->sendSMPLock); 3309285809Sscottl pccb = pmcsc->smpSendHead; 3310285809Sscottl 3311285809Sscottl /* if link is down, do nothing */ 3312285809Sscottl if ((pccb == NULL) || pmcsc->flags & AGTIAPI_RESET) 3313285809Sscottl { 3314285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock); 3315285809Sscottl AGTIAPI_PRINTK("agtiapi_StartSMP: goto ext\n"); 3316285809Sscottl goto ext; 3317285809Sscottl } 3318285809Sscottl 3319285809Sscottl /* clear send queue */ 3320285809Sscottl pmcsc->smpSendHead = NULL; 3321285809Sscottl pmcsc->smpSendTail = NULL; 3322285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->sendSMPLock); 3323285809Sscottl 3324285809Sscottl /* send all ccbs down */ 3325285809Sscottl while (pccb) 3326285809Sscottl { 3327285809Sscottl pccb_t pccb_next; 3328285809Sscottl U32 status; 3329285809Sscottl 3330285809Sscottl pccb_next = pccb->pccbNext; 3331285809Sscottl pccb->pccbNext = NULL; 3332285809Sscottl 3333285809Sscottl if (!pccb->ccb) 3334285809Sscottl { 3335285809Sscottl AGTIAPI_PRINTK("agtiapi_StartSMP: pccb->ccb is NULL ERROR!\n"); 3336285809Sscottl pccb = pccb_next; 3337285809Sscottl continue; 3338285809Sscottl } 3339285809Sscottl 3340285809Sscottl if (!pccb->devHandle) 3341285809Sscottl { 3342285809Sscottl AGTIAPI_PRINTK("agtiapi_StartSMP: ccb NULL device ERROR!\n"); 3343285809Sscottl pccb = pccb_next; 3344285809Sscottl continue; 3345285809Sscottl } 3346285809Sscottl pccb->flags |= TAG_SMP; // mark as SMP for later tracking 3347285809Sscottl AGTIAPI_PRINTK( "agtiapi_StartSMP: ccb %p retry %d\n", 3348285809Sscottl pccb, pccb->retryCount ); 3349285809Sscottl status = tiINISMPStart( &pmcsc->tiRoot, 3350285809Sscottl &pccb->tiIORequest, 3351285809Sscottl pccb->devHandle, 3352285809Sscottl &pccb->tiSMPFrame, 3353285809Sscottl (void *)&pccb->tdIOReqBody, 3354285809Sscottl tiInterruptContext); 3355285809Sscottl 3356285809Sscottl switch (status) 3357285809Sscottl { 3358285809Sscottl case tiSuccess: 3359285809Sscottl break; 3360285809Sscottl case tiBusy: 3361285809Sscottl AGTIAPI_PRINTK("agtiapi_StartSMP: tiINISMPStart status tiBusy %p\n", 3362285809Sscottl pccb->ccb); 3363285809Sscottl /* pending ccb back to send queue */ 3364285809Sscottl agtiapi_QueueCCB(pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail 3365285809Sscottl AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb); 3366285809Sscottl break; 3367285809Sscottl case tiError: 3368285809Sscottl AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status tiError %p\n", 3369285809Sscottl pccb->ccb); 3370285809Sscottl pccb->ccbStatus = tiSMPFailed; 3371285809Sscottl agtiapi_SMPDone(pmcsc, pccb); 3372285809Sscottl break; 3373285809Sscottl default: 3374285809Sscottl AGTIAPI_PRINTK("agtiapi_StartIO: tiINIIOStart status default %x %p\n", 3375285809Sscottl status, pccb->ccb); 3376285809Sscottl pccb->ccbStatus = tiSMPFailed; 3377285809Sscottl agtiapi_SMPDone(pmcsc, pccb); 3378285809Sscottl } 3379285809Sscottl 3380285809Sscottl pccb = pccb_next; 3381285809Sscottl } 3382285809Sscottl ext: 3383285809Sscottl /* some SMP requests might have been completed */ 3384285809Sscottl AG_GET_DONE_SMP_PCCB(pccb, pmcsc); 3385285809Sscottl 3386285809Sscottl return; 3387285809Sscottl} 3388285809Sscottl 3389285809Sscottl#if __FreeBSD_version > 901000 3390285809Sscottl/****************************************************************************** 3391285809Sscottlagtiapi_PrepareSMPSGList() 3392285809Sscottl 3393285809SscottlPurpose: 3394285809Sscottl This function prepares scatter-gather list for the given ccb 3395285809SscottlParameters: 3396285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 3397285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 3398285809SscottlReturn: 3399285809Sscottl 0 - success 3400285809Sscottl 1 - failure 3401285809Sscottl 3402285809SscottlNote: 3403285809Sscottl******************************************************************************/ 3404285809Sscottlstatic int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb ) 3405285809Sscottl{ 3406285809Sscottl /* Pointer to CAM's ccb */ 3407285809Sscottl union ccb *ccb = pccb->ccb; 3408285809Sscottl struct ccb_smpio *csmpio = &ccb->smpio; 3409285809Sscottl struct ccb_hdr *ccbh = &ccb->ccb_h; 3410285809Sscottl 3411285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n"); 3412285809Sscottl switch((ccbh->flags & CAM_DATA_MASK)) 3413285809Sscottl { 3414285809Sscottl case CAM_DATA_PADDR: 3415285809Sscottl case CAM_DATA_SG_PADDR: 3416285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address not supported\n"); 3417285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 3418285809Sscottl xpt_done(ccb); 3419285809Sscottl return tiReject; 3420285809Sscottl case CAM_DATA_SG: 3421285809Sscottl 3422285809Sscottl /* 3423285809Sscottl * Currently we do not support Multiple SG list 3424285809Sscottl * return error for now 3425285809Sscottl */ 3426285809Sscottl if ( (csmpio->smp_request_sglist_cnt > 1) 3427285809Sscottl || (csmpio->smp_response_sglist_cnt > 1) ) 3428285809Sscottl { 3429285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list not supported\n"); 3430285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 3431285809Sscottl xpt_done(ccb); 3432285809Sscottl return tiReject; 3433285809Sscottl } 3434285809Sscottl } 3435285809Sscottl if ( csmpio->smp_request_sglist_cnt != 0 ) 3436285809Sscottl { 3437285809Sscottl /* 3438285809Sscottl * Virtual address that needs to translated into 3439285809Sscottl * one or more physical address ranges. 3440285809Sscottl */ 3441285809Sscottl int error; 3442285809Sscottl //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock)); 3443285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n"); 3444285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 3445285809Sscottl pccb->CCB_dmamap, 3446285809Sscottl csmpio->smp_request, 3447285809Sscottl csmpio->smp_request_len, 3448285809Sscottl agtiapi_PrepareSMPSGListCB, 3449285809Sscottl pccb, 3450285809Sscottl BUS_DMA_NOWAIT /* 0 */ ); 3451285809Sscottl 3452285809Sscottl //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock)); 3453285809Sscottl 3454285809Sscottl if (error == EINPROGRESS) 3455285809Sscottl { 3456285809Sscottl /* 3457285809Sscottl * So as to maintain ordering, 3458285809Sscottl * freeze the controller queue 3459285809Sscottl * until our mapping is 3460285809Sscottl * returned. 3461285809Sscottl */ 3462285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" ); 3463285809Sscottl xpt_freeze_simq( pmcsc->sim, 1 ); 3464285809Sscottl pmcsc->SimQFrozen = agTRUE; 3465285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 3466285809Sscottl } 3467285809Sscottl } 3468285809Sscottl if( csmpio->smp_response_sglist_cnt != 0 ) 3469285809Sscottl { 3470285809Sscottl /* 3471285809Sscottl * Virtual address that needs to translated into 3472285809Sscottl * one or more physical address ranges. 3473285809Sscottl */ 3474285809Sscottl int error; 3475285809Sscottl //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) ); 3476285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" ); 3477285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 3478285809Sscottl pccb->CCB_dmamap, 3479285809Sscottl csmpio->smp_response, 3480285809Sscottl csmpio->smp_response_len, 3481285809Sscottl agtiapi_PrepareSMPSGListCB, 3482285809Sscottl pccb, 3483285809Sscottl BUS_DMA_NOWAIT /* 0 */ ); 3484285809Sscottl 3485285809Sscottl //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) ); 3486285809Sscottl 3487285809Sscottl if ( error == EINPROGRESS ) 3488285809Sscottl { 3489285809Sscottl /* 3490285809Sscottl * So as to maintain ordering, 3491285809Sscottl * freeze the controller queue 3492285809Sscottl * until our mapping is 3493285809Sscottl * returned. 3494285809Sscottl */ 3495285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" ); 3496285809Sscottl xpt_freeze_simq( pmcsc->sim, 1 ); 3497285809Sscottl pmcsc->SimQFrozen = agTRUE; 3498285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 3499285809Sscottl } 3500285809Sscottl } 3501285809Sscottl 3502285809Sscottl else 3503285809Sscottl { 3504285809Sscottl if ( (csmpio->smp_request_sglist_cnt == 0) && 3505285809Sscottl (csmpio->smp_response_sglist_cnt == 0) ) 3506285809Sscottl { 3507285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" ); 3508285809Sscottl pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request; 3509285809Sscottl pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len; 3510285809Sscottl pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len; 3511285809Sscottl 3512285809Sscottl // 0xFF to be defined 3513285809Sscottl agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD ); 3514285809Sscottl } 3515285809Sscottl pccb->tiSMPFrame.flag = 0; 3516285809Sscottl } 3517285809Sscottl 3518285809Sscottl return tiSuccess; 3519285809Sscottl} 3520285809Sscottl#else 3521285809Sscottl 3522285809Sscottl/****************************************************************************** 3523285809Sscottlagtiapi_PrepareSMPSGList() 3524285809Sscottl 3525285809SscottlPurpose: 3526285809Sscottl This function prepares scatter-gather list for the given ccb 3527285809SscottlParameters: 3528285809Sscottl struct agtiapi_softc *pmsc (IN) Pointer to the HBA data structure 3529285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 3530285809SscottlReturn: 3531285809Sscottl 0 - success 3532285809Sscottl 1 - failure 3533285809Sscottl 3534285809SscottlNote: 3535285809Sscottl******************************************************************************/ 3536285809Sscottlstatic int agtiapi_PrepareSMPSGList( struct agtiapi_softc *pmcsc, ccb_t *pccb ) 3537285809Sscottl{ 3538285809Sscottl /* Pointer to CAM's ccb */ 3539285809Sscottl union ccb *ccb = pccb->ccb; 3540285809Sscottl struct ccb_smpio *csmpio = &ccb->smpio; 3541285809Sscottl struct ccb_hdr *ccbh = &ccb->ccb_h; 3542285809Sscottl 3543285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSMPSGList: start\n"); 3544285809Sscottl 3545285809Sscottl if (ccbh->flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS)) 3546285809Sscottl { 3547285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Physical Address " 3548285809Sscottl "not supported\n" ); 3549285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 3550285809Sscottl xpt_done(ccb); 3551285809Sscottl return tiReject;; 3552285809Sscottl } 3553285809Sscottl 3554285809Sscottl if (ccbh->flags & CAM_SCATTER_VALID) 3555285809Sscottl { 3556285809Sscottl /* 3557285809Sscottl * Currently we do not support Multiple SG list 3558285809Sscottl * return error for now 3559285809Sscottl */ 3560285809Sscottl if ( (csmpio->smp_request_sglist_cnt > 1) 3561285809Sscottl || (csmpio->smp_response_sglist_cnt > 1) ) 3562285809Sscottl { 3563285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: Multiple SG list " 3564285809Sscottl "not supported\n" ); 3565285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 3566285809Sscottl xpt_done(ccb); 3567285809Sscottl return tiReject;; 3568285809Sscottl } 3569285809Sscottl if ( csmpio->smp_request_sglist_cnt != 0 ) 3570285809Sscottl { 3571285809Sscottl /* 3572285809Sscottl * Virtual address that needs to translated into 3573285809Sscottl * one or more physical address ranges. 3574285809Sscottl */ 3575285809Sscottl int error; 3576285809Sscottl //AG_LOCAL_LOCK(&(pmcsc->pCardInfo->pmIOLock)); 3577285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepareSGList: virtual address\n"); 3578285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 3579285809Sscottl pccb->CCB_dmamap, 3580285809Sscottl csmpio->smp_request, 3581285809Sscottl csmpio->smp_request_len, 3582285809Sscottl agtiapi_PrepareSMPSGListCB, 3583285809Sscottl pccb, 3584285809Sscottl BUS_DMA_NOWAIT /* 0 */ ); 3585285809Sscottl 3586285809Sscottl //AG_LOCAL_UNLOCK(&(pmcsc->pCardInfo->pmIOLock)); 3587285809Sscottl 3588285809Sscottl if (error == EINPROGRESS) 3589285809Sscottl { 3590285809Sscottl /* 3591285809Sscottl * So as to maintain ordering, 3592285809Sscottl * freeze the controller queue 3593285809Sscottl * until our mapping is 3594285809Sscottl * returned. 3595285809Sscottl */ 3596285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" ); 3597285809Sscottl xpt_freeze_simq( pmcsc->sim, 1 ); 3598285809Sscottl pmcsc->SimQFrozen = agTRUE; 3599285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 3600285809Sscottl } 3601285809Sscottl } 3602285809Sscottl if( csmpio->smp_response_sglist_cnt != 0 ) 3603285809Sscottl { 3604285809Sscottl /* 3605285809Sscottl * Virtual address that needs to translated into 3606285809Sscottl * one or more physical address ranges. 3607285809Sscottl */ 3608285809Sscottl int error; 3609285809Sscottl //AG_LOCAL_LOCK( &(pmcsc->pCardInfo->pmIOLock) ); 3610285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: virtual address\n" ); 3611285809Sscottl error = bus_dmamap_load( pmcsc->buffer_dmat, 3612285809Sscottl pccb->CCB_dmamap, 3613285809Sscottl csmpio->smp_response, 3614285809Sscottl csmpio->smp_response_len, 3615285809Sscottl agtiapi_PrepareSMPSGListCB, 3616285809Sscottl pccb, 3617285809Sscottl BUS_DMA_NOWAIT /* 0 */ ); 3618285809Sscottl 3619285809Sscottl //AG_LOCAL_UNLOCK( &(pmcsc->pCardInfo->pmIOLock) ); 3620285809Sscottl 3621285809Sscottl if ( error == EINPROGRESS ) 3622285809Sscottl { 3623285809Sscottl /* 3624285809Sscottl * So as to maintain ordering, 3625285809Sscottl * freeze the controller queue 3626285809Sscottl * until our mapping is 3627285809Sscottl * returned. 3628285809Sscottl */ 3629285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSGList: EINPROGRESS\n" ); 3630285809Sscottl xpt_freeze_simq( pmcsc->sim, 1 ); 3631285809Sscottl pmcsc->SimQFrozen = agTRUE; 3632285809Sscottl ccbh->status |= CAM_RELEASE_SIMQ; 3633285809Sscottl } 3634285809Sscottl } 3635285809Sscottl } 3636285809Sscottl else 3637285809Sscottl { 3638285809Sscottl if ( (csmpio->smp_request_sglist_cnt == 0) && 3639285809Sscottl (csmpio->smp_response_sglist_cnt == 0) ) 3640285809Sscottl { 3641285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGList: physical address\n" ); 3642285809Sscottl pccb->tiSMPFrame.outFrameBuf = (void *)csmpio->smp_request; 3643285809Sscottl pccb->tiSMPFrame.outFrameLen = csmpio->smp_request_len; 3644285809Sscottl pccb->tiSMPFrame.expectedRespLen = csmpio->smp_response_len; 3645285809Sscottl 3646285809Sscottl // 0xFF to be defined 3647285809Sscottl agtiapi_PrepareSMPSGListCB( pccb, NULL, 0, 0xAABBCCDD ); 3648285809Sscottl } 3649285809Sscottl pccb->tiSMPFrame.flag = 0; 3650285809Sscottl } 3651285809Sscottl 3652285809Sscottl return tiSuccess; 3653285809Sscottl} 3654285809Sscottl 3655285809Sscottl#endif 3656285809Sscottl/****************************************************************************** 3657285809Sscottlagtiapi_PrepareSMPSGListCB() 3658285809Sscottl 3659285809SscottlPurpose: 3660285809Sscottl Callback function for bus_dmamap_load() 3661285809Sscottl This fuctions sends IO to LL layer. 3662285809SscottlParameters: 3663285809Sscottl void *arg (IN) Pointer to the HBA data structure 3664285809Sscottl bus_dma_segment_t *segs (IN) Pointer to dma segment 3665285809Sscottl int nsegs (IN) number of dma segment 3666285809Sscottl int error (IN) error 3667285809SscottlReturn: 3668285809SscottlNote: 3669285809Sscottl******************************************************************************/ 3670285809Sscottlstatic void agtiapi_PrepareSMPSGListCB( void *arg, 3671285809Sscottl bus_dma_segment_t *segs, 3672285809Sscottl int nsegs, 3673285809Sscottl int error ) 3674285809Sscottl{ 3675285809Sscottl pccb_t pccb = arg; 3676285809Sscottl union ccb *ccb = pccb->ccb; 3677285809Sscottl struct agtiapi_softc *pmcsc; 3678285809Sscottl U32 TID = CMND_TO_TARGET(ccb); 3679285809Sscottl int status; 3680285809Sscottl tiDeviceHandle_t *tiExpDevHandle; 3681285809Sscottl tiPortalContext_t *tiExpPortalContext; 3682285809Sscottl ag_portal_info_t *tiExpPortalInfo; 3683285809Sscottl 3684285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: start, nsegs %d error 0x%x\n", 3685285809Sscottl nsegs, error ); 3686285809Sscottl pmcsc = pccb->pmcsc; 3687285809Sscottl 3688285809Sscottl if ( error != tiSuccess ) 3689285809Sscottl { 3690285809Sscottl if (error == 0xAABBCCDD) 3691285809Sscottl { 3692285809Sscottl // do nothing 3693285809Sscottl } 3694285809Sscottl else 3695285809Sscottl { 3696285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: error status 0x%x\n", 3697285809Sscottl error ); 3698285809Sscottl bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap ); 3699285809Sscottl bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap ); 3700285809Sscottl agtiapi_FreeCCB( pmcsc, pccb ); 3701285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 3702285809Sscottl xpt_done( ccb ); 3703285809Sscottl return; 3704285809Sscottl } 3705285809Sscottl } 3706285809Sscottl 3707285809Sscottl if ( nsegs > AGTIAPI_MAX_DMA_SEGS ) 3708285809Sscottl { 3709285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: over the limit. nsegs %d " 3710285809Sscottl "AGTIAPI_MAX_DMA_SEGS %d\n", 3711285809Sscottl nsegs, AGTIAPI_MAX_DMA_SEGS ); 3712285809Sscottl bus_dmamap_unload( pmcsc->buffer_dmat, pccb->CCB_dmamap ); 3713285809Sscottl bus_dmamap_destroy( pmcsc->buffer_dmat, pccb->CCB_dmamap ); 3714285809Sscottl agtiapi_FreeCCB( pmcsc, pccb ); 3715285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 3716285809Sscottl xpt_done( ccb ); 3717285809Sscottl return; 3718285809Sscottl } 3719285809Sscottl 3720285809Sscottl /* 3721285809Sscottl * If assigned pDevHandle is not available 3722285809Sscottl * then there is no need to send it to StartIO() 3723285809Sscottl */ 3724285809Sscottl /* TODO: Add check for deviceType */ 3725285809Sscottl if ( pccb->targetId < 0 || pccb->targetId >= maxTargets ) 3726285809Sscottl { 3727285809Sscottl agtiapi_FreeCCB( pmcsc, pccb ); 3728285809Sscottl ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 3729285809Sscottl xpt_done(ccb); 3730285809Sscottl pccb->ccb = NULL; 3731285809Sscottl return; 3732285809Sscottl } 3733285809Sscottl TID = INDEX( pmcsc, pccb->targetId ); 3734285809Sscottl if ( (TID >= pmcsc->devDiscover) || 3735285809Sscottl !(pccb->devHandle = pmcsc->pDevList[TID].pDevHandle) ) 3736285809Sscottl { 3737285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: not sending ccb devH %p, " 3738285809Sscottl "target %d tid %d/%d " 3739285809Sscottl "card %p ERROR pccb %p\n", 3740285809Sscottl pccb->devHandle, 3741285809Sscottl pccb->targetId, 3742285809Sscottl TID, 3743285809Sscottl pmcsc->devDiscover, 3744285809Sscottl pmcsc, 3745285809Sscottl pccb ); 3746285809Sscottl agtiapi_FreeCCB( pmcsc, pccb ); 3747285809Sscottl ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 3748285809Sscottl xpt_done( ccb ); 3749285809Sscottl pccb->ccb = NULL; 3750285809Sscottl return; 3751285809Sscottl } 3752285809Sscottl /* TODO: add indirect handling */ 3753285809Sscottl /* set the flag correctly based on Indiret SMP request and responce */ 3754285809Sscottl 3755285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, " 3756285809Sscottl "pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n", 3757285809Sscottl pccb->devHandle, 3758285809Sscottl pccb->targetId, TID, 3759285809Sscottl pmcsc->devDiscover, 3760285809Sscottl pmcsc ); 3761285809Sscottl tiExpDevHandle = pccb->devHandle; 3762285809Sscottl tiExpPortalInfo = pmcsc->pDevList[TID].pPortalInfo; 3763285809Sscottl tiExpPortalContext = &tiExpPortalInfo->tiPortalContext; 3764285809Sscottl /* Look for the expander associated with the ses device */ 3765285809Sscottl status = tiINIGetExpander( &pmcsc->tiRoot, 3766285809Sscottl tiExpPortalContext, 3767285809Sscottl pccb->devHandle, 3768285809Sscottl &tiExpDevHandle ); 3769285809Sscottl 3770285809Sscottl if ( status != tiSuccess ) 3771285809Sscottl { 3772285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: Error getting Expander " 3773285809Sscottl "device\n" ); 3774285809Sscottl agtiapi_FreeCCB( pmcsc, pccb ); 3775285809Sscottl ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 3776285809Sscottl xpt_done( ccb ); 3777285809Sscottl pccb->ccb = NULL; 3778285809Sscottl return; 3779285809Sscottl } 3780285809Sscottl 3781285809Sscottl /* this is expander device */ 3782285809Sscottl pccb->devHandle = tiExpDevHandle; 3783285809Sscottl /* put the request in send queue */ 3784285809Sscottl agtiapi_QueueCCB( pmcsc, &pmcsc->smpSendHead, &pmcsc->smpSendTail 3785285809Sscottl AG_CARD_LOCAL_LOCK(&pmcsc->sendSMPLock), pccb ); 3786285809Sscottl 3787285809Sscottl agtiapi_StartSMP( pmcsc ); 3788285809Sscottl 3789285809Sscottl return; 3790285809Sscottl} 3791285809Sscottl 3792285809Sscottl 3793285809Sscottl/****************************************************************************** 3794285809Sscottlagtiapi_Done() 3795285809Sscottl 3796285809SscottlPurpose: 3797285809Sscottl Processing completed ccbs 3798285809SscottlParameters: 3799285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 3800285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 3801285809SscottlReturn: 3802285809SscottlNote: 3803285809Sscottl******************************************************************************/ 3804285809SscottlSTATIC void agtiapi_Done(struct agtiapi_softc *pmcsc, ccb_t *pccb) 3805285809Sscottl{ 3806285809Sscottl pccb_t pccb_curr = pccb; 3807285809Sscottl pccb_t pccb_next; 3808285809Sscottl 3809285809Sscottl tiIniScsiCmnd_t *cmnd; 3810285809Sscottl union ccb * ccb; 3811285809Sscottl 3812285809Sscottl AGTIAPI_IO("agtiapi_Done: start\n"); 3813285809Sscottl while (pccb_curr) 3814285809Sscottl { 3815285809Sscottl /* start from 1st ccb in the chain */ 3816285809Sscottl pccb_next = pccb_curr->pccbNext; 3817285809Sscottl 3818285809Sscottl if (agtiapi_CheckError(pmcsc, pccb_curr) != 0) 3819285809Sscottl { 3820285809Sscottl /* send command back and release the ccb */ 3821285809Sscottl cmnd = &pccb_curr->tiSuperScsiRequest.scsiCmnd; 3822285809Sscottl 3823285809Sscottl if (cmnd->cdb[0] == RECEIVE_DIAGNOSTIC) 3824285809Sscottl { 3825285809Sscottl AGTIAPI_PRINTK("agtiapi_Done: RECEIVE_DIAG pg %d id %d cmnd %p pccb " 3826285809Sscottl "%p\n", cmnd->cdb[2], pccb_curr->targetId, cmnd, 3827285809Sscottl pccb_curr); 3828285809Sscottl } 3829285809Sscottl 3830285809Sscottl CMND_DMA_UNMAP(pmcsc, ccb); 3831285809Sscottl 3832285809Sscottl /* send the request back to the CAM */ 3833285809Sscottl ccb = pccb_curr->ccb; 3834285809Sscottl agtiapi_FreeCCB(pmcsc, pccb_curr); 3835285809Sscottl xpt_done(ccb); 3836285809Sscottl } 3837285809Sscottl pccb_curr = pccb_next; 3838285809Sscottl } 3839285809Sscottl return; 3840285809Sscottl} 3841285809Sscottl 3842285809Sscottl/****************************************************************************** 3843285809Sscottlagtiapi_SMPDone() 3844285809Sscottl 3845285809SscottlPurpose: 3846285809Sscottl Processing completed ccbs 3847285809SscottlParameters: 3848285809Sscottl struct agtiapi_softc *pmcsc (IN) Ponter to HBA data structure 3849285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not 3850285809Sscottl CAM's CCB 3851285809SscottlReturn: 3852285809SscottlNote: 3853285809Sscottl******************************************************************************/ 3854285809SscottlSTATIC void agtiapi_SMPDone(struct agtiapi_softc *pmcsc, ccb_t *pccb) 3855285809Sscottl{ 3856285809Sscottl pccb_t pccb_curr = pccb; 3857285809Sscottl pccb_t pccb_next; 3858285809Sscottl 3859285809Sscottl union ccb * ccb; 3860285809Sscottl 3861285809Sscottl AGTIAPI_PRINTK("agtiapi_SMPDone: start\n"); 3862285809Sscottl 3863285809Sscottl while (pccb_curr) 3864285809Sscottl { 3865285809Sscottl /* start from 1st ccb in the chain */ 3866285809Sscottl pccb_next = pccb_curr->pccbNext; 3867285809Sscottl 3868285809Sscottl if (agtiapi_CheckSMPError(pmcsc, pccb_curr) != 0) 3869285809Sscottl { 3870285809Sscottl CMND_DMA_UNMAP(pmcsc, ccb); 3871285809Sscottl 3872285809Sscottl /* send the request back to the CAM */ 3873285809Sscottl ccb = pccb_curr->ccb; 3874285809Sscottl agtiapi_FreeSMPCCB(pmcsc, pccb_curr); 3875285809Sscottl xpt_done(ccb); 3876285809Sscottl 3877285809Sscottl } 3878285809Sscottl pccb_curr = pccb_next; 3879285809Sscottl } 3880285809Sscottl 3881285809Sscottl AGTIAPI_PRINTK("agtiapi_SMPDone: Done\n"); 3882285809Sscottl return; 3883285809Sscottl} 3884285809Sscottl 3885285809Sscottl/****************************************************************************** 3886285809Sscottlagtiapi_hexdump() 3887285809Sscottl 3888285809SscottlPurpose: 3889285809Sscottl Utility function for dumping in hex 3890285809SscottlParameters: 3891285809Sscottl const char *ptitle (IN) A string to be printed 3892285809Sscottl bit8 *pbuf (IN) A pointer to a buffer to be printed. 3893285809Sscottl int len (IN) The lengther of the buffer 3894285809SscottlReturn: 3895285809SscottlNote: 3896285809Sscottl******************************************************************************/ 3897285809Sscottlvoid agtiapi_hexdump(const char *ptitle, bit8 *pbuf, int len) 3898285809Sscottl{ 3899285809Sscottl int i; 3900285809Sscottl AGTIAPI_PRINTK("%s - hexdump(len=%d):\n", ptitle, (int)len); 3901285809Sscottl if (!pbuf) 3902285809Sscottl { 3903285809Sscottl AGTIAPI_PRINTK("pbuf is NULL\n"); 3904285809Sscottl return; 3905285809Sscottl } 3906285809Sscottl for (i = 0; i < len; ) 3907285809Sscottl { 3908285809Sscottl if (len - i > 4) 3909285809Sscottl { 3910285809Sscottl AGTIAPI_PRINTK( " 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1], 3911285809Sscottl pbuf[i+2], pbuf[i+3] ); 3912285809Sscottl i += 4; 3913285809Sscottl } 3914285809Sscottl else 3915285809Sscottl { 3916285809Sscottl AGTIAPI_PRINTK(" 0x%02x,", pbuf[i]); 3917285809Sscottl i++; 3918285809Sscottl } 3919285809Sscottl } 3920285809Sscottl AGTIAPI_PRINTK("\n"); 3921285809Sscottl} 3922285809Sscottl 3923285809Sscottl 3924285809Sscottl/****************************************************************************** 3925285809Sscottlagtiapi_CheckError() 3926285809Sscottl 3927285809SscottlPurpose: 3928285809Sscottl Processes status pertaining to the ccb -- whether it was 3929285809Sscottl completed successfully, aborted, or error encountered. 3930285809SscottlParameters: 3931285809Sscottl ag_card_t *pCard (IN) Pointer to HBA data structure 3932285809Sscottl ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB 3933285809SscottlReturn: 3934285809Sscottl 0 - the command retry is required 3935285809Sscottl 1 - the command process is completed 3936285809SscottlNote: 3937285809Sscottl 3938285809Sscottl******************************************************************************/ 3939285809SscottlSTATIC U32 agtiapi_CheckError(struct agtiapi_softc *pmcsc, ccb_t *pccb) 3940285809Sscottl{ 3941285809Sscottl ag_device_t *pDevice; 3942285809Sscottl // union ccb * ccb = pccb->ccb; 3943285809Sscottl union ccb * ccb; 3944285809Sscottl int is_error, TID; 3945285809Sscottl 3946285809Sscottl if (pccb == NULL) { 3947285809Sscottl return 0; 3948285809Sscottl } 3949285809Sscottl ccb = pccb->ccb; 3950285809Sscottl AGTIAPI_IO("agtiapi_CheckError: start\n"); 3951285809Sscottl if (ccb == NULL) 3952285809Sscottl { 3953285809Sscottl /* shouldn't be here but just in case we do */ 3954285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckError: CCB orphan = %p ERROR\n", pccb); 3955285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 3956285809Sscottl return 0; 3957285809Sscottl } 3958285809Sscottl 3959285809Sscottl is_error = 1; 3960285809Sscottl pDevice = NULL; 3961285809Sscottl if (pmcsc != NULL && pccb->targetId >= 0 && pccb->targetId < maxTargets) 3962285809Sscottl { 3963285809Sscottl if (pmcsc->pWWNList != NULL) 3964285809Sscottl { 3965285809Sscottl TID = INDEX(pmcsc, pccb->targetId); 3966285809Sscottl if (TID < maxTargets) 3967285809Sscottl { 3968285809Sscottl pDevice = &pmcsc->pDevList[TID]; 3969285809Sscottl if (pDevice != NULL) 3970285809Sscottl { 3971285809Sscottl is_error = 0; 3972285809Sscottl } 3973285809Sscottl } 3974285809Sscottl } 3975285809Sscottl } 3976285809Sscottl if (is_error) 3977285809Sscottl { 3978285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckError: pDevice == NULL\n"); 3979285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 3980285809Sscottl return 0; 3981285809Sscottl } 3982285809Sscottl 3983285809Sscottl /* SCSI status */ 3984285809Sscottl ccb->csio.scsi_status = pccb->scsiStatus; 3985285809Sscottl 3986285809Sscottl if(pDevice->CCBCount > 0){ 3987285809Sscottl atomic_subtract_int(&pDevice->CCBCount,1); 3988285809Sscottl} 3989285809Sscottl AG_LOCAL_LOCK(&pmcsc->freezeLock); 3990285809Sscottl if(pmcsc->freezeSim == agTRUE) 3991285809Sscottl { 3992285809Sscottl pmcsc->freezeSim = agFALSE; 3993285809Sscottl xpt_release_simq(pmcsc->sim, 1); 3994285809Sscottl } 3995285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->freezeLock); 3996285809Sscottl 3997285809Sscottl switch (pccb->ccbStatus) 3998285809Sscottl { 3999285809Sscottl case tiIOSuccess: 4000285809Sscottl AGTIAPI_IO("agtiapi_CheckError: tiIOSuccess pccb %p\n", pccb); 4001285809Sscottl /* CAM status */ 4002285809Sscottl if (pccb->scsiStatus == SCSI_STATUS_OK) 4003285809Sscottl { 4004285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 4005285809Sscottl } 4006285809Sscottl else 4007285809Sscottl if (pccb->scsiStatus == SCSI_TASK_ABORTED) 4008285809Sscottl { 4009285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4010285809Sscottl } 4011285809Sscottl else 4012285809Sscottl { 4013285809Sscottl ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 4014285809Sscottl } 4015285809Sscottl if (ccb->csio.scsi_status == SCSI_CHECK_CONDITION) 4016285809Sscottl { 4017285809Sscottl ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 4018285809Sscottl } 4019285809Sscottl 4020285809Sscottl break; 4021285809Sscottl 4022285809Sscottl case tiIOOverRun: 4023285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckError: tiIOOverRun pccb %p\n", pccb); 4024285809Sscottl /* resid is ignored for this condition */ 4025285809Sscottl ccb->csio.resid = 0; 4026285809Sscottl ccb->ccb_h.status = CAM_DATA_RUN_ERR; 4027285809Sscottl break; 4028285809Sscottl case tiIOUnderRun: 4029285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckError: tiIOUnderRun pccb %p\n", pccb); 4030285809Sscottl ccb->csio.resid = pccb->scsiStatus; 4031285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 4032285809Sscottl ccb->csio.scsi_status = SCSI_STATUS_OK; 4033285809Sscottl break; 4034285809Sscottl 4035285809Sscottl case tiIOFailed: 4036285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n", 4037285809Sscottl pccb, pccb->scsiStatus, pccb->targetId ); 4038285809Sscottl if (pccb->scsiStatus == tiDeviceBusy) 4039285809Sscottl { 4040285809Sscottl AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - tiDetailBusy\n", 4041285809Sscottl pccb ); 4042285809Sscottl ccb->ccb_h.status &= ~CAM_STATUS_MASK; 4043285809Sscottl ccb->ccb_h.status |= CAM_REQUEUE_REQ; 4044285809Sscottl if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) 4045285809Sscottl { 4046285809Sscottl ccb->ccb_h.status |= CAM_DEV_QFRZN; 4047285809Sscottl xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 4048285809Sscottl } 4049285809Sscottl } 4050285809Sscottl else if(pccb->scsiStatus == tiBusy) 4051285809Sscottl { 4052285809Sscottl AG_LOCAL_LOCK(&pmcsc->freezeLock); 4053285809Sscottl if(pmcsc->freezeSim == agFALSE) 4054285809Sscottl { 4055285809Sscottl pmcsc->freezeSim = agTRUE; 4056285809Sscottl xpt_freeze_simq(pmcsc->sim, 1); 4057285809Sscottl } 4058285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->freezeLock); 4059285809Sscottl ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 4060285809Sscottl ccb->ccb_h.status |= CAM_REQUEUE_REQ; 4061285809Sscottl } 4062285809Sscottl else if (pccb->scsiStatus == tiDetailNoLogin) 4063285809Sscottl { 4064285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4065285809Sscottl "tiDetailNoLogin ERROR\n", pccb ); 4066285809Sscottl ccb->ccb_h.status = CAM_DEV_NOT_THERE; 4067285809Sscottl } 4068285809Sscottl else if (pccb->scsiStatus == tiDetailNotValid) 4069285809Sscottl { 4070285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4071285809Sscottl "tiDetailNotValid ERROR\n", pccb ); 4072285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 4073285809Sscottl } 4074285809Sscottl else if (pccb->scsiStatus == tiDetailAbortLogin) 4075285809Sscottl { 4076285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4077285809Sscottl "tiDetailAbortLogin ERROR\n", pccb ); 4078285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4079285809Sscottl } 4080285809Sscottl else if (pccb->scsiStatus == tiDetailAbortReset) 4081285809Sscottl { 4082285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4083285809Sscottl "tiDetailAbortReset ERROR\n", pccb ); 4084285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4085285809Sscottl } 4086285809Sscottl else if (pccb->scsiStatus == tiDetailAborted) 4087285809Sscottl { 4088285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4089285809Sscottl "tiDetailAborted ERROR\n", pccb ); 4090285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4091285809Sscottl } 4092285809Sscottl else if (pccb->scsiStatus == tiDetailOtherError) 4093285809Sscottl { 4094285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4095285809Sscottl "tiDetailOtherError ERROR\n", pccb ); 4096285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4097285809Sscottl } 4098285809Sscottl break; 4099285809Sscottl case tiIODifError: 4100285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n", 4101285809Sscottl pccb, pccb->scsiStatus, pccb->targetId ); 4102285809Sscottl if (pccb->scsiStatus == tiDetailDifAppTagMismatch) 4103285809Sscottl { 4104285809Sscottl AGTIAPI_IO( "agtiapi_CheckError: pccb %p tiIOFailed - " 4105285809Sscottl "tiDetailDifAppTagMismatch\n", pccb ); 4106285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4107285809Sscottl } 4108285809Sscottl else if (pccb->scsiStatus == tiDetailDifRefTagMismatch) 4109285809Sscottl { 4110285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4111285809Sscottl "tiDetailDifRefTagMismatch\n", pccb ); 4112285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4113285809Sscottl } 4114285809Sscottl else if (pccb->scsiStatus == tiDetailDifCrcMismatch) 4115285809Sscottl { 4116285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed - " 4117285809Sscottl "tiDetailDifCrcMismatch\n", pccb ); 4118285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4119285809Sscottl } 4120285809Sscottl break; 4121285809Sscottl#ifdef HIALEAH_ENCRYPTION 4122285809Sscottl case tiIOEncryptError: 4123285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOFailed %d id %d ERROR\n", 4124285809Sscottl pccb, pccb->scsiStatus, pccb->targetId ); 4125285809Sscottl if (pccb->scsiStatus == tiDetailDekKeyCacheMiss) 4126285809Sscottl { 4127285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - " 4128285809Sscottl "tiDetailDekKeyCacheMiss ERROR\n", 4129285809Sscottl __FUNCTION__, pccb ); 4130285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4131285809Sscottl agtiapi_HandleEncryptedIOFailure(pDevice, pccb); 4132285809Sscottl } 4133285809Sscottl else if (pccb->scsiStatus == tiDetailDekIVMismatch) 4134285809Sscottl { 4135285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: %s: pccb %p tiIOFailed - " 4136285809Sscottl "tiDetailDekIVMismatch ERROR\n", __FUNCTION__, pccb ); 4137285809Sscottl ccb->ccb_h.status = CAM_REQ_ABORTED; 4138285809Sscottl agtiapi_HandleEncryptedIOFailure(pDevice, pccb); 4139285809Sscottl } 4140285809Sscottl break; 4141285809Sscottl#endif 4142285809Sscottl default: 4143285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckError: pccb %p tiIOdefault %d id %d ERROR\n", 4144285809Sscottl pccb, pccb->ccbStatus, pccb->targetId ); 4145285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4146285809Sscottl break; 4147285809Sscottl } 4148285809Sscottl 4149285809Sscottl return 1; 4150285809Sscottl} 4151285809Sscottl 4152285809Sscottl 4153285809Sscottl/****************************************************************************** 4154285809Sscottlagtiapi_SMPCheckError() 4155285809Sscottl 4156285809SscottlPurpose: 4157285809Sscottl Processes status pertaining to the ccb -- whether it was 4158285809Sscottl completed successfully, aborted, or error encountered. 4159285809SscottlParameters: 4160285809Sscottl ag_card_t *pCard (IN) Pointer to HBA data structure 4161285809Sscottl ccb_t *pccd (IN) A pointer to the driver's own CCB, not CAM's CCB 4162285809SscottlReturn: 4163285809Sscottl 0 - the command retry is required 4164285809Sscottl 1 - the command process is completed 4165285809SscottlNote: 4166285809Sscottl 4167285809Sscottl******************************************************************************/ 4168285809SscottlSTATIC U32 agtiapi_CheckSMPError( struct agtiapi_softc *pmcsc, ccb_t *pccb ) 4169285809Sscottl{ 4170285809Sscottl union ccb * ccb = pccb->ccb; 4171285809Sscottl 4172285809Sscottl AGTIAPI_PRINTK("agtiapi_CheckSMPError: start\n"); 4173285809Sscottl 4174285809Sscottl if (!ccb) 4175285809Sscottl { 4176285809Sscottl /* shouldn't be here but just in case we do */ 4177285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckSMPError: CCB orphan = %p ERROR\n", 4178285809Sscottl pccb ); 4179285809Sscottl agtiapi_FreeSMPCCB(pmcsc, pccb); 4180285809Sscottl return 0; 4181285809Sscottl } 4182285809Sscottl 4183285809Sscottl switch (pccb->ccbStatus) 4184285809Sscottl { 4185285809Sscottl case tiSMPSuccess: 4186285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPSuccess pccb %p\n", 4187285809Sscottl pccb ); 4188285809Sscottl /* CAM status */ 4189285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 4190285809Sscottl break; 4191285809Sscottl case tiSMPFailed: 4192285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckSMPError: tiSMPFailed pccb %p\n", 4193285809Sscottl pccb ); 4194285809Sscottl /* CAM status */ 4195285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4196285809Sscottl break; 4197285809Sscottl default: 4198285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckSMPError: pccb %p tiSMPdefault %d " 4199285809Sscottl "id %d ERROR\n", 4200285809Sscottl pccb, 4201285809Sscottl pccb->ccbStatus, 4202285809Sscottl pccb->targetId ); 4203285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP_ERR; 4204285809Sscottl break; 4205285809Sscottl } 4206285809Sscottl 4207285809Sscottl 4208285809Sscottl return 1; 4209285809Sscottl 4210285809Sscottl} 4211285809Sscottl 4212285809Sscottl/****************************************************************************** 4213285809Sscottlagtiapi_HandleEncryptedIOFailure(): 4214285809Sscottl 4215285809SscottlPurpose: 4216285809SscottlParameters: 4217285809SscottlReturn: 4218285809SscottlNote: 4219285809Sscottl Currently not used. 4220285809Sscottl******************************************************************************/ 4221285809Sscottlvoid agtiapi_HandleEncryptedIOFailure(ag_device_t *pDev, ccb_t *pccb) 4222285809Sscottl{ 4223285809Sscottl 4224285809Sscottl AGTIAPI_PRINTK("agtiapi_HandleEncryptedIOFailure: start\n"); 4225285809Sscottl return; 4226285809Sscottl} 4227285809Sscottl 4228285809Sscottl/****************************************************************************** 4229285809Sscottlagtiapi_Retry() 4230285809Sscottl 4231285809SscottlPurpose: 4232285809Sscottl Retry a ccb. 4233285809SscottlParameters: 4234285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to the HBA structure 4235285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 4236285809SscottlReturn: 4237285809SscottlNote: 4238285809Sscottl Currently not used. 4239285809Sscottl******************************************************************************/ 4240285809SscottlSTATIC void agtiapi_Retry(struct agtiapi_softc *pmcsc, ccb_t *pccb) 4241285809Sscottl{ 4242285809Sscottl pccb->retryCount++; 4243285809Sscottl pccb->flags = ACTIVE | AGTIAPI_RETRY; 4244285809Sscottl pccb->ccbStatus = 0; 4245285809Sscottl pccb->scsiStatus = 0; 4246285809Sscottl pccb->startTime = ticks; 4247285809Sscottl 4248285809Sscottl AGTIAPI_PRINTK( "agtiapi_Retry: start\n" ); 4249285809Sscottl AGTIAPI_PRINTK( "agtiapi_Retry: ccb %p retry %d flgs x%x\n", pccb, 4250285809Sscottl pccb->retryCount, pccb->flags ); 4251285809Sscottl 4252285809Sscottl agtiapi_QueueCCB(pmcsc, &pmcsc->ccbSendHead, &pmcsc->ccbSendTail 4253285809Sscottl AG_CARD_LOCAL_LOCK(&pmcsc->sendLock), pccb); 4254285809Sscottl return; 4255285809Sscottl} 4256285809Sscottl 4257285809Sscottl 4258285809Sscottl/****************************************************************************** 4259285809Sscottlagtiapi_DumpCCB() 4260285809Sscottl 4261285809SscottlPurpose: 4262285809Sscottl Dump CCB for debuging 4263285809SscottlParameters: 4264285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 4265285809SscottlReturn: 4266285809SscottlNote: 4267285809Sscottl******************************************************************************/ 4268285809SscottlSTATIC void agtiapi_DumpCCB(ccb_t *pccb) 4269285809Sscottl{ 4270285809Sscottl AGTIAPI_PRINTK("agtiapi_DumpCCB: pccb %p, devHandle %p, tid %d, lun %d\n", 4271285809Sscottl pccb, 4272285809Sscottl pccb->devHandle, 4273285809Sscottl pccb->targetId, 4274285809Sscottl pccb->lun); 4275285809Sscottl AGTIAPI_PRINTK("flag 0x%x, add_mode 0x%x, ccbStatus 0x%x, scsiStatus 0x%x\n", 4276285809Sscottl pccb->flags, 4277285809Sscottl pccb->addrMode, 4278285809Sscottl pccb->ccbStatus, 4279285809Sscottl pccb->scsiStatus); 4280285809Sscottl AGTIAPI_PRINTK("scsi comand = 0x%x, numSgElements = %d\n", 4281285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[0], 4282285809Sscottl pccb->numSgElements); 4283285809Sscottl AGTIAPI_PRINTK("dataLen = 0x%x, sens_len = 0x%x\n", 4284285809Sscottl pccb->dataLen, 4285285809Sscottl pccb->senseLen); 4286285809Sscottl AGTIAPI_PRINTK("tiSuperScsiRequest:\n"); 4287285809Sscottl AGTIAPI_PRINTK("scsiCmnd: expDataLength 0x%x, taskAttribute 0x%x\n", 4288285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.expDataLength, 4289285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.taskAttribute); 4290285809Sscottl AGTIAPI_PRINTK("cdb[0] = 0x%x, cdb[1] = 0x%x, cdb[2] = 0x%x, cdb[3] = 0x%x\n", 4291285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[0], 4292285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[1], 4293285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[2], 4294285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[3]); 4295285809Sscottl AGTIAPI_PRINTK("cdb[4] = 0x%x, cdb[5] = 0x%x, cdb[6] = 0x%x, cdb[7] = 0x%x\n", 4296285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[4], 4297285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[5], 4298285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[6], 4299285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[7]); 4300285809Sscottl AGTIAPI_PRINTK( "cdb[8] = 0x%x, cdb[9] = 0x%x, cdb[10] = 0x%x, " 4301285809Sscottl "cdb[11] = 0x%x\n", 4302285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[8], 4303285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[9], 4304285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[10], 4305285809Sscottl pccb->tiSuperScsiRequest.scsiCmnd.cdb[11] ); 4306285809Sscottl AGTIAPI_PRINTK("agSgl1: upper 0x%x, lower 0x%x, len 0x%x, type %d\n", 4307285809Sscottl pccb->tiSuperScsiRequest.agSgl1.upper, 4308285809Sscottl pccb->tiSuperScsiRequest.agSgl1.lower, 4309285809Sscottl pccb->tiSuperScsiRequest.agSgl1.len, 4310285809Sscottl pccb->tiSuperScsiRequest.agSgl1.type); 4311285809Sscottl} 4312285809Sscottl 4313285809Sscottl/****************************************************************************** 4314285809Sscottlagtiapi_eh_HostReset() 4315285809Sscottl 4316285809SscottlPurpose: 4317285809Sscottl A new error handler of Host Reset command. 4318285809SscottlParameters: 4319285809Sscottl scsi_cmnd *cmnd (IN) Pointer to a command to the HBA to be reset 4320285809SscottlReturn: 4321285809Sscottl SUCCESS - success 4322285809Sscottl FAILED - fail 4323285809SscottlNote: 4324285809Sscottl******************************************************************************/ 4325285809Sscottlint agtiapi_eh_HostReset( struct agtiapi_softc *pmcsc, union ccb *cmnd ) 4326285809Sscottl{ 4327285809Sscottl AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n", 4328285809Sscottl cmnd ); 4329285809Sscottl 4330285809Sscottl if( cmnd == NULL ) 4331285809Sscottl { 4332285809Sscottl printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" ); 4333285809Sscottl return tiInvalidHandle; 4334285809Sscottl } 4335285809Sscottl 4336285809Sscottl#ifdef LOGEVENT 4337285809Sscottl agtiapi_LogEvent( pmcsc, 4338285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 4339285809Sscottl 0, 4340285809Sscottl agNULL, 4341285809Sscottl 0, 4342285809Sscottl "agtiapi_eh_HostReset! " ); 4343285809Sscottl#endif 4344285809Sscottl 4345285809Sscottl return agtiapi_DoSoftReset( pmcsc ); 4346285809Sscottl} 4347285809Sscottl 4348285809Sscottl 4349285809Sscottlint agtiapi_eh_DeviceReset( struct agtiapi_softc *pmcsc, union ccb *cmnd ) 4350285809Sscottl{ 4351285809Sscottl AGTIAPI_PRINTK( "agtiapi_eh_HostReset: ccb pointer %p\n", 4352285809Sscottl cmnd ); 4353285809Sscottl 4354285809Sscottl if( cmnd == NULL ) 4355285809Sscottl { 4356285809Sscottl printf( "agtiapi_eh_HostReset: null command, skipping reset.\n" ); 4357285809Sscottl return tiInvalidHandle; 4358285809Sscottl } 4359285809Sscottl return agtiapi_DoSoftReset( pmcsc ); 4360285809Sscottl} 4361285809Sscottl/****************************************************************************** 4362285809Sscottlagtiapi_QueueCCB() 4363285809Sscottl 4364285809SscottlPurpose: 4365285809Sscottl Put ccb in ccb queue at the tail 4366285809SscottlParameters: 4367285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 4368285809Sscottl pccb_t *phead (IN) Double pointer to ccb queue head 4369285809Sscottl pccb_t *ptail (IN) Double pointer to ccb queue tail 4370285809Sscottl ccb_t *pccb (IN) Poiner to a ccb to be queued 4371285809SscottlReturn: 4372285809SscottlNote: 4373285809Sscottl Put the ccb to the tail of queue 4374285809Sscottl******************************************************************************/ 4375285809SscottlSTATIC void agtiapi_QueueCCB( struct agtiapi_softc *pmcsc, 4376285809Sscottl pccb_t *phead, 4377285809Sscottl pccb_t *ptail, 4378285809Sscottl#ifdef AGTIAPI_LOCAL_LOCK 4379285809Sscottl struct mtx *mutex, 4380285809Sscottl#endif 4381285809Sscottl ccb_t *pccb ) 4382285809Sscottl{ 4383285809Sscottl AGTIAPI_IO( "agtiapi_QueueCCB: start\n" ); 4384285809Sscottl AGTIAPI_IO( "agtiapi_QueueCCB: %p to %p\n", pccb, phead ); 4385285809Sscottl if (phead == NULL || ptail == NULL) 4386285809Sscottl { 4387285809Sscottl panic( "agtiapi_QueueCCB: phead %p ptail %p", phead, ptail ); 4388285809Sscottl } 4389285809Sscottl pccb->pccbNext = NULL; 4390285809Sscottl AG_LOCAL_LOCK( mutex ); 4391285809Sscottl if (*phead == NULL) 4392285809Sscottl { 4393285809Sscottl //WARN_ON(*ptail != NULL); /* critical, just get more logs */ 4394285809Sscottl *phead = pccb; 4395285809Sscottl } 4396285809Sscottl else 4397285809Sscottl { 4398285809Sscottl //WARN_ON(*ptail == NULL); /* critical, just get more logs */ 4399285809Sscottl if (*ptail) 4400285809Sscottl (*ptail)->pccbNext = pccb; 4401285809Sscottl } 4402285809Sscottl *ptail = pccb; 4403285809Sscottl AG_LOCAL_UNLOCK( mutex ); 4404285809Sscottl return; 4405285809Sscottl} 4406285809Sscottl 4407285809Sscottl 4408285809Sscottl/****************************************************************************** 4409285809Sscottlagtiapi_QueueCCB() 4410285809Sscottl 4411285809SscottlPurpose: 4412285809Sscottl 4413285809SscottlParameters: 4414285809Sscottl 4415285809Sscottl 4416285809SscottlReturn: 4417285809SscottlNote: 4418285809Sscottl 4419285809Sscottl******************************************************************************/ 4420285809Sscottlstatic int agtiapi_QueueSMP(struct agtiapi_softc *pmcsc, union ccb * ccb) 4421285809Sscottl{ 4422285809Sscottl pccb_t pccb = agNULL; /* call dequeue */ 4423285809Sscottl int status = tiSuccess; 4424285809Sscottl int targetID = xpt_path_target_id(ccb->ccb_h.path); 4425285809Sscottl 4426285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueSMP: start\n"); 4427285809Sscottl 4428285809Sscottl /* get a ccb */ 4429285809Sscottl if ((pccb = agtiapi_GetCCB(pmcsc)) == NULL) 4430285809Sscottl { 4431285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueSMP: GetCCB ERROR\n"); 4432285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 4433285809Sscottl xpt_done(ccb); 4434285809Sscottl return tiBusy; 4435285809Sscottl } 4436285809Sscottl pccb->pmcsc = pmcsc; 4437285809Sscottl 4438285809Sscottl /* initialize Command Control Block (CCB) */ 4439285809Sscottl pccb->targetId = targetID; 4440285809Sscottl pccb->ccb = ccb; /* for struct scsi_cmnd */ 4441285809Sscottl 4442285809Sscottl status = agtiapi_PrepareSMPSGList(pmcsc, pccb); 4443285809Sscottl 4444285809Sscottl if (status != tiSuccess) 4445285809Sscottl { 4446285809Sscottl AGTIAPI_PRINTK("agtiapi_QueueSMP: agtiapi_PrepareSMPSGList failure\n"); 4447285809Sscottl agtiapi_FreeCCB(pmcsc, pccb); 4448285809Sscottl if (status == tiReject) 4449285809Sscottl { 4450285809Sscottl ccb->ccb_h.status = CAM_REQ_INVALID; 4451285809Sscottl } 4452285809Sscottl else 4453285809Sscottl { 4454285809Sscottl ccb->ccb_h.status = CAM_REQ_CMP; 4455285809Sscottl } 4456285809Sscottl xpt_done(ccb); 4457285809Sscottl return tiError; 4458285809Sscottl } 4459285809Sscottl 4460285809Sscottl return status; 4461285809Sscottl} 4462285809Sscottl 4463285809Sscottl/****************************************************************************** 4464285809Sscottlagtiapi_SetLunField() 4465285809Sscottl 4466285809SscottlPurpose: 4467285809Sscottl Set LUN field based on different address mode 4468285809SscottlParameters: 4469285809Sscottl ccb_t *pccb (IN) A pointer to the driver's own CCB, not CAM's CCB 4470285809SscottlReturn: 4471285809SscottlNote: 4472285809Sscottl******************************************************************************/ 4473285809Sscottlvoid agtiapi_SetLunField(ccb_t *pccb) 4474285809Sscottl{ 4475285809Sscottl U08 *pchar; 4476285809Sscottl 4477285809Sscottl pchar = (U08 *)&pccb->tiSuperScsiRequest.scsiCmnd.lun; 4478285809Sscottl 4479285809Sscottl// AGTIAPI_PRINTK("agtiapi_SetLunField: start\n"); 4480285809Sscottl 4481285809Sscottl switch (pccb->addrMode) 4482285809Sscottl { 4483285809Sscottl case AGTIAPI_PERIPHERAL: 4484285809Sscottl *pchar++ = 0; 4485285809Sscottl *pchar = (U08)pccb->lun; 4486285809Sscottl break; 4487285809Sscottl case AGTIAPI_VOLUME_SET: 4488285809Sscottl *pchar++ = (AGTIAPI_VOLUME_SET << AGTIAPI_ADDRMODE_SHIFT) | 4489285809Sscottl (U08)((pccb->lun >> 8) & 0x3F); 4490285809Sscottl *pchar = (U08)pccb->lun; 4491285809Sscottl break; 4492285809Sscottl case AGTIAPI_LUN_ADDR: 4493285809Sscottl *pchar++ = (AGTIAPI_LUN_ADDR << AGTIAPI_ADDRMODE_SHIFT) | 4494285809Sscottl pccb->targetId; 4495285809Sscottl *pchar = (U08)pccb->lun; 4496285809Sscottl break; 4497285809Sscottl } 4498285809Sscottl 4499285809Sscottl 4500285809Sscottl} 4501285809Sscottl 4502285809Sscottl 4503285809Sscottl/***************************************************************************** 4504285809Sscottlagtiapi_FreeCCB() 4505285809Sscottl 4506285809SscottlPurpose: 4507285809Sscottl Free a ccb and put it back to ccbFreeList. 4508285809SscottlParameters: 4509285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 4510285809Sscottl pccb_t pccb (IN) A pointer to the driver's own CCB, not 4511285809Sscottl CAM's CCB 4512285809SscottlReturns: 4513285809SscottlNote: 4514285809Sscottl*****************************************************************************/ 4515285809SscottlSTATIC void agtiapi_FreeCCB(struct agtiapi_softc *pmcsc, pccb_t pccb) 4516285809Sscottl{ 4517285809Sscottl union ccb *ccb = pccb->ccb; 4518285809Sscottl bus_dmasync_op_t op; 4519285809Sscottl 4520285809Sscottl AG_LOCAL_LOCK(&pmcsc->ccbLock); 4521285809Sscottl AGTIAPI_IO( "agtiapi_FreeCCB: start %p\n", pccb ); 4522285809Sscottl 4523285809Sscottl#ifdef AGTIAPI_TEST_EPL 4524285809Sscottl tiEncrypt_t *encrypt; 4525285809Sscottl#endif 4526285809Sscottl 4527285809Sscottl agtiapi_DumpCDB( "agtiapi_FreeCCB", pccb ); 4528285809Sscottl 4529285809Sscottl if (pccb->sgList != agNULL) 4530285809Sscottl { 4531285809Sscottl AGTIAPI_IO( "agtiapi_FreeCCB: pccb->sgList is NOT null\n" ); 4532285809Sscottl } 4533285809Sscottl else 4534285809Sscottl { 4535285809Sscottl AGTIAPI_PRINTK( "agtiapi_FreeCCB: pccb->sgList is null\n" ); 4536285809Sscottl } 4537285809Sscottl 4538285809Sscottl /* set data transfer direction */ 4539285809Sscottl if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 4540285809Sscottl { 4541285809Sscottl op = BUS_DMASYNC_POSTWRITE; 4542285809Sscottl } 4543285809Sscottl else 4544285809Sscottl { 4545285809Sscottl op = BUS_DMASYNC_POSTREAD; 4546285809Sscottl } 4547285809Sscottl 4548285809Sscottl if (pccb->numSgElements == 0) 4549285809Sscottl { 4550285809Sscottl // do nothing 4551285809Sscottl AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements zero\n" ); 4552285809Sscottl } 4553285809Sscottl else if (pccb->numSgElements == 1) 4554285809Sscottl { 4555285809Sscottl AGTIAPI_IO( "agtiapi_FreeCCB: numSgElements is one\n" ); 4556285809Sscottl //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD 4557285809Sscottl bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op); 4558285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 4559285809Sscottl } 4560285809Sscottl else 4561285809Sscottl { 4562285809Sscottl AGTIAPI_PRINTK( "agtiapi_FreeCCB: numSgElements 2 or higher \n" ); 4563285809Sscottl //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD 4564285809Sscottl bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op); 4565285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 4566285809Sscottl } 4567285809Sscottl 4568285809Sscottl#ifdef AGTIAPI_TEST_DPL 4569285809Sscottl if (pccb->tiSuperScsiRequest.Dif.enableDIFPerLA == TRUE) { 4570285809Sscottl if(pccb->dplPtr) 4571285809Sscottl memset( (char *) pccb->dplPtr, 4572285809Sscottl 0, 4573285809Sscottl MAX_DPL_REGIONS * sizeof(dplaRegion_t) ); 4574285809Sscottl pccb->tiSuperScsiRequest.Dif.enableDIFPerLA = FALSE; 4575285809Sscottl pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrLo = 0; 4576285809Sscottl pccb->tiSuperScsiRequest.Dif.DIFPerLAAddrHi = 0; 4577285809Sscottl } 4578285809Sscottl#endif 4579285809Sscottl 4580285809Sscottl#ifdef AGTIAPI_TEST_EPL 4581285809Sscottl encrypt = &pccb->tiSuperScsiRequest.Encrypt; 4582285809Sscottl if (encrypt->enableEncryptionPerLA == TRUE) { 4583285809Sscottl encrypt->enableEncryptionPerLA = FALSE; 4584285809Sscottl encrypt->EncryptionPerLAAddrLo = 0; 4585285809Sscottl encrypt->EncryptionPerLAAddrHi = 0; 4586285809Sscottl } 4587285809Sscottl#endif 4588285809Sscottl 4589285809Sscottl#ifdef ENABLE_SATA_DIF 4590285809Sscottl if (pccb->holePtr && pccb->dmaHandleHole) 4591285809Sscottl pci_free_consistent( pmcsc->pCardInfo->pPCIDev, 4592285809Sscottl 512, 4593285809Sscottl pccb->holePtr, 4594285809Sscottl pccb->dmaHandleHole ); 4595285809Sscottl pccb->holePtr = 0; 4596285809Sscottl pccb->dmaHandleHole = 0; 4597285809Sscottl#endif 4598285809Sscottl 4599285809Sscottl pccb->dataLen = 0; 4600285809Sscottl pccb->retryCount = 0; 4601285809Sscottl pccb->ccbStatus = 0; 4602285809Sscottl pccb->scsiStatus = 0; 4603285809Sscottl pccb->startTime = 0; 4604285809Sscottl pccb->dmaHandle = 0; 4605285809Sscottl pccb->numSgElements = 0; 4606285809Sscottl pccb->tiIORequest.tdData = 0; 4607285809Sscottl memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN); 4608285809Sscottl 4609285809Sscottl#ifdef HIALEAH_ENCRYPTION 4610285809Sscottl if (pmcsc->encrypt) 4611285809Sscottl agtiapi_CleanupEncryptedIO(pmcsc, pccb); 4612285809Sscottl#endif 4613285809Sscottl 4614285809Sscottl pccb->flags = 0; 4615285809Sscottl pccb->ccb = NULL; 4616285809Sscottl pccb->pccbIO = NULL; 4617285809Sscottl pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList; 4618285809Sscottl pmcsc->ccbFreeList = (caddr_t *)pccb; 4619285809Sscottl 4620285809Sscottl pmcsc->activeCCB--; 4621285809Sscottl 4622285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->ccbLock); 4623285809Sscottl return; 4624285809Sscottl} 4625285809Sscottl 4626285809Sscottl 4627285809Sscottl/****************************************************************************** 4628285809Sscottlagtiapi_FlushCCBs() 4629285809Sscottl 4630285809SscottlPurpose: 4631285809Sscottl Flush all in processed ccbs. 4632285809SscottlParameters: 4633285809Sscottl ag_card_t *pCard (IN) Pointer to HBA data structure 4634285809Sscottl U32 flag (IN) Flag to call back 4635285809SscottlReturn: 4636285809SscottlNote: 4637285809Sscottl******************************************************************************/ 4638285809SscottlSTATIC void agtiapi_FlushCCBs( struct agtiapi_softc *pCard, U32 flag ) 4639285809Sscottl{ 4640285809Sscottl union ccb *ccb; 4641285809Sscottl ccb_t *pccb; 4642285809Sscottl 4643285809Sscottl AGTIAPI_PRINTK( "agtiapi_FlushCCBs: enter \n" ); 4644285809Sscottl for( pccb = (pccb_t)pCard->ccbChainList; 4645285809Sscottl pccb != NULL; 4646285809Sscottl pccb = pccb->pccbChainNext ) { 4647285809Sscottl if( pccb->flags == 0 ) 4648285809Sscottl { 4649285809Sscottl // printf( "agtiapi_FlushCCBs: nothing, continue \n" ); 4650285809Sscottl continue; 4651285809Sscottl } 4652285809Sscottl ccb = pccb->ccb; 4653285809Sscottl if ( pccb->flags & ( TASK_MANAGEMENT | DEV_RESET ) ) 4654285809Sscottl { 4655285809Sscottl AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeTMCCB \n" ); 4656285809Sscottl agtiapi_FreeTMCCB( pCard, pccb ); 4657285809Sscottl } 4658285809Sscottl else 4659285809Sscottl { 4660285809Sscottl if ( pccb->flags & TAG_SMP ) 4661285809Sscottl { 4662285809Sscottl AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeSMPCCB \n" ); 4663285809Sscottl agtiapi_FreeSMPCCB( pCard, pccb ); 4664285809Sscottl } 4665285809Sscottl else 4666285809Sscottl { 4667285809Sscottl AGTIAPI_PRINTK( "agtiapi_FlushCCBs: agtiapi_FreeCCB \n" ); 4668285809Sscottl agtiapi_FreeCCB( pCard, pccb ); 4669285809Sscottl } 4670285809Sscottl if( ccb ) { 4671285809Sscottl CMND_DMA_UNMAP( pCard, ccb ); 4672285809Sscottl if( flag == AGTIAPI_CALLBACK ) { 4673285809Sscottl ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 4674285809Sscottl xpt_done( ccb ); 4675285809Sscottl } 4676285809Sscottl } 4677285809Sscottl } 4678285809Sscottl } 4679285809Sscottl} 4680285809Sscottl 4681285809Sscottl/***************************************************************************** 4682285809Sscottlagtiapi_FreeSMPCCB() 4683285809Sscottl 4684285809SscottlPurpose: 4685285809Sscottl Free a ccb and put it back to ccbFreeList. 4686285809SscottlParameters: 4687285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 4688285809Sscottl pccb_t pccb (IN) A pointer to the driver's own CCB, not 4689285809Sscottl CAM's CCB 4690285809SscottlReturns: 4691285809SscottlNote: 4692285809Sscottl*****************************************************************************/ 4693285809SscottlSTATIC void agtiapi_FreeSMPCCB(struct agtiapi_softc *pmcsc, pccb_t pccb) 4694285809Sscottl{ 4695285809Sscottl union ccb *ccb = pccb->ccb; 4696285809Sscottl bus_dmasync_op_t op; 4697285809Sscottl 4698285809Sscottl AG_LOCAL_LOCK(&pmcsc->ccbLock); 4699285809Sscottl AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: start %p\n", pccb); 4700285809Sscottl 4701285809Sscottl /* set data transfer direction */ 4702285809Sscottl if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 4703285809Sscottl { 4704285809Sscottl op = BUS_DMASYNC_POSTWRITE; 4705285809Sscottl } 4706285809Sscottl else 4707285809Sscottl { 4708285809Sscottl op = BUS_DMASYNC_POSTREAD; 4709285809Sscottl } 4710285809Sscottl 4711285809Sscottl if (pccb->numSgElements == 0) 4712285809Sscottl { 4713285809Sscottl // do nothing 4714285809Sscottl AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 0\n"); 4715285809Sscottl } 4716285809Sscottl else if (pccb->numSgElements == 1) 4717285809Sscottl { 4718285809Sscottl AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 1\n"); 4719285809Sscottl //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD 4720285809Sscottl bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op); 4721285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 4722285809Sscottl } 4723285809Sscottl else 4724285809Sscottl { 4725285809Sscottl AGTIAPI_PRINTK("agtiapi_FreeSMPCCB: numSgElements 2 or higher \n"); 4726285809Sscottl //op is either BUS_DMASYNC_POSTWRITE or BUS_DMASYNC_POSTREAD 4727285809Sscottl bus_dmamap_sync(pmcsc->buffer_dmat, pccb->CCB_dmamap, op); 4728285809Sscottl bus_dmamap_unload(pmcsc->buffer_dmat, pccb->CCB_dmamap); 4729285809Sscottl } 4730285809Sscottl 4731285809Sscottl /*dma api cleanning*/ 4732285809Sscottl pccb->dataLen = 0; 4733285809Sscottl pccb->retryCount = 0; 4734285809Sscottl pccb->ccbStatus = 0; 4735285809Sscottl pccb->startTime = 0; 4736285809Sscottl pccb->dmaHandle = 0; 4737285809Sscottl pccb->numSgElements = 0; 4738285809Sscottl pccb->tiIORequest.tdData = 0; 4739285809Sscottl memset((void *)&pccb->tiSMPFrame, 0, AGSMP_INIT_XCHG_LEN); 4740285809Sscottl 4741285809Sscottl pccb->flags = 0; 4742285809Sscottl pccb->ccb = NULL; 4743285809Sscottl pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList; 4744285809Sscottl pmcsc->ccbFreeList = (caddr_t *)pccb; 4745285809Sscottl 4746285809Sscottl pmcsc->activeCCB--; 4747285809Sscottl 4748285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->ccbLock); 4749285809Sscottl return; 4750285809Sscottl 4751285809Sscottl} 4752285809Sscottl 4753285809Sscottl/***************************************************************************** 4754285809Sscottlagtiapi_FreeTMCCB() 4755285809Sscottl 4756285809SscottlPurpose: 4757285809Sscottl Free a ccb and put it back to ccbFreeList. 4758285809SscottlParameters: 4759285809Sscottl struct agtiapi_softc *pmcsc (IN) Pointer to HBA data structure 4760285809Sscottl pccb_t pccb (IN) A pointer to the driver's own CCB, not 4761285809Sscottl CAM's CCB 4762285809SscottlReturns: 4763285809SscottlNote: 4764285809Sscottl*****************************************************************************/ 4765285809SscottlSTATIC void agtiapi_FreeTMCCB(struct agtiapi_softc *pmcsc, pccb_t pccb) 4766285809Sscottl{ 4767285809Sscottl AG_LOCAL_LOCK(&pmcsc->ccbLock); 4768285809Sscottl AGTIAPI_PRINTK("agtiapi_FreeTMCCB: start %p\n", pccb); 4769285809Sscottl pccb->dataLen = 0; 4770285809Sscottl pccb->retryCount = 0; 4771285809Sscottl pccb->ccbStatus = 0; 4772285809Sscottl pccb->scsiStatus = 0; 4773285809Sscottl pccb->startTime = 0; 4774285809Sscottl pccb->dmaHandle = 0; 4775285809Sscottl pccb->numSgElements = 0; 4776285809Sscottl pccb->tiIORequest.tdData = 0; 4777285809Sscottl memset((void *)&pccb->tiSuperScsiRequest, 0, AGSCSI_INIT_XCHG_LEN); 4778285809Sscottl pccb->flags = 0; 4779285809Sscottl pccb->ccb = NULL; 4780285809Sscottl pccb->pccbIO = NULL; 4781285809Sscottl pccb->pccbNext = (pccb_t)pmcsc->ccbFreeList; 4782285809Sscottl pmcsc->ccbFreeList = (caddr_t *)pccb; 4783285809Sscottl pmcsc->activeCCB--; 4784285809Sscottl AG_LOCAL_UNLOCK(&pmcsc->ccbLock); 4785285809Sscottl return; 4786285809Sscottl} 4787285809Sscottl/****************************************************************************** 4788285809Sscottlagtiapi_CheckAllVectors(): 4789285809Sscottl 4790285809SscottlPurpose: 4791285809SscottlParameters: 4792285809SscottlReturn: 4793285809SscottlNote: 4794285809Sscottl Currently, not used. 4795285809Sscottl******************************************************************************/ 4796285809Sscottlvoid agtiapi_CheckAllVectors( struct agtiapi_softc *pCard, bit32 context ) 4797285809Sscottl{ 4798285809Sscottl#ifdef SPC_MSIX_INTR 4799285809Sscottl if (!agtiapi_intx_mode) 4800285809Sscottl { 4801285809Sscottl int i; 4802285809Sscottl 4803285809Sscottl for (i = 0; i < pCard->pCardInfo->maxInterruptVectors; i++) 4804285809Sscottl if (tiCOMInterruptHandler(&pCard->tiRoot, i) == agTRUE) 4805285809Sscottl tiCOMDelayedInterruptHandler(&pCard->tiRoot, i, 100, context); 4806285809Sscottl } 4807285809Sscottl else 4808285809Sscottl if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE) 4809285809Sscottl tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context); 4810285809Sscottl#else 4811285809Sscottl if (tiCOMInterruptHandler(&pCard->tiRoot, 0) == agTRUE) 4812285809Sscottl tiCOMDelayedInterruptHandler(&pCard->tiRoot, 0, 100, context); 4813285809Sscottl#endif 4814285809Sscottl 4815285809Sscottl} 4816285809Sscottl 4817285809Sscottl 4818285809Sscottl/****************************************************************************** 4819285809Sscottlagtiapi_CheckCB() 4820285809Sscottl 4821285809SscottlPurpose: 4822285809Sscottl Check call back function returned event for process completion 4823285809SscottlParameters: 4824285809Sscottl struct agtiapi_softc *pCard Pointer to card data structure 4825285809Sscottl U32 milisec (IN) Waiting time for expected event 4826285809Sscottl U32 flag (IN) Flag of the event to check 4827285809Sscottl U32 *pStatus (IN) Pointer to status of the card or port to check 4828285809SscottlReturn: 4829285809Sscottl AGTIAPI_SUCCESS - event comes as expected 4830285809Sscottl AGTIAPI_FAIL - event not coming 4831285809SscottlNote: 4832285809Sscottl Currently, not used 4833285809Sscottl******************************************************************************/ 4834285809SscottlagBOOLEAN agtiapi_CheckCB( struct agtiapi_softc *pCard, 4835285809Sscottl U32 milisec, 4836285809Sscottl U32 flag, 4837285809Sscottl volatile U32 *pStatus ) 4838285809Sscottl{ 4839285809Sscottl U32 msecsPerTick = pCard->pCardInfo->tiRscInfo.tiInitiatorResource. 4840285809Sscottl initiatorOption.usecsPerTick / 1000; 4841285809Sscottl S32 i = milisec/msecsPerTick; 4842285809Sscottl AG_GLOBAL_ARG( _flags ); 4843285809Sscottl 4844285809Sscottl AGTIAPI_PRINTK( "agtiapi_CheckCB: start\n" ); 4845285809Sscottl AGTIAPI_FLOW( "agtiapi_CheckCB: start\n" ); 4846285809Sscottl 4847285809Sscottl if( i <= 0 ) 4848285809Sscottl i = 1; 4849285809Sscottl while (i > 0) 4850285809Sscottl { 4851285809Sscottl if (*pStatus & TASK_MANAGEMENT) 4852285809Sscottl { 4853285809Sscottl if (*pStatus & AGTIAPI_CB_DONE) 4854285809Sscottl { 4855285809Sscottl if( flag == 0 || *pStatus & flag ) 4856285809Sscottl return AGTIAPI_SUCCESS; 4857285809Sscottl else 4858285809Sscottl return AGTIAPI_FAIL; 4859285809Sscottl } 4860285809Sscottl } 4861285809Sscottl else if (pCard->flags & AGTIAPI_CB_DONE) 4862285809Sscottl { 4863285809Sscottl if( flag == 0 || *pStatus & flag ) 4864285809Sscottl return AGTIAPI_SUCCESS; 4865285809Sscottl else 4866285809Sscottl return AGTIAPI_FAIL; 4867285809Sscottl } 4868285809Sscottl 4869285809Sscottl agtiapi_DelayMSec( msecsPerTick ); 4870285809Sscottl 4871285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, _flags ); 4872285809Sscottl tiCOMTimerTick( &pCard->tiRoot ); 4873285809Sscottl 4874285809Sscottl agtiapi_CheckAllVectors( pCard, tiNonInterruptContext ); 4875285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, _flags ); 4876285809Sscottl 4877285809Sscottl i--; 4878285809Sscottl } 4879285809Sscottl 4880285809Sscottl if( *pStatus & TASK_MANAGEMENT ) 4881285809Sscottl *pStatus |= TASK_TIMEOUT; 4882285809Sscottl 4883285809Sscottl return AGTIAPI_FAIL; 4884285809Sscottl} 4885285809Sscottl 4886285809Sscottl 4887285809Sscottl/****************************************************************************** 4888285809Sscottlagtiapi_DiscoverTgt() 4889285809Sscottl 4890285809SscottlPurpose: 4891285809Sscottl Discover available devices 4892285809SscottlParameters: 4893285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure 4894285809SscottlReturn: 4895285809SscottlNote: 4896285809Sscottl******************************************************************************/ 4897285809SscottlSTATIC void agtiapi_DiscoverTgt(struct agtiapi_softc *pCard) 4898285809Sscottl{ 4899285809Sscottl 4900285809Sscottl ag_portal_data_t *pPortalData; 4901285809Sscottl U32 count; 4902285809Sscottl 4903285809Sscottl AGTIAPI_PRINTK("agtiapi_DiscoverTgt: start\n"); 4904285809Sscottl AGTIAPI_FLOW("agtiapi_DiscoverTgt\n"); 4905285809Sscottl AGTIAPI_INIT("agtiapi_DiscoverTgt\n"); 4906285809Sscottl 4907285809Sscottl pPortalData = pCard->pPortalData; 4908285809Sscottl for (count = 0; count < pCard->portCount; count++, pPortalData++) 4909285809Sscottl { 4910285809Sscottl pCard->flags &= ~AGTIAPI_CB_DONE; 4911285809Sscottl if (!(PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)) 4912285809Sscottl { 4913285809Sscottl if (pCard->flags & AGTIAPI_INIT_TIME) 4914285809Sscottl { 4915285809Sscottl if (agtiapi_CheckCB(pCard, 5000, AGTIAPI_PORT_DISC_READY, 4916285809Sscottl &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL) 4917285809Sscottl { 4918285809Sscottl AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Port %p / %d not ready for " 4919285809Sscottl "discovery\n", 4920285809Sscottl pPortalData, count ); 4921285809Sscottl /* 4922285809Sscottl * There is no need to spend time on discovering device 4923285809Sscottl * if port is not ready to do so. 4924285809Sscottl */ 4925285809Sscottl continue; 4926285809Sscottl } 4927285809Sscottl } 4928285809Sscottl else 4929285809Sscottl continue; 4930285809Sscottl } 4931285809Sscottl 4932285809Sscottl AGTIAPI_FLOW( "agtiapi_DiscoverTgt: Portal %p DiscoverTargets starts\n", 4933285809Sscottl pPortalData ); 4934285809Sscottl AGTIAPI_INIT_DELAY(1000); 4935285809Sscottl 4936285809Sscottl pCard->flags &= ~AGTIAPI_CB_DONE; 4937285809Sscottl if (tiINIDiscoverTargets(&pCard->tiRoot, 4938285809Sscottl &pPortalData->portalInfo.tiPortalContext, 4939285809Sscottl FORCE_PERSISTENT_ASSIGN_MASK) 4940285809Sscottl != tiSuccess) 4941285809Sscottl AGTIAPI_PRINTK("agtiapi_DiscoverTgt: tiINIDiscoverTargets ERROR\n"); 4942285809Sscottl 4943285809Sscottl /* 4944285809Sscottl * Should wait till discovery completion to start 4945285809Sscottl * next portal. However, lower layer have issue on 4946285809Sscottl * multi-portal case under Linux. 4947285809Sscottl */ 4948285809Sscottl } 4949285809Sscottl 4950285809Sscottl pPortalData = pCard->pPortalData; 4951285809Sscottl for (count = 0; count < pCard->portCount; count++, pPortalData++) 4952285809Sscottl { 4953285809Sscottl if ((PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY)) 4954285809Sscottl { 4955285809Sscottl if (agtiapi_CheckCB(pCard, 20000, AGTIAPI_DISC_COMPLETE, 4956285809Sscottl &PORTAL_STATUS(pPortalData)) == AGTIAPI_FAIL) 4957285809Sscottl { 4958285809Sscottl if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE)) 4959285809Sscottl AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover complete, " 4960285809Sscottl "status 0x%x\n", 4961285809Sscottl pPortalData, 4962285809Sscottl PORTAL_STATUS(pPortalData) ); 4963285809Sscottl else 4964285809Sscottl AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %p discover is not " 4965285809Sscottl "completed, status 0x%x\n", 4966285809Sscottl pPortalData, PORTAL_STATUS(pPortalData) ); 4967285809Sscottl continue; 4968285809Sscottl } 4969285809Sscottl AGTIAPI_PRINTK( "agtiapi_DiscoverTgt: Portal %d discover target " 4970285809Sscottl "success\n", 4971285809Sscottl count ); 4972285809Sscottl } 4973285809Sscottl } 4974285809Sscottl 4975285809Sscottl /* 4976285809Sscottl * Calling to get device handle should be done per portal based 4977285809Sscottl * and better right after discovery is done. However, lower iscsi 4978285809Sscottl * layer may not returns discovery complete in correct sequence or we 4979285809Sscottl * ran out time. We get device handle for all portals together 4980285809Sscottl * after discovery is done or timed out. 4981285809Sscottl */ 4982285809Sscottl pPortalData = pCard->pPortalData; 4983285809Sscottl for (count = 0; count < pCard->portCount; count++, pPortalData++) 4984285809Sscottl { 4985285809Sscottl /* 4986285809Sscottl * We try to get device handle no matter 4987285809Sscottl * if discovery is completed or not. 4988285809Sscottl */ 4989285809Sscottl if (PORTAL_STATUS(pPortalData) & AGTIAPI_PORT_DISC_READY) 4990285809Sscottl { 4991285809Sscottl U32 i; 4992285809Sscottl 4993285809Sscottl for (i = 0; i < AGTIAPI_GET_DEV_MAX; i++) 4994285809Sscottl { 4995285809Sscottl if (agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 0, 0) != 0) 4996285809Sscottl break; 4997285809Sscottl agtiapi_DelayMSec(AGTIAPI_EXTRA_DELAY); 4998285809Sscottl } 4999285809Sscottl 5000285809Sscottl if ((PORTAL_STATUS(pPortalData) & AGTIAPI_DISC_COMPLETE) || 5001285809Sscottl (pCard->tgtCount > 0)) 5002285809Sscottl PORTAL_STATUS(pPortalData) |= ( AGTIAPI_DISC_DONE | 5003285809Sscottl AGTIAPI_PORT_LINK_UP ); 5004285809Sscottl } 5005285809Sscottl } 5006285809Sscottl 5007285809Sscottl return; 5008285809Sscottl 5009285809Sscottl} 5010285809Sscottl 5011285809Sscottl 5012285809Sscottl 5013285809Sscottl/****************************************************************************** 5014285809Sscottlagtiapi_PrepCCBs() 5015285809Sscottl 5016285809SscottlPurpose: 5017285809Sscottl Prepares CCB including DMA map. 5018285809SscottlParameters: 5019285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure 5020285809Sscottl ccb_hdr_t *hdr (IN) Pointer to the CCB header 5021285809Sscottl U32 size (IN) size 5022285809Sscottl U32 max_ccb (IN) count 5023285809Sscottl 5024285809SscottlReturn: 5025285809SscottlNote: 5026285809Sscottl******************************************************************************/ 5027285809SscottlSTATIC void agtiapi_PrepCCBs( struct agtiapi_softc *pCard, 5028285809Sscottl ccb_hdr_t *hdr, 5029285809Sscottl U32 size, 5030285809Sscottl U32 max_ccb, 5031285809Sscottl int tid ) 5032285809Sscottl{ 5033285809Sscottl 5034285809Sscottl int i; 5035285809Sscottl U32 hdr_sz, ccb_sz; 5036285809Sscottl ccb_t *pccb = 0; 5037285809Sscottl int offset = 0; 5038285809Sscottl int nsegs = 0; 5039285809Sscottl int sgl_sz = 0; 5040285809Sscottl 5041285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepCCBs: start\n"); 5042285809Sscottl offset = tid * AGTIAPI_CCB_PER_DEVICE; 5043285809Sscottl nsegs = AGTIAPI_NSEGS; 5044285809Sscottl sgl_sz = sizeof(tiSgl_t) * nsegs; 5045285809Sscottl AGTIAPI_PRINTK( "agtiapi_PrepCCBs: tid %d offset %d nsegs %d sizeof(tiSgl_t) " 5046285809Sscottl "%lu, max_ccb %d\n", 5047285809Sscottl tid, 5048285809Sscottl offset, 5049285809Sscottl nsegs, 5050285809Sscottl sizeof(tiSgl_t), 5051285809Sscottl max_ccb ); 5052285809Sscottl 5053285809Sscottl ccb_sz = (AGTIAPI_CCB_SIZE + cache_line_size() - 1) & ~(cache_line_size() -1); 5054285809Sscottl hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1); 5055285809Sscottl 5056285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepCCBs: after cache line\n"); 5057285809Sscottl 5058285809Sscottl memset((void *)hdr, 0, size); 5059285809Sscottl hdr->next = pCard->ccbAllocList; 5060285809Sscottl pCard->ccbAllocList = hdr; 5061285809Sscottl 5062285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepCCBs: after memset\n"); 5063285809Sscottl 5064285809Sscottl pccb = (ccb_t*) ((char*)hdr + hdr_sz); 5065285809Sscottl 5066285809Sscottl for (i = 0; i < max_ccb; i++, pccb = (ccb_t*)((char*)pccb + ccb_sz)) 5067285809Sscottl { 5068285809Sscottl pccb->tiIORequest.osData = (void *)pccb; 5069285809Sscottl 5070285809Sscottl /* 5071285809Sscottl * Initially put all the ccbs on the free list 5072285809Sscottl * in addition to chainlist. 5073285809Sscottl * ccbChainList is a list of all available ccbs 5074285809Sscottl * (free/active everything) 5075285809Sscottl */ 5076285809Sscottl pccb->pccbChainNext = (pccb_t)pCard->ccbChainList; 5077285809Sscottl pccb->pccbNext = (pccb_t)pCard->ccbFreeList; 5078285809Sscottl 5079285809Sscottl pCard->ccbChainList = (caddr_t *)pccb; 5080285809Sscottl pCard->ccbFreeList = (caddr_t *)pccb; 5081285809Sscottl pCard->ccbTotal++; 5082285809Sscottl 5083285809Sscottl#ifdef AGTIAPI_ALIGN_CHECK 5084285809Sscottl if (&pccb & 0x63) 5085285809Sscottl AGTIAPI_PRINTK("pccb = %p\n", pccb); 5086285809Sscottl if (pccb->devHandle & 0x63) 5087285809Sscottl AGTIAPI_PRINTK("devHandle addr = %p\n", &pccb->devHandle); 5088285809Sscottl if (&pccb->lun & 0x63) 5089285809Sscottl AGTIAPI_PRINTK("lun addr = %p\n", &pccb->lun); 5090285809Sscottl if (&pccb->targetId & 0x63) 5091285809Sscottl AGTIAPI_PRINTK("tig addr = %p\n", &pccb->targetId); 5092285809Sscottl if (&pccb->ccbStatus & 0x63) 5093285809Sscottl AGTIAPI_PRINTK("ccbStatus addr = %p\n", &pccb->ccbStatus); 5094285809Sscottl if (&pccb->scsiStatus & 0x63) 5095285809Sscottl AGTIAPI_PRINTK("scsiStatus addr = %p\n", &pccb->scsiStatus); 5096285809Sscottl if (&pccb->dataLen & 0x63) 5097285809Sscottl AGTIAPI_PRINTK("dataLen addr = %p\n", &pccb->dataLen); 5098285809Sscottl if (&pccb->senseLen & 0x63) 5099285809Sscottl AGTIAPI_PRINTK("senseLen addr = %p\n", &pccb->senseLen); 5100285809Sscottl if (&pccb->numSgElements & 0x63) 5101285809Sscottl AGTIAPI_PRINTK("numSgElements addr = %p\n", &pccb->numSgElements); 5102285809Sscottl if (&pccb->retryCount & 0x63) 5103285809Sscottl AGTIAPI_PRINTK("retry cnt addr = %p\n", &pccb->retryCount); 5104285809Sscottl if (&pccb->flags & 0x63) 5105285809Sscottl AGTIAPI_PRINTK("flag addr = %p\n", &pccb->flags); 5106285809Sscottl if (&pccb->pSenseData & 0x63) 5107285809Sscottl AGTIAPI_PRINTK("senseData addr = %p\n", &pccb->pSenseData); 5108285809Sscottl if (&pccb->sgList[0] & 0x63) 5109285809Sscottl AGTIAPI_PRINTK("SgList 0 = %p\n", &pccb->sgList[0]); 5110285809Sscottl if (&pccb->pccbNext & 0x63) 5111285809Sscottl AGTIAPI_PRINTK("ccb next = %p\n", &pccb->pccbNext); 5112285809Sscottl if (&pccb->pccbChainNext & 0x63) 5113285809Sscottl AGTIAPI_PRINTK("ccbChainNext = %p\n", &pccb->pccbChainNext); 5114285809Sscottl if (&pccb->cmd & 0x63) 5115285809Sscottl AGTIAPI_PRINTK("command = %p\n", &pccb->cmd); 5116285809Sscottl if( &pccb->startTime & 0x63 ) 5117285809Sscottl AGTIAPI_PRINTK( "startTime = %p\n", &pccb->startTime ); 5118285809Sscottl if (&pccb->tiIORequest & 0x63) 5119285809Sscottl AGTIAPI_PRINTK("tiIOReq addr = %p\n", &pccb->tiIORequest); 5120285809Sscottl if (&pccb->tdIOReqBody & 0x63) 5121285809Sscottl AGTIAPI_PRINTK("tdIORequestBody addr = %p\n", &pccb->tdIOReqBody); 5122285809Sscottl if (&pccb->tiSuperScsiRequest & 0x63) 5123285809Sscottl AGTIAPI_PRINTK( "InitiatorExchange addr = %p\n", 5124285809Sscottl &pccb->tiSuperScsiRequest ); 5125285809Sscottl#endif 5126285809Sscottl if ( bus_dmamap_create( pCard->buffer_dmat, 0, &pccb->CCB_dmamap ) != 5127285809Sscottl tiSuccess) 5128285809Sscottl { 5129285809Sscottl AGTIAPI_PRINTK("agtiapi_PrepCCBs: can't create dma\n"); 5130285809Sscottl return; 5131285809Sscottl } 5132285809Sscottl /* assigns tiSgl_t memory to pccb */ 5133285809Sscottl pccb->sgList = (void*)((U64)pCard->tisgl_mem + ((i + offset) * sgl_sz)); 5134285809Sscottl pccb->tisgl_busaddr = pCard->tisgl_busaddr + ((i + offset) * sgl_sz); 5135285809Sscottl pccb->ccb = NULL; 5136285809Sscottl pccb->pccbIO = NULL; 5137285809Sscottl pccb->startTime = 0; 5138285809Sscottl } 5139285809Sscottl 5140285809Sscottl#ifdef AGTIAPI_ALIGN_CHECK 5141285809Sscottl AGTIAPI_PRINTK("ccb size = %d / %d\n", sizeof(ccb_t), ccb_sz); 5142285809Sscottl#endif 5143285809Sscottl return; 5144285809Sscottl} 5145285809Sscottl 5146285809Sscottl/****************************************************************************** 5147285809Sscottlagtiapi_InitCCBs() 5148285809Sscottl 5149285809SscottlPurpose: 5150285809Sscottl Create and initialize per card based CCB pool. 5151285809SscottlParameters: 5152285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure 5153285809Sscottl int tgtCount (IN) Count 5154285809SscottlReturn: 5155285809Sscottl Total number of ccb allocated 5156285809SscottlNote: 5157285809Sscottl******************************************************************************/ 5158285809SscottlSTATIC U32 agtiapi_InitCCBs(struct agtiapi_softc *pCard, int tgtCount, int tid) 5159285809Sscottl{ 5160285809Sscottl 5161285809Sscottl U32 max_ccb, size, ccb_sz, hdr_sz; 5162285809Sscottl int no_allocs = 0, i; 5163285809Sscottl ccb_hdr_t *hdr = 0; 5164285809Sscottl 5165285809Sscottl AGTIAPI_PRINTK("agtiapi_InitCCBs: start\n"); 5166285809Sscottl AGTIAPI_PRINTK("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid); 5167285809Sscottl AGTIAPI_FLOW("agtiapi_InitCCBs: tgtCount %d tid %d\n", tgtCount, tid); 5168285809Sscottl 5169285809Sscottl#ifndef HOTPLUG_SUPPORT 5170285809Sscottl if (pCard->tgtCount > AGSA_MAX_INBOUND_Q) 5171285809Sscottl return 1; 5172285809Sscottl#else 5173285809Sscottl if (tgtCount > AGSA_MAX_INBOUND_Q) 5174285809Sscottl tgtCount = AGSA_MAX_INBOUND_Q; 5175285809Sscottl#endif 5176285809Sscottl 5177285809Sscottl max_ccb = tgtCount * AGTIAPI_CCB_PER_DEVICE;// / 4; // TBR 5178285809Sscottl ccb_sz = ( (AGTIAPI_CCB_SIZE + cache_line_size() - 1) & 5179285809Sscottl ~(cache_line_size() -1) ); 5180285809Sscottl hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1); 5181285809Sscottl size = ccb_sz * max_ccb + hdr_sz; 5182285809Sscottl 5183285809Sscottl for (i = 0; i < (1 << no_allocs); i++) 5184285809Sscottl { 5185285809Sscottl hdr = (ccb_hdr_t*)malloc( size, M_PMC_MCCB, M_NOWAIT ); 5186285809Sscottl if( !hdr ) 5187285809Sscottl { 5188285809Sscottl panic( "agtiapi_InitCCBs: bug!!!\n" ); 5189285809Sscottl } 5190285809Sscottl else 5191285809Sscottl { 5192285809Sscottl agtiapi_PrepCCBs( pCard, hdr, size, max_ccb, tid ); 5193285809Sscottl } 5194285809Sscottl } 5195285809Sscottl 5196285809Sscottl return 1; 5197285809Sscottl 5198285809Sscottl} 5199285809Sscottl 5200285809Sscottl 5201285809Sscottl#ifdef LINUX_PERBI_SUPPORT 5202285809Sscottl/****************************************************************************** 5203285809Sscottlagtiapi_GetWWNMappings() 5204285809Sscottl 5205285809SscottlPurpose: 5206285809Sscottl Get the mappings from target IDs to WWNs, if any. 5207285809Sscottl Store them in the WWN_list array, indexed by target ID. 5208285809Sscottl Leave the devListIndex field blank; this will be filled-in later. 5209285809SscottlParameters: 5210285809Sscottl ag_card_t *pCard (IN) Pointer to HBA data structure 5211285809Sscottl ag_mapping_t *pMapList (IN) Pointer to mapped device list 5212285809SscottlReturn: 5213285809SscottlNote: The boot command line parameters are used to load the 5214285809Sscottl mapping information, which is contained in the system 5215285809Sscottl configuration file. 5216285809Sscottl******************************************************************************/ 5217285809SscottlSTATIC void agtiapi_GetWWNMappings( struct agtiapi_softc *pCard, 5218285809Sscottl ag_mapping_t *pMapList ) 5219285809Sscottl{ 5220285809Sscottl int devDisc; 5221285809Sscottl int lIdx = 0; 5222285809Sscottl ag_tgt_map_t *pWWNList; 5223285809Sscottl ag_slr_map_t *pSLRList; 5224285809Sscottl ag_device_t *pDevList; 5225285809Sscottl 5226285809Sscottl if( !pCard ) 5227285809Sscottl panic( "agtiapi_GetWWNMappings: no pCard \n" ); 5228285809Sscottl 5229285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetWWNMappings: start\n" ); 5230285809Sscottl 5231285809Sscottl pWWNList = pCard->pWWNList; 5232285809Sscottl pSLRList = pCard->pSLRList; 5233285809Sscottl pDevList = pCard->pDevList; 5234285809Sscottl pCard->numTgtHardMapped = 0; 5235285809Sscottl devDisc = pCard->devDiscover; 5236285809Sscottl 5237285809Sscottl pWWNList[devDisc-1].devListIndex = maxTargets; 5238285809Sscottl pSLRList[devDisc-1].localeNameLen = -2; 5239285809Sscottl pSLRList[devDisc-1].remoteNameLen = -2; 5240285809Sscottl pDevList[devDisc-1].targetId = maxTargets; 5241285809Sscottl 5242285809Sscottl /* 5243285809Sscottl * Get the mappings from holding area which contains 5244285809Sscottl * the input of the system file and store them 5245285809Sscottl * in the WWN_list array, indexed by target ID. 5246285809Sscottl */ 5247285809Sscottl for ( lIdx = 0; lIdx < devDisc - 1; lIdx++) { 5248285809Sscottl pWWNList[lIdx].flags = 0; 5249285809Sscottl pWWNList[lIdx].devListIndex = maxTargets; 5250285809Sscottl pSLRList[lIdx].localeNameLen = -1; 5251285809Sscottl pSLRList[lIdx].remoteNameLen = -1; 5252285809Sscottl } 5253285809Sscottl 5254285809Sscottl // this is where we would propagate values fed to pMapList 5255285809Sscottl 5256285809Sscottl} /* agtiapi_GetWWNMappings */ 5257285809Sscottl 5258285809Sscottl#endif 5259285809Sscottl 5260285809Sscottl 5261285809Sscottl/****************************************************************************** 5262285809Sscottlagtiapi_FindWWNListNext() 5263285809SscottlPurpose: 5264285809Sscottl finds first available new (unused) wwn list entry 5265285809Sscottl 5266285809SscottlParameters: 5267285809Sscottl ag_tgt_map_t *pWWNList Pointer to head of wwn list 5268285809Sscottl int lstMax Number of entries in WWNList 5269285809SscottlReturn: 5270285809Sscottl index into WWNList indicating available entry space; 5271285809Sscottl if available entry space is not found, return negative value 5272285809Sscottl******************************************************************************/ 5273285809SscottlSTATIC int agtiapi_FindWWNListNext( ag_tgt_map_t *pWWNList, int lstMax ) 5274285809Sscottl{ 5275285809Sscottl int lLstIdx; 5276285809Sscottl 5277285809Sscottl for ( lLstIdx = 0; lLstIdx < lstMax; lLstIdx++ ) 5278285809Sscottl { 5279285809Sscottl if ( pWWNList[lLstIdx].devListIndex == lstMax && 5280285809Sscottl pWWNList[lLstIdx].targetLen == 0 ) 5281285809Sscottl { 5282285809Sscottl AGTIAPI_PRINTK( "agtiapi_FindWWNListNext: %d %d %d %d v. %d\n", 5283285809Sscottl lLstIdx, 5284285809Sscottl pWWNList[lLstIdx].devListIndex, 5285285809Sscottl pWWNList[lLstIdx].targetLen, 5286285809Sscottl pWWNList[lLstIdx].portId, 5287285809Sscottl lstMax ); 5288285809Sscottl return lLstIdx; 5289285809Sscottl } 5290285809Sscottl } 5291285809Sscottl return -1; 5292285809Sscottl} 5293285809Sscottl 5294285809Sscottl 5295285809Sscottl/****************************************************************************** 5296285809Sscottlagtiapi_GetDevHandle() 5297285809Sscottl 5298285809SscottlPurpose: 5299285809Sscottl Get device handle. Handles will be placed in the 5300285809Sscottl devlist array with same order as TargetList provided and 5301285809Sscottl will be mapped to a scsi target id and registered to OS later. 5302285809SscottlParameters: 5303285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure 5304285809Sscottl ag_portal_info_t *pPortalInfo (IN) Pointer to the portal data structure 5305285809Sscottl U32 eType (IN) Port event 5306285809Sscottl U32 eStatus (IN) Port event status 5307285809SscottlReturn: 5308285809Sscottl Number of device handle slot present 5309285809SscottlNote: 5310285809Sscottl The sequence of device handle will match the sequence of taregt list 5311285809Sscottl******************************************************************************/ 5312285809SscottlSTATIC U32 agtiapi_GetDevHandle( struct agtiapi_softc *pCard, 5313285809Sscottl ag_portal_info_t *pPortalInfo, 5314285809Sscottl U32 eType, 5315285809Sscottl U32 eStatus ) 5316285809Sscottl{ 5317285809Sscottl ag_device_t *pDevice; 5318285809Sscottl // tiDeviceHandle_t *agDev[pCard->devDiscover]; 5319285809Sscottl tiDeviceHandle_t **agDev; 5320285809Sscottl int devIdx, szdv, devTotal, cmpsetRtn; 5321285809Sscottl int lDevIndex = 0, lRunScanFlag = FALSE; 5322285809Sscottl int *lDevFlags; 5323285809Sscottl tiPortInfo_t portInfT; 5324285809Sscottl ag_device_t lTmpDevice; 5325285809Sscottl ag_tgt_map_t *pWWNList; 5326285809Sscottl ag_slr_map_t *pSLRList; 5327285809Sscottl bit32 lReadRm; 5328285809Sscottl bit16 lReadCt; 5329285809Sscottl 5330285809Sscottl 5331285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: start\n" ); 5332285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: pCard->devDiscover %d / tgtCt %d\n", 5333285809Sscottl pCard->devDiscover, pCard->tgtCount ); 5334285809Sscottl AGTIAPI_FLOW( "agtiapi_GetDevHandle: portalInfo %p\n", pPortalInfo ); 5335285809Sscottl AGTIAPI_INIT_DELAY( 1000 ); 5336285809Sscottl 5337285809Sscottl agDev = (tiDeviceHandle_t **) malloc( sizeof(tiDeviceHandle_t *) * pCard->devDiscover, 5338285809Sscottl M_PMC_MDEV, M_ZERO | M_NOWAIT); 5339285809Sscottl if (agDev == NULL) 5340285809Sscottl { 5341285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc agDev[]\n" ); 5342285809Sscottl return 0; 5343285809Sscottl } 5344285809Sscottl 5345285809Sscottl lDevFlags = (int *) malloc( sizeof(int) * pCard->devDiscover, 5346285809Sscottl M_PMC_MFLG, M_ZERO | M_NOWAIT ); 5347285809Sscottl if (lDevFlags == NULL) 5348285809Sscottl { 5349285809Sscottl free((caddr_t)agDev, M_PMC_MDEV); 5350285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: failed to alloc lDevFlags[]\n" ); 5351285809Sscottl return 0; 5352285809Sscottl } 5353285809Sscottl 5354285809Sscottl pWWNList = pCard->pWWNList; 5355285809Sscottl pSLRList = pCard->pSLRList; 5356285809Sscottl 5357285809Sscottl memset( (void *)agDev, 0, sizeof(void *) * pCard->devDiscover ); 5358285809Sscottl memset( lDevFlags, 0, sizeof(int) * pCard->devDiscover ); 5359285809Sscottl 5360285809Sscottl // get device handles 5361285809Sscottl devTotal = tiINIGetDeviceHandles( &pCard->tiRoot, 5362285809Sscottl &pPortalInfo->tiPortalContext, 5363285809Sscottl (tiDeviceHandle_t **)agDev, 5364285809Sscottl pCard->devDiscover ); 5365285809Sscottl 5366285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: portalInfo %p port id %d event %u " 5367285809Sscottl "status %u card %p pCard->devDiscover %d devTotal %d " 5368285809Sscottl "pPortalInfo->devTotal %d pPortalInfo->devPrev %d " 5369285809Sscottl "AGTIAPI_INIT_TIME %x\n", 5370285809Sscottl pPortalInfo, pPortalInfo->portID, eType, eStatus, pCard, 5371285809Sscottl pCard->devDiscover, devTotal, pPortalInfo->devTotal, 5372285809Sscottl pPortalInfo->devPrev, 5373285809Sscottl pCard->flags & AGTIAPI_INIT_TIME ); 5374285809Sscottl 5375285809Sscottl // reset devTotal from any previous runs of this 5376285809Sscottl pPortalInfo->devPrev = devTotal; 5377285809Sscottl pPortalInfo->devTotal = devTotal; 5378285809Sscottl 5379285809Sscottl AG_LIST_LOCK( &pCard->devListLock ); 5380285809Sscottl 5381285809Sscottl if ( tiCOMGetPortInfo( &pCard->tiRoot, 5382285809Sscottl &pPortalInfo->tiPortalContext, 5383285809Sscottl &portInfT ) 5384285809Sscottl != tiSuccess) 5385285809Sscottl { 5386285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: tiCOMGetPortInfo did not succeed. \n" ); 5387285809Sscottl } 5388285809Sscottl 5389285809Sscottl 5390285809Sscottl szdv = sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] ); 5391285809Sscottl if (szdv > pCard->devDiscover) 5392285809Sscottl { 5393285809Sscottl szdv = pCard->devDiscover; 5394285809Sscottl } 5395285809Sscottl 5396285809Sscottl // reconstructing dev list via comparison of wwn 5397285809Sscottl 5398285809Sscottl for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ ) 5399285809Sscottl { 5400285809Sscottl if ( agDev[devIdx] != 0 ) 5401285809Sscottl { 5402285809Sscottl // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: agDev %d not NULL %p\n", 5403285809Sscottl // devIdx, agDev[devIdx] ); 5404285809Sscottl 5405285809Sscottl // pack temp device structure for tiINIGetDeviceInfo call 5406285809Sscottl pDevice = &lTmpDevice; 5407285809Sscottl pDevice->devType = DIRECT_DEVICE; 5408285809Sscottl pDevice->pCard = (void *)pCard; 5409285809Sscottl pDevice->flags = ACTIVE; 5410285809Sscottl pDevice->pPortalInfo = pPortalInfo; 5411285809Sscottl pDevice->pDevHandle = agDev[devIdx]; 5412285809Sscottl pDevice->qbusy = agFALSE; 5413285809Sscottl 5414285809Sscottl //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: idx %d / %d : %p \n", 5415285809Sscottl // devIdx, pCard->devDiscover, agDev[devIdx] ); 5416285809Sscottl 5417285809Sscottl tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], 5418285809Sscottl &pDevice->devInfo ); 5419285809Sscottl 5420285809Sscottl //AGTIAPI_PRINTK( "agtiapi_GetDevHandle: wwn sizes %ld %d/%d ", 5421285809Sscottl // sizeof(pDevice->targetName), 5422285809Sscottl // pDevice->devInfo.osAddress1, 5423285809Sscottl // pDevice->devInfo.osAddress2 ); 5424285809Sscottl 5425285809Sscottl wwncpy( pDevice ); 5426285809Sscottl wwnprintk( (unsigned char*)pDevice->targetName, pDevice->targetLen ); 5427285809Sscottl 5428285809Sscottl for ( lDevIndex = 0; lDevIndex < szdv; lDevIndex++ ) // match w/ wwn list 5429285809Sscottl { 5430285809Sscottl if ( (pCard->pDevList[lDevIndex].portalId == pPortalInfo->portID) && 5431285809Sscottl pDevice->targetLen > 0 && 5432285809Sscottl portInfT.localNameLen > 0 && 5433285809Sscottl portInfT.remoteNameLen > 0 && 5434285809Sscottl pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen > 0 && 5435285809Sscottl pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen > 0 && 5436285809Sscottl ( portInfT.localNameLen == 5437285809Sscottl pSLRList[pWWNList[lDevIndex].sasLrIdx].localeNameLen ) && 5438285809Sscottl ( portInfT.remoteNameLen == 5439285809Sscottl pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteNameLen ) && 5440285809Sscottl memcmp( pWWNList[lDevIndex].targetName, pDevice->targetName, 5441285809Sscottl pDevice->targetLen ) == 0 && 5442285809Sscottl memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].localeName, 5443285809Sscottl portInfT.localName, 5444285809Sscottl portInfT.localNameLen ) == 0 && 5445285809Sscottl memcmp( pSLRList[pWWNList[lDevIndex].sasLrIdx].remoteName, 5446285809Sscottl portInfT.remoteName, 5447285809Sscottl portInfT.remoteNameLen ) == 0 ) 5448285809Sscottl { 5449285809Sscottl AGTIAPI_PRINTK( " pWWNList match @ %d/%d/%d \n", 5450285809Sscottl lDevIndex, devIdx, pPortalInfo->portID ); 5451285809Sscottl 5452285809Sscottl if ( (pCard->pDevList[lDevIndex].targetId == lDevIndex) && 5453285809Sscottl ( pPortalInfo->pDevList[lDevIndex] == 5454285809Sscottl &pCard->pDevList[lDevIndex] ) ) // active 5455285809Sscottl { 5456285809Sscottl 5457285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: dev in use %d of %d/%d\n", 5458285809Sscottl lDevIndex, devTotal, pPortalInfo->portID ); 5459285809Sscottl lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev handle 5460285809Sscottl lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used 5461285809Sscottl lReadRm = atomic_readandclear_32( &pWWNList[lDevIndex].devRemoved ); 5462285809Sscottl if ( lReadRm ) // cleared timeout, now remove count for timer 5463285809Sscottl { 5464285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: clear timer count for" 5465285809Sscottl " %d of %d\n", 5466285809Sscottl lDevIndex, pPortalInfo->portID ); 5467285809Sscottl atomic_subtract_16( &pCard->rmChkCt, 1 ); 5468285809Sscottl lReadCt = atomic_load_acq_16( &pCard->rmChkCt ); 5469285809Sscottl if ( 0 == lReadCt ) 5470285809Sscottl { 5471285809Sscottl callout_stop( &pCard->devRmTimer ); 5472285809Sscottl } 5473285809Sscottl } 5474285809Sscottl break; 5475285809Sscottl } 5476285809Sscottl 5477285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: goin fresh on %d of %d/%d\n", 5478285809Sscottl lDevIndex, // reactivate now 5479285809Sscottl devTotal, pPortalInfo->portID ); 5480285809Sscottl 5481285809Sscottl // pDevice going fresh 5482285809Sscottl lRunScanFlag = TRUE; // scan and clear outstanding removals 5483285809Sscottl 5484285809Sscottl // pCard->tgtCount++; ## 5485285809Sscottl pDevice->targetId = lDevIndex; 5486285809Sscottl pDevice->portalId = pPortalInfo->portID; 5487285809Sscottl 5488285809Sscottl memcpy ( &pCard->pDevList[lDevIndex], pDevice, sizeof(lTmpDevice) ); 5489285809Sscottl agDev[devIdx]->osData = (void *)&pCard->pDevList[lDevIndex]; 5490285809Sscottl if ( agtiapi_InitCCBs( pCard, 1, pDevice->targetId ) == 0 ) 5491285809Sscottl { 5492285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: InitCCB " 5493285809Sscottl "tgtCnt %d ERROR!\n", pCard->tgtCount ); 5494285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 5495285809Sscottl free((caddr_t)lDevFlags, M_PMC_MFLG); 5496285809Sscottl free((caddr_t)agDev, M_PMC_MDEV); 5497285809Sscottl return 0; 5498285809Sscottl } 5499285809Sscottl pPortalInfo->pDevList[lDevIndex] = &pCard->pDevList[lDevIndex]; // (ag_device_t *) 5500285809Sscottl if ( 0 == lDevFlags[devIdx] ) 5501285809Sscottl { 5502285809Sscottl pPortalInfo->devTotal++; 5503285809Sscottl lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used 5504285809Sscottl lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used 5505285809Sscottl } 5506285809Sscottl else 5507285809Sscottl { 5508285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: odd dev handle " 5509285809Sscottl "status inspect %d %d %d\n", 5510285809Sscottl lDevFlags[devIdx], devIdx, lDevIndex ); 5511285809Sscottl pPortalInfo->devTotal++; 5512285809Sscottl lDevFlags[devIdx] |= DPMC_LEANFLAG_AGDEVUSED; // agDev used 5513285809Sscottl lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // pDevice used 5514285809Sscottl 5515285809Sscottl } 5516285809Sscottl break; 5517285809Sscottl } 5518285809Sscottl } 5519285809Sscottl // end: match this wwn with previous wwn list 5520285809Sscottl 5521285809Sscottl // we have an agDev entry, but no pWWNList target for it 5522285809Sscottl if ( !(lDevFlags[devIdx] & DPMC_LEANFLAG_AGDEVUSED) ) 5523285809Sscottl { // flag dev handle not accounted for yet 5524285809Sscottl lDevFlags[devIdx] |= DPMC_LEANFLAG_NOWWNLIST; 5525285809Sscottl // later, get an empty pDevice and map this agDev. 5526285809Sscottl // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: devIdx %d flags 0x%x, %d\n", 5527285809Sscottl // devIdx, lDevFlags[devIdx], (lDevFlags[devIdx] & 8) ); 5528285809Sscottl } 5529285809Sscottl } 5530285809Sscottl else 5531285809Sscottl { 5532285809Sscottl lDevFlags[devIdx] |= DPMC_LEANFLAG_NOAGDEVYT; // known empty agDev handle 5533285809Sscottl } 5534285809Sscottl } 5535285809Sscottl 5536285809Sscottl // AGTIAPI_PRINTK( "agtiapi_GetDevHandle: all WWN all the time, " 5537285809Sscottl // "devLstIdx/flags/(WWNL)portId ... \n" ); 5538285809Sscottl // review device list for further action needed 5539285809Sscottl for ( devIdx = 0; devIdx < pCard->devDiscover; devIdx++ ) 5540285809Sscottl { 5541285809Sscottl if ( lDevFlags[devIdx] & DPMC_LEANFLAG_NOWWNLIST ) // new target, register 5542285809Sscottl { 5543285809Sscottl int lNextDyad; // find next available dyad entry 5544285809Sscottl 5545285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: register new target, " 5546285809Sscottl "devIdx %d -- %d \n", devIdx, pCard->devDiscover ); 5547285809Sscottl lRunScanFlag = TRUE; // scan and clear outstanding removals 5548285809Sscottl for ( lNextDyad = 0; lNextDyad < pCard->devDiscover; lNextDyad++ ) 5549285809Sscottl { 5550285809Sscottl if ( pSLRList[lNextDyad].localeNameLen < 0 && 5551285809Sscottl pSLRList[lNextDyad].remoteNameLen < 0 ) 5552285809Sscottl break; 5553285809Sscottl } 5554285809Sscottl 5555285809Sscottl if ( lNextDyad == pCard->devDiscover ) 5556285809Sscottl { 5557285809Sscottl printf( "agtiapi_GetDevHandle: failed to find available SAS LR\n" ); 5558285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 5559285809Sscottl free( (caddr_t)lDevFlags, M_PMC_MFLG ); 5560285809Sscottl free( (caddr_t)agDev, M_PMC_MDEV ); 5561285809Sscottl return 0; 5562285809Sscottl } 5563285809Sscottl // index of new entry 5564285809Sscottl lDevIndex = agtiapi_FindWWNListNext( pWWNList, pCard->devDiscover ); 5565285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: listIdx new target %d of %d/%d\n", 5566285809Sscottl lDevIndex, devTotal, pPortalInfo->portID ); 5567285809Sscottl if ( 0 > lDevIndex ) 5568285809Sscottl { 5569285809Sscottl printf( "agtiapi_GetDevHandle: WARNING -- WWNList exhausted.\n" ); 5570285809Sscottl continue; 5571285809Sscottl } 5572285809Sscottl 5573285809Sscottl pDevice = &pCard->pDevList[lDevIndex]; 5574285809Sscottl 5575285809Sscottl tiINIGetDeviceInfo( &pCard->tiRoot, agDev[devIdx], &pDevice->devInfo ); 5576285809Sscottl wwncpy( pDevice ); 5577285809Sscottl agtiapi_InitCCBs( pCard, 1, lDevIndex ); 5578285809Sscottl 5579285809Sscottl pDevice->pCard = (void *)pCard; 5580285809Sscottl pDevice->devType = DIRECT_DEVICE; 5581285809Sscottl 5582285809Sscottl // begin to populate new WWNList entry 5583285809Sscottl memcpy( pWWNList[lDevIndex].targetName, pDevice->targetName, pDevice->targetLen ); 5584285809Sscottl pWWNList[lDevIndex].targetLen = pDevice->targetLen; 5585285809Sscottl 5586285809Sscottl pWWNList[lDevIndex].flags = SOFT_MAPPED; 5587285809Sscottl pWWNList[lDevIndex].portId = pPortalInfo->portID; 5588285809Sscottl pWWNList[lDevIndex].devListIndex = lDevIndex; 5589285809Sscottl pWWNList[lDevIndex].sasLrIdx = lNextDyad; 5590285809Sscottl 5591285809Sscottl pSLRList[lNextDyad].localeNameLen = portInfT.localNameLen; 5592285809Sscottl pSLRList[lNextDyad].remoteNameLen = portInfT.remoteNameLen; 5593285809Sscottl memcpy( pSLRList[lNextDyad].localeName, portInfT.localName, portInfT.localNameLen ); 5594285809Sscottl memcpy( pSLRList[lNextDyad].remoteName, portInfT.remoteName, portInfT.remoteNameLen ); 5595285809Sscottl // end of populating new WWNList entry 5596285809Sscottl 5597285809Sscottl pDevice->targetId = lDevIndex; 5598285809Sscottl 5599285809Sscottl pDevice->flags = ACTIVE; 5600285809Sscottl pDevice->CCBCount = 0; 5601285809Sscottl pDevice->pDevHandle = agDev[devIdx]; 5602285809Sscottl agDev[devIdx]->osData = (void*)pDevice; 5603285809Sscottl 5604285809Sscottl pDevice->pPortalInfo = pPortalInfo; 5605285809Sscottl pDevice->portalId = pPortalInfo->portID; 5606285809Sscottl pPortalInfo->pDevList[lDevIndex] = (void*)pDevice; 5607285809Sscottl lDevFlags[lDevIndex] |= DPMC_LEANFLAG_PDEVSUSED; // mark pDevice slot used 5608285809Sscottl } 5609285809Sscottl 5610285809Sscottl if ( (pCard->pDevList[devIdx].portalId == pPortalInfo->portID) && 5611285809Sscottl !(lDevFlags[devIdx] & DPMC_LEANFLAG_PDEVSUSED) ) // pDevice not used 5612285809Sscottl { 5613285809Sscottl pDevice = &pCard->pDevList[devIdx]; 5614285809Sscottl //pDevice->flags &= ~ACTIVE; 5615285809Sscottl if ( ( pDevice->pDevHandle != NULL || 5616285809Sscottl pPortalInfo->pDevList[devIdx] != NULL ) ) 5617285809Sscottl { 5618285809Sscottl atomic_add_16( &pCard->rmChkCt, 1 ); // show count of lost device 5619285809Sscottl 5620285809Sscottl if (FALSE == lRunScanFlag) 5621285809Sscottl { 5622285809Sscottl 5623285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: targ dropped out %d of %d/%d\n", 5624285809Sscottl devIdx, devTotal, pPortalInfo->portID ); 5625285809Sscottl // if ( 0 == pWWNList[devIdx].devRemoved ) '.devRemoved = 5; 5626285809Sscottl cmpsetRtn = atomic_cmpset_32( &pWWNList[devIdx].devRemoved, 0, 5 ); 5627285809Sscottl if ( 0 == cmpsetRtn ) 5628285809Sscottl { 5629285809Sscottl AGTIAPI_PRINTK( "agtiapi_GetDevHandle: target %d timer already set\n", 5630285809Sscottl devIdx ); 5631285809Sscottl } 5632285809Sscottl else 5633285809Sscottl { 5634285809Sscottl callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard ); 5635285809Sscottl } 5636285809Sscottl } 5637285809Sscottl // else ... scan coming soon enough anyway, ignore timer for dropout 5638285809Sscottl } 5639285809Sscottl } 5640285809Sscottl } // end of for ( devIdx = 0; ... 5641285809Sscottl 5642285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 5643285809Sscottl 5644285809Sscottl free((caddr_t)lDevFlags, M_PMC_MFLG); 5645285809Sscottl free((caddr_t)agDev, M_PMC_MDEV); 5646285809Sscottl 5647285809Sscottl if ( TRUE == lRunScanFlag ) 5648285809Sscottl agtiapi_clrRmScan( pCard ); 5649285809Sscottl 5650285809Sscottl return devTotal; 5651285809Sscottl} // end agtiapi_GetDevHandle 5652285809Sscottl 5653285809Sscottl/****************************************************************************** 5654285809Sscottlagtiapi_scan() 5655285809Sscottl 5656285809SscottlPurpose: 5657285809Sscottl Triggers CAM's scan 5658285809SscottlParameters: 5659285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the HBA data structure 5660285809SscottlReturn: 5661285809SscottlNote: 5662285809Sscottl******************************************************************************/ 5663285809Sscottlstatic void agtiapi_scan(struct agtiapi_softc *pmcsc) 5664285809Sscottl{ 5665285809Sscottl union ccb *ccb; 5666285809Sscottl int bus, tid, lun, card_no; 5667285809Sscottl static int num=0; 5668285809Sscottl 5669285809Sscottl AGTIAPI_PRINTK("agtiapi_scan: start cardNO %d \n", pmcsc->cardNo); 5670285809Sscottl 5671285809Sscottl bus = cam_sim_path(pmcsc->sim); 5672285809Sscottl 5673285809Sscottl tid = CAM_TARGET_WILDCARD; 5674285809Sscottl lun = CAM_LUN_WILDCARD; 5675285809Sscottl 5676285809Sscottl mtx_lock(&(pmcsc->pCardInfo->pmIOLock)); 5677285809Sscottl ccb = xpt_alloc_ccb_nowait(); 5678285809Sscottl if (ccb == agNULL) 5679285809Sscottl { 5680285809Sscottl mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 5681285809Sscottl return; 5682285809Sscottl } 5683285809Sscottl if (xpt_create_path(&ccb->ccb_h.path, agNULL, bus, tid, 5684285809Sscottl CAM_LUN_WILDCARD) != CAM_REQ_CMP) 5685285809Sscottl { 5686285809Sscottl mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 5687285809Sscottl xpt_free_ccb(ccb); 5688285809Sscottl return; 5689285809Sscottl } 5690285809Sscottl 5691285809Sscottl mtx_unlock(&(pmcsc->pCardInfo->pmIOLock)); 5692285809Sscottl pmcsc->dev_scan = agTRUE; 5693285809Sscottl xpt_rescan(ccb); 5694285809Sscottl return; 5695285809Sscottl} 5696285809Sscottl 5697285809Sscottl/****************************************************************************** 5698285809Sscottlagtiapi_DeQueueCCB() 5699285809Sscottl 5700285809SscottlPurpose: 5701285809Sscottl Remove a ccb from a queue 5702285809SscottlParameters: 5703285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to the card structure 5704285809Sscottl pccb_t *phead (IN) Pointer to a head of ccb queue 5705285809Sscottl ccb_t *pccd (IN) Pointer to the ccb to be processed 5706285809SscottlReturn: 5707285809Sscottl AGTIAPI_SUCCESS - the ccb is removed from queue 5708285809Sscottl AGTIAPI_FAIL - the ccb is not found from queue 5709285809SscottlNote: 5710285809Sscottl******************************************************************************/ 5711285809SscottlSTATIC agBOOLEAN 5712285809Sscottlagtiapi_DeQueueCCB(struct agtiapi_softc *pCard, pccb_t *phead, pccb_t *ptail, 5713285809Sscottl#ifdef AGTIAPI_LOCAL_LOCK 5714285809Sscottl struct mtx *lock, 5715285809Sscottl#endif 5716285809Sscottl ccb_t *pccb) 5717285809Sscottl{ 5718285809Sscottl ccb_t *pccb_curr; 5719285809Sscottl U32 status = AGTIAPI_FAIL; 5720285809Sscottl 5721285809Sscottl AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead); 5722285809Sscottl 5723285809Sscottl if (pccb == NULL || *phead == NULL) 5724285809Sscottl { 5725285809Sscottl return AGTIAPI_FAIL; 5726285809Sscottl } 5727285809Sscottl 5728285809Sscottl AGTIAPI_PRINTK("agtiapi_DeQueueCCB: %p from %p\n", pccb, phead); 5729285809Sscottl AG_LOCAL_LOCK(lock); 5730285809Sscottl 5731285809Sscottl if (pccb == *phead) 5732285809Sscottl { 5733285809Sscottl *phead = (*phead)->pccbNext; 5734285809Sscottl if (pccb == *ptail) 5735285809Sscottl { 5736285809Sscottl *ptail = NULL; 5737285809Sscottl } 5738285809Sscottl else 5739285809Sscottl pccb->pccbNext = NULL; 5740285809Sscottl status = AGTIAPI_SUCCESS; 5741285809Sscottl } 5742285809Sscottl else 5743285809Sscottl { 5744285809Sscottl pccb_curr = *phead; 5745285809Sscottl while (pccb_curr->pccbNext != NULL) 5746285809Sscottl { 5747285809Sscottl if (pccb_curr->pccbNext == pccb) 5748285809Sscottl { 5749285809Sscottl pccb_curr->pccbNext = pccb->pccbNext; 5750285809Sscottl pccb->pccbNext = NULL; 5751285809Sscottl if (pccb == *ptail) 5752285809Sscottl { 5753285809Sscottl *ptail = pccb_curr; 5754285809Sscottl } 5755285809Sscottl else 5756285809Sscottl pccb->pccbNext = NULL; 5757285809Sscottl status = AGTIAPI_SUCCESS; 5758285809Sscottl break; 5759285809Sscottl } 5760285809Sscottl pccb_curr = pccb_curr->pccbNext; 5761285809Sscottl } 5762285809Sscottl } 5763285809Sscottl AG_LOCAL_UNLOCK(lock); 5764285809Sscottl 5765285809Sscottl return status; 5766285809Sscottl} 5767285809Sscottl 5768285809Sscottl 5769285809SscottlSTATIC void wwnprintk( unsigned char *name, int len ) 5770285809Sscottl{ 5771285809Sscottl int i; 5772285809Sscottl 5773285809Sscottl for (i = 0; i < len; i++, name++) 5774285809Sscottl AGTIAPI_PRINTK("%02x", *name); 5775285809Sscottl AGTIAPI_PRINTK("\n"); 5776285809Sscottl} 5777285809Sscottl/* 5778285809Sscottl * SAS and SATA behind expander has 8 byte long unique address. 5779285809Sscottl * However, direct connect SATA device use 512 byte unique device id. 5780285809Sscottl * SPC uses remoteName to indicate length of ID and remoteAddress for the 5781285809Sscottl * address of memory that holding ID. 5782285809Sscottl */ 5783285809SscottlSTATIC int wwncpy( ag_device_t *pDevice ) 5784285809Sscottl{ 5785285809Sscottl int rc = 0; 5786285809Sscottl 5787285809Sscottl if (sizeof(pDevice->targetName) >= pDevice->devInfo.osAddress1 + 5788285809Sscottl pDevice->devInfo.osAddress2) 5789285809Sscottl { 5790285809Sscottl memcpy(pDevice->targetName, 5791285809Sscottl pDevice->devInfo.remoteName, 5792285809Sscottl pDevice->devInfo.osAddress1); 5793285809Sscottl memcpy(pDevice->targetName + pDevice->devInfo.osAddress1, 5794285809Sscottl pDevice->devInfo.remoteAddress, 5795285809Sscottl pDevice->devInfo.osAddress2); 5796285809Sscottl pDevice->targetLen = pDevice->devInfo.osAddress1 + 5797285809Sscottl pDevice->devInfo.osAddress2; 5798285809Sscottl rc = pDevice->targetLen; 5799285809Sscottl } 5800285809Sscottl else 5801285809Sscottl { 5802285809Sscottl AGTIAPI_PRINTK("WWN wrong size: %d + %d ERROR\n", 5803285809Sscottl pDevice->devInfo.osAddress1, pDevice->devInfo.osAddress2); 5804285809Sscottl rc = -1; 5805285809Sscottl } 5806285809Sscottl return rc; 5807285809Sscottl} 5808285809Sscottl 5809285809Sscottl 5810285809Sscottl/****************************************************************************** 5811285809Sscottlagtiapi_ReleaseCCBs() 5812285809Sscottl 5813285809SscottlPurpose: 5814285809Sscottl Free all allocated CCB memories for the Host Adapter. 5815285809SscottlParameters: 5816285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to HBA data stucture 5817285809SscottlReturn: 5818285809SscottlNote: 5819285809Sscottl******************************************************************************/ 5820285809SscottlSTATIC void agtiapi_ReleaseCCBs( struct agtiapi_softc *pCard ) 5821285809Sscottl{ 5822285809Sscottl 5823285809Sscottl ccb_hdr_t *hdr; 5824285809Sscottl U32 hdr_sz; 5825285809Sscottl ccb_t *pccb = 0; 5826285809Sscottl 5827285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseCCBs: start\n" ); 5828285809Sscottl 5829285809Sscottl#if ( defined AGTIAPI_TEST_DPL || defined AGTIAPI_TEST_EPL ) 5830285809Sscottl ccb_t *pccb; 5831285809Sscottl#endif 5832285809Sscottl 5833285809Sscottl#ifdef AGTIAPI_TEST_DPL 5834285809Sscottl for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL; 5835285809Sscottl pccb = pccb->pccbChainNext) 5836285809Sscottl { 5837285809Sscottl if(pccb->dplPtr && pccb->dplDma) 5838285809Sscottl pci_pool_free(pCard->dpl_ctx_pool, pccb->dplPtr, pccb->dplDma); 5839285809Sscottl } 5840285809Sscottl#endif 5841285809Sscottl 5842285809Sscottl#ifdef AGTIAPI_TEST_EPL 5843285809Sscottl for (pccb = (pccb_t)pCard->ccbChainList; pccb != NULL; 5844285809Sscottl pccb = pccb->pccbChainNext) 5845285809Sscottl { 5846285809Sscottl if(pccb->epl_ptr && pccb->epl_dma_ptr) 5847285809Sscottl pci_pool_free( 5848285809Sscottl pCard->epl_ctx_pool, 5849285809Sscottl pccb->epl_ptr, 5850285809Sscottl pccb->epl_dma_ptr 5851285809Sscottl ); 5852285809Sscottl } 5853285809Sscottl#endif 5854285809Sscottl 5855285809Sscottl while ((hdr = pCard->ccbAllocList) != NULL) 5856285809Sscottl { 5857285809Sscottl pCard->ccbAllocList = hdr->next; 5858285809Sscottl hdr_sz = (sizeof(*hdr) + cache_line_size() - 1) & ~(cache_line_size() - 1); 5859285809Sscottl pccb = (ccb_t*) ((char*)hdr + hdr_sz); 5860285809Sscottl if (pCard->buffer_dmat != NULL && pccb->CCB_dmamap != NULL) 5861285809Sscottl { 5862285809Sscottl bus_dmamap_destroy(pCard->buffer_dmat, pccb->CCB_dmamap); 5863285809Sscottl } 5864285809Sscottl free(hdr, M_PMC_MCCB); 5865285809Sscottl } 5866285809Sscottl pCard->ccbAllocList = NULL; 5867285809Sscottl 5868285809Sscottl 5869285809Sscottl return; 5870285809Sscottl} 5871285809Sscottl 5872285809Sscottl/****************************************************************************** 5873285809Sscottlagtiapi_TITimer() 5874285809Sscottl 5875285809SscottlPurpose: 5876285809Sscottl Timer tick for tisa common layer 5877285809SscottlParameters: 5878285809Sscottl void *data (IN) Pointer to the HBA data structure 5879285809SscottlReturn: 5880285809SscottlNote: 5881285809Sscottl******************************************************************************/ 5882285809SscottlSTATIC void agtiapi_TITimer( void *data ) 5883285809Sscottl{ 5884285809Sscottl 5885285809Sscottl U32 next_tick; 5886285809Sscottl struct agtiapi_softc *pCard; 5887285809Sscottl 5888285809Sscottl pCard = (struct agtiapi_softc *)data; 5889285809Sscottl 5890285809Sscottl// AGTIAPI_PRINTK("agtiapi_TITimer: start\n"); 5891285809Sscottl AG_GLOBAL_ARG( flags ); 5892285809Sscottl 5893285809Sscottl next_tick = pCard->pCardInfo->tiRscInfo.tiLoLevelResource. 5894285809Sscottl loLevelOption.usecsPerTick / USEC_PER_TICK; 5895285809Sscottl 5896285809Sscottl if( next_tick == 0 ) /* no timer required */ 5897285809Sscottl return; 5898285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags ); 5899285809Sscottl if( pCard->flags & AGTIAPI_SHUT_DOWN ) 5900285809Sscottl goto ext; 5901285809Sscottl tiCOMTimerTick( &pCard->tiRoot ); /* tisa common layer timer tick */ 5902285809Sscottl 5903285809Sscottl //add for polling mode 5904285809Sscottl#ifdef PMC_SPC 5905285809Sscottl if( agtiapi_polling_mode ) 5906285809Sscottl agtiapi_CheckAllVectors( pCard, tiNonInterruptContext ); 5907285809Sscottl#endif 5908285809Sscottl callout_reset( &pCard->OS_timer, next_tick, agtiapi_TITimer, pCard ); 5909285809Sscottlext: 5910285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 5911285809Sscottl return; 5912285809Sscottl} 5913285809Sscottl 5914285809Sscottl/****************************************************************************** 5915285809Sscottlagtiapi_clrRmScan() 5916285809Sscottl 5917285809SscottlPurpose: 5918285809Sscottl Clears device list entries scheduled for timeout and calls scan 5919285809SscottlParameters: 5920285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to HBA data structure 5921285809Sscottl******************************************************************************/ 5922285809SscottlSTATIC void agtiapi_clrRmScan( struct agtiapi_softc *pCard ) 5923285809Sscottl{ 5924285809Sscottl ag_tgt_map_t *pWWNList; 5925285809Sscottl ag_portal_info_t *pPortalInfo; 5926285809Sscottl ag_portal_data_t *pPortalData; 5927285809Sscottl int lIdx; 5928285809Sscottl bit32 lReadRm; 5929285809Sscottl bit16 lReadCt; 5930285809Sscottl 5931285809Sscottl pWWNList = pCard->pWWNList; 5932285809Sscottl 5933285809Sscottl AGTIAPI_PRINTK( "agtiapi_clrRmScan: start\n" ); 5934285809Sscottl 5935285809Sscottl AG_LIST_LOCK( &pCard->devListLock ); 5936285809Sscottl 5937285809Sscottl for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ ) 5938285809Sscottl { 5939285809Sscottl lReadCt = atomic_load_acq_16( &pCard->rmChkCt ); 5940285809Sscottl if ( 0 == lReadCt ) 5941285809Sscottl { 5942285809Sscottl break; // trim to who cares 5943285809Sscottl } 5944285809Sscottl 5945285809Sscottl lReadRm = atomic_readandclear_32( &pWWNList[lIdx].devRemoved ); 5946285809Sscottl if ( lReadRm > 0 ) 5947285809Sscottl { 5948285809Sscottl pCard->pDevList[lIdx].flags &= ~ACTIVE; 5949285809Sscottl pCard->pDevList[lIdx].pDevHandle = NULL; 5950285809Sscottl 5951285809Sscottl pPortalData = &pCard->pPortalData[pWWNList[lIdx].portId]; 5952285809Sscottl pPortalInfo = &pPortalData->portalInfo; 5953285809Sscottl pPortalInfo->pDevList[lIdx] = NULL; 5954285809Sscottl AGTIAPI_PRINTK( "agtiapi_clrRmScan: cleared dev %d at port %d\n", 5955285809Sscottl lIdx, pWWNList[lIdx].portId ); 5956285809Sscottl atomic_subtract_16( &pCard->rmChkCt, 1 ); 5957285809Sscottl } 5958285809Sscottl } 5959285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 5960285809Sscottl 5961285809Sscottl agtiapi_scan( pCard ); 5962285809Sscottl} 5963285809Sscottl 5964285809Sscottl 5965285809Sscottl/****************************************************************************** 5966285809Sscottlagtiapi_devRmCheck() 5967285809Sscottl 5968285809SscottlPurpose: 5969285809Sscottl Timer tick to check for timeout on missing targets 5970285809Sscottl Removes device list entry when timeout is reached 5971285809SscottlParameters: 5972285809Sscottl void *data (IN) Pointer to the HBA data structure 5973285809Sscottl******************************************************************************/ 5974285809SscottlSTATIC void agtiapi_devRmCheck( void *data ) 5975285809Sscottl{ 5976285809Sscottl struct agtiapi_softc *pCard; 5977285809Sscottl ag_tgt_map_t *pWWNList; 5978285809Sscottl int lIdx, cmpsetRtn, lRunScanFlag = FALSE; 5979285809Sscottl bit16 lReadCt; 5980285809Sscottl bit32 lReadRm; 5981285809Sscottl 5982285809Sscottl pCard = ( struct agtiapi_softc * )data; 5983285809Sscottl 5984285809Sscottl // routine overhead 5985285809Sscottl if ( callout_pending( &pCard->devRmTimer ) ) // callout was reset 5986285809Sscottl { 5987285809Sscottl return; 5988285809Sscottl } 5989285809Sscottl if ( !callout_active( &pCard->devRmTimer ) ) // callout was stopped 5990285809Sscottl { 5991285809Sscottl return; 5992285809Sscottl } 5993285809Sscottl callout_deactivate( &pCard->devRmTimer ); 5994285809Sscottl 5995285809Sscottl if( pCard->flags & AGTIAPI_SHUT_DOWN ) 5996285809Sscottl { 5997285809Sscottl return; // implicit timer clear 5998285809Sscottl } 5999285809Sscottl 6000285809Sscottl pWWNList = pCard->pWWNList; 6001285809Sscottl 6002285809Sscottl AG_LIST_LOCK( &pCard->devListLock ); 6003285809Sscottl lReadCt = atomic_load_acq_16( &pCard->rmChkCt ); 6004285809Sscottl if ( lReadCt ) 6005285809Sscottl { 6006285809Sscottl if ( callout_pending(&pCard->devRmTimer) == FALSE ) 6007285809Sscottl { 6008285809Sscottl callout_reset( &pCard->devRmTimer, 1 * hz, agtiapi_devRmCheck, pCard ); 6009285809Sscottl } 6010285809Sscottl else 6011285809Sscottl { 6012285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 6013285809Sscottl return; 6014285809Sscottl } 6015285809Sscottl 6016285809Sscottl for ( lIdx = 0; lIdx < pCard->devDiscover; lIdx++ ) 6017285809Sscottl { 6018285809Sscottl lReadCt = atomic_load_acq_16( &pCard->rmChkCt ); 6019285809Sscottl if ( 0 == lReadCt ) 6020285809Sscottl { 6021285809Sscottl break; // if handled somewhere else, get out 6022285809Sscottl } 6023285809Sscottl 6024285809Sscottl lReadRm = atomic_load_acq_32( &pWWNList[lIdx].devRemoved ); 6025285809Sscottl if ( lReadRm > 0 ) 6026285809Sscottl { 6027285809Sscottl if ( 1 == lReadRm ) // timed out 6028285809Sscottl { // no decrement of devRemoved as way to leave a clrRmScan marker 6029285809Sscottl lRunScanFlag = TRUE; // other devRemoved values are about to get wiped 6030285809Sscottl break; // ... so bail out 6031285809Sscottl } 6032285809Sscottl else 6033285809Sscottl { 6034285809Sscottl AGTIAPI_PRINTK( "agtiapi_devRmCheck: counting down dev %d @ %d; %d\n", 6035285809Sscottl lIdx, lReadRm, lReadCt ); 6036285809Sscottl cmpsetRtn = atomic_cmpset_32( &pWWNList[lIdx].devRemoved, 6037285809Sscottl lReadRm, 6038285809Sscottl lReadRm-1 ); 6039285809Sscottl if ( 0 == cmpsetRtn ) 6040285809Sscottl { 6041285809Sscottl printf( "agtiapi_devRmCheck: %d decrement already handled\n", 6042285809Sscottl lIdx ); 6043285809Sscottl } 6044285809Sscottl } 6045285809Sscottl } 6046285809Sscottl } 6047285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 6048285809Sscottl 6049285809Sscottl if ( TRUE == lRunScanFlag ) 6050285809Sscottl agtiapi_clrRmScan( pCard ); 6051285809Sscottl } 6052285809Sscottl else 6053285809Sscottl { 6054285809Sscottl AG_LIST_UNLOCK( &pCard->devListLock ); 6055285809Sscottl } 6056285809Sscottl 6057285809Sscottl return; 6058285809Sscottl} 6059285809Sscottl 6060285809Sscottl 6061285809Sscottlstatic void agtiapi_cam_poll( struct cam_sim *asim ) 6062285809Sscottl{ 6063285809Sscottl return; 6064285809Sscottl} 6065285809Sscottl 6066285809Sscottl/***************************************************************************** 6067285809Sscottlagtiapi_ResetCard() 6068285809Sscottl 6069285809SscottlPurpose: 6070285809Sscottl Hard or soft reset on the controller and resend any 6071285809Sscottl outstanding requests if needed. 6072285809SscottlParameters: 6073285809Sscottl struct agtiapi_softc *pCard (IN) Pointer to HBA data structure 6074285809Sscottl unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers 6075285809SscottlReturn: 6076285809Sscottl AGTIAPI_SUCCESS - reset successful 6077285809Sscottl AGTIAPI_FAIL - reset failed 6078285809SscottlNote: 6079285809Sscottl*****************************************************************************/ 6080285809SscottlU32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags ) 6081285809Sscottl{ 6082285809Sscottl ag_device_t *pDevice; 6083285809Sscottl U32 lIdx = 0; 6084285809Sscottl U32 lFlagVal; 6085285809Sscottl agBOOLEAN ret; 6086285809Sscottl ag_portal_info_t *pPortalInfo; 6087285809Sscottl ag_portal_data_t *pPortalData; 6088285809Sscottl U32 count, loop; 6089285809Sscottl int szdv; 6090285809Sscottl 6091285809Sscottl if( pCard->flags & AGTIAPI_RESET ) { 6092285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" ); 6093285809Sscottl return AGTIAPI_FAIL; 6094285809Sscottl } 6095285809Sscottl 6096285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n", 6097285809Sscottl pCard->resetCount ); 6098285809Sscottl#ifdef LOGEVENT 6099285809Sscottl agtiapi_LogEvent( pCard, 6100285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 6101285809Sscottl 0, 6102285809Sscottl agNULL, 6103285809Sscottl 0, 6104285809Sscottl "Reset initiator time = %d!", 6105285809Sscottl pCard->resetCount + 1 ); 6106285809Sscottl#endif 6107285809Sscottl 6108285809Sscottl pCard->flags |= AGTIAPI_RESET; 6109285809Sscottl pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS); 6110285809Sscottl tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE ); 6111285809Sscottl pCard->flags &= ~AGTIAPI_SYS_INTR_ON; 6112285809Sscottl 6113285809Sscottl agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK ); 6114285809Sscottl 6115285809Sscottl for ( lIdx = 1; 3 >= lIdx; lIdx++ ) // we try reset up to 3 times 6116285809Sscottl { 6117285809Sscottl if( pCard->flags & AGTIAPI_SOFT_RESET ) 6118285809Sscottl { 6119285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" ); 6120285809Sscottl tiCOMReset( &pCard->tiRoot, tiSoftReset ); 6121285809Sscottl } 6122285809Sscottl else 6123285809Sscottl { 6124285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" ); 6125285809Sscottl } 6126285809Sscottl 6127285809Sscottl lFlagVal = AGTIAPI_RESET_SUCCESS; 6128285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags ); 6129285809Sscottl ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags ); 6130285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags ); 6131285809Sscottl 6132285809Sscottl if( ret == AGTIAPI_FAIL ) 6133285809Sscottl { 6134285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, " 6135285809Sscottl "try again?\n" ); 6136285809Sscottl } 6137285809Sscottl else 6138285809Sscottl { 6139285809Sscottl break; 6140285809Sscottl } 6141285809Sscottl } 6142285809Sscottl if ( 1 < lIdx ) 6143285809Sscottl { 6144285809Sscottl if ( AGTIAPI_FAIL == ret ) 6145285809Sscottl { 6146285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n", 6147285809Sscottl lIdx ); 6148285809Sscottl } 6149285809Sscottl else 6150285809Sscottl { 6151285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n", 6152285809Sscottl lIdx ); 6153285809Sscottl } 6154285809Sscottl } 6155285809Sscottl if( AGTIAPI_FAIL == ret ) 6156285809Sscottl { 6157285809Sscottl printf( "agtiapi_ResetCard: reset ERROR\n" ); 6158285809Sscottl pCard->flags &= ~AGTIAPI_INSTALLED; 6159285809Sscottl return AGTIAPI_FAIL; 6160285809Sscottl } 6161285809Sscottl 6162285809Sscottl pCard->flags &= ~AGTIAPI_SOFT_RESET; 6163285809Sscottl 6164285809Sscottl // disable all devices 6165285809Sscottl pDevice = pCard->pDevList; 6166285809Sscottl for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ ) 6167285809Sscottl { 6168285809Sscottl /* if ( pDevice->flags & ACTIVE ) 6169285809Sscottl { 6170285809Sscottl printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx ); 6171285809Sscottl } */ 6172285809Sscottl pDevice->flags &= ~ACTIVE; 6173285809Sscottl } 6174285809Sscottl 6175285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags ); 6176285809Sscottl if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess ) 6177285809Sscottl printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" ); 6178285809Sscottl else 6179285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" ); 6180285809Sscottl 6181285809Sscottl if( !pCard->pDevList ) { // try to get a little sanity here 6182285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n", 6183285809Sscottl pCard->pDevList ); 6184285809Sscottl return AGTIAPI_FAIL; 6185285809Sscottl } 6186285809Sscottl 6187285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n", 6188285809Sscottl pCard->tgtCount, pCard->portCount ); 6189285809Sscottl pCard->tgtCount = 0; 6190285809Sscottl 6191285809Sscottl DELAY( 500000 ); 6192285809Sscottl 6193285809Sscottl pCard->flags &= ~AGTIAPI_CB_DONE; 6194285809Sscottl 6195285809Sscottl pPortalData = pCard->pPortalData; 6196285809Sscottl 6197285809Sscottl for( count = 0; count < pCard->portCount; count++ ) { 6198285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags ); 6199285809Sscottl pPortalInfo = &pPortalData->portalInfo; 6200285809Sscottl pPortalInfo->portStatus = 0; 6201285809Sscottl pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START | 6202285809Sscottl AGTIAPI_PORT_DISC_READY | 6203285809Sscottl AGTIAPI_DISC_DONE | 6204285809Sscottl AGTIAPI_DISC_COMPLETE ); 6205285809Sscottl 6206285809Sscottl szdv = 6207285809Sscottl sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] ); 6208285809Sscottl if (szdv > pCard->devDiscover) 6209285809Sscottl { 6210285809Sscottl szdv = pCard->devDiscover; 6211285809Sscottl } 6212285809Sscottl 6213285809Sscottl for( lIdx = 0, loop = 0; 6214285809Sscottl lIdx < szdv && loop < pPortalInfo->devTotal; 6215285809Sscottl lIdx++ ) 6216285809Sscottl { 6217285809Sscottl pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx]; 6218285809Sscottl if( pDevice ) 6219285809Sscottl { 6220285809Sscottl loop++; 6221285809Sscottl pDevice->pDevHandle = 0; // mark for availability in pCard->pDevList[] 6222285809Sscottl // don't erase more as the device is scheduled for removal on DPC 6223285809Sscottl } 6224285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n", 6225285809Sscottl pDevice, pPortalInfo->pDevList, lIdx ); 6226285809Sscottl pPortalInfo->devTotal = pPortalInfo->devPrev = 0; 6227285809Sscottl } 6228285809Sscottl 6229285809Sscottl for( lIdx = 0; lIdx < maxTargets; lIdx++ ) 6230285809Sscottl { // we reconstruct dev list later in get dev handle 6231285809Sscottl pPortalInfo->pDevList[lIdx] = NULL; 6232285809Sscottl } 6233285809Sscottl 6234285809Sscottl for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ ) 6235285809Sscottl { 6236285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data " 6237285809Sscottl "%p / %d / %p\n", 6238285809Sscottl &pCard->tiRoot, 6239285809Sscottl pPortalInfo->portID, 6240285809Sscottl &pPortalInfo->tiPortalContext ); 6241285809Sscottl 6242285809Sscottl if( tiCOMPortStart( &pCard->tiRoot, 6243285809Sscottl pPortalInfo->portID, 6244285809Sscottl &pPortalInfo->tiPortalContext, 6245285809Sscottl 0 ) 6246285809Sscottl != tiSuccess ) 6247285809Sscottl { 6248285809Sscottl printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n", 6249285809Sscottl pPortalInfo->portID ); 6250285809Sscottl } 6251285809Sscottl else 6252285809Sscottl { 6253285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n", 6254285809Sscottl pPortalInfo->portID ); 6255285809Sscottl break; 6256285809Sscottl } 6257285809Sscottl } 6258285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 6259285809Sscottl tiCOMGetPortInfo( &pCard->tiRoot, 6260285809Sscottl &pPortalInfo->tiPortalContext, 6261285809Sscottl &pPortalInfo->tiPortInfo ); 6262285809Sscottl pPortalData++; 6263285809Sscottl } 6264285809Sscottl // ## fail case: pCard->flags &= ~AGTIAPI_INSTALLED; 6265285809Sscottl 6266285809Sscottl 6267285809Sscottl AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags); 6268285809Sscottl 6269285809Sscottl if( !(pCard->flags & AGTIAPI_INSTALLED) ) // driver not installed ! 6270285809Sscottl { 6271285809Sscottl printf( "agtiapi_ResetCard: error, driver not intstalled? " 6272285809Sscottl "!AGTIAPI_INSTALLED \n" ); 6273285809Sscottl return AGTIAPI_FAIL; 6274285809Sscottl } 6275285809Sscottl 6276285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount ); 6277285809Sscottl 6278285809Sscottl#ifdef LOGEVENT 6279285809Sscottl agtiapi_LogEvent( pCard, 6280285809Sscottl IOCTL_EVT_SEV_INFORMATIONAL, 6281285809Sscottl 0, 6282285809Sscottl agNULL, 6283285809Sscottl 0, 6284285809Sscottl "Reset initiator total device = %d!", 6285285809Sscottl pCard->tgtCount ); 6286285809Sscottl#endif 6287285809Sscottl pCard->resetCount++; 6288285809Sscottl 6289285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" ); 6290285809Sscottl // clear send & done queue 6291285809Sscottl AG_LOCAL_LOCK( &pCard->sendLock ); 6292285809Sscottl pCard->ccbSendHead = NULL; 6293285809Sscottl pCard->ccbSendTail = NULL; 6294285809Sscottl AG_LOCAL_UNLOCK( &pCard->sendLock ); 6295285809Sscottl 6296285809Sscottl AG_LOCAL_LOCK( &pCard->doneLock ); 6297285809Sscottl pCard->ccbDoneHead = NULL; 6298285809Sscottl pCard->ccbDoneTail = NULL; 6299285809Sscottl AG_LOCAL_UNLOCK( &pCard->doneLock ); 6300285809Sscottl 6301285809Sscottl // clear smp queues also 6302285809Sscottl AG_LOCAL_LOCK( &pCard->sendSMPLock ); 6303285809Sscottl pCard->smpSendHead = NULL; 6304285809Sscottl pCard->smpSendTail = NULL; 6305285809Sscottl AG_LOCAL_UNLOCK( &pCard->sendSMPLock ); 6306285809Sscottl 6307285809Sscottl AG_LOCAL_LOCK( &pCard->doneSMPLock ); 6308285809Sscottl pCard->smpDoneHead = NULL; 6309285809Sscottl pCard->smpDoneTail = NULL; 6310285809Sscottl AG_LOCAL_UNLOCK( &pCard->doneSMPLock ); 6311285809Sscottl 6312285809Sscottl // finished with all reset stuff, now start things back up 6313285809Sscottl tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE ); 6314285809Sscottl pCard->flags |= AGTIAPI_SYS_INTR_ON; 6315285809Sscottl pCard->flags |= AGTIAPI_HAD_RESET; 6316285809Sscottl pCard->flags &= ~AGTIAPI_RESET; // ## 6317285809Sscottl agtiapi_StartIO( pCard ); 6318285809Sscottl AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" ); 6319285809Sscottl return AGTIAPI_SUCCESS; 6320285809Sscottl} // agtiapi_ResetCard 6321285809Sscottl 6322285809Sscottl 6323285809Sscottl/****************************************************************************** 6324285809Sscottlagtiapi_ReleaseHBA() 6325285809Sscottl 6326285809SscottlPurpose: 6327285809Sscottl Releases all resources previously acquired to support 6328285809Sscottl a specific Host Adapter, including the I/O Address range, 6329285809Sscottl and unregisters the agtiapi Host Adapter. 6330285809SscottlParameters: 6331285809Sscottl device_t dev (IN) - device pointer 6332285809SscottlReturn: 6333285809Sscottl always return 0 - success 6334285809SscottlNote: 6335285809Sscottl******************************************************************************/ 6336285809Sscottlint agtiapi_ReleaseHBA( device_t dev ) 6337285809Sscottl{ 6338285809Sscottl 6339285809Sscottl int thisCard = device_get_unit( dev ); // keeping get_unit call to once 6340285809Sscottl int i; 6341285809Sscottl ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ]; 6342285809Sscottl struct ccb_setasync csa; 6343285809Sscottl struct agtiapi_softc *pCard; 6344285809Sscottl pCard = device_get_softc( dev ); 6345285809Sscottl ag_card_info_t *pCardInfo = pCard->pCardInfo; 6346285809Sscottl ag_resource_info_t *pRscInfo = &thisCardInst->tiRscInfo; 6347285809Sscottl 6348285809Sscottl AG_GLOBAL_ARG(flags); 6349285809Sscottl 6350285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: start\n" ); 6351285809Sscottl 6352285809Sscottl if (thisCardInst != pCardInfo) 6353285809Sscottl { 6354285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p " 6355285809Sscottl "pCardInfo %p\n", 6356285809Sscottl thisCardInst, 6357285809Sscottl pCardInfo ); 6358285809Sscottl panic( "agtiapi_ReleaseHBA: Wrong ag_card_info_t thisCardInst %p pCardInfo " 6359285809Sscottl "%p\n", 6360285809Sscottl thisCardInst, 6361285809Sscottl pCardInfo ); 6362285809Sscottl return( EIO ); 6363285809Sscottl } 6364285809Sscottl 6365285809Sscottl 6366285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA card %p\n", pCard ); 6367285809Sscottl pCard->flags |= AGTIAPI_SHUT_DOWN; 6368285809Sscottl 6369285809Sscottl 6370285809Sscottl // remove timer 6371285809Sscottl if (pCard->flags & AGTIAPI_TIMER_ON) 6372285809Sscottl { 6373285809Sscottl AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags ); 6374285809Sscottl callout_drain( &pCard->OS_timer ); 6375285809Sscottl callout_drain( &pCard->devRmTimer ); 6376285809Sscottl callout_drain(&pCard->IO_timer); 6377285809Sscottl AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags ); 6378285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: timer released\n" ); 6379285809Sscottl } 6380285809Sscottl 6381285809Sscottl#ifdef HIALEAH_ENCRYPTION 6382285809Sscottl//Release encryption table memory - Fix it 6383285809Sscottl //if(pCard->encrypt && (pCard->flags & AGTIAPI_INSTALLED)) 6384285809Sscottl //agtiapi_CleanupEncryption(pCard); 6385285809Sscottl#endif 6386285809Sscottl 6387285809Sscottl /* 6388285809Sscottl * Shutdown the channel so that chip gets frozen 6389285809Sscottl * and it does not do any more pci-bus accesses. 6390285809Sscottl */ 6391285809Sscottl if (pCard->flags & AGTIAPI_SYS_INTR_ON) 6392285809Sscottl { 6393285809Sscottl tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE ); 6394285809Sscottl pCard->flags &= ~AGTIAPI_SYS_INTR_ON; 6395285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: card interrupt off\n" ); 6396285809Sscottl } 6397285809Sscottl if (pCard->flags & AGTIAPI_INSTALLED) 6398285809Sscottl { 6399285809Sscottl tiCOMShutDown( &pCard->tiRoot ); 6400285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: low layers shutdown\n" ); 6401285809Sscottl } 6402285809Sscottl 6403285809Sscottl /* 6404285809Sscottl * first release IRQ, so that we do not get any more interrupts 6405285809Sscottl * from this host 6406285809Sscottl */ 6407285809Sscottl if (pCard->flags & AGTIAPI_IRQ_REQUESTED) 6408285809Sscottl { 6409285809Sscottl if (!agtiapi_intx_mode) 6410285809Sscottl { 6411285809Sscottl int i; 6412285809Sscottl for (i = 0; i< MAX_MSIX_NUM_VECTOR; i++) 6413285809Sscottl { 6414285809Sscottl if (pCard->irq[i] != agNULL && pCard->rscID[i] != 0) 6415285809Sscottl { 6416285809Sscottl bus_teardown_intr(dev, pCard->irq[i], pCard->intrcookie[i]); 6417285809Sscottl bus_release_resource( dev, 6418285809Sscottl SYS_RES_IRQ, 6419285809Sscottl pCard->rscID[i], 6420285809Sscottl pCard->irq[i] ); 6421285809Sscottl } 6422285809Sscottl } 6423285809Sscottl pci_release_msi(dev); 6424285809Sscottl } 6425285809Sscottl pCard->flags &= ~AGTIAPI_IRQ_REQUESTED; 6426285809Sscottl 6427285809Sscottl 6428285809Sscottl 6429285809Sscottl#ifdef AGTIAPI_DPC 6430285809Sscottl for (i = 0; i < MAX_MSIX_NUM_DPC; i++) 6431285809Sscottl tasklet_kill(&pCard->tasklet_dpc[i]); 6432285809Sscottl#endif 6433285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: IRQ released\n"); 6434285809Sscottl } 6435285809Sscottl 6436285809Sscottl // release memory vs. alloc in agtiapi_alloc_ostimem; used in ostiAllocMemory 6437285809Sscottl if( pCard->osti_busaddr != 0 ) { 6438285809Sscottl bus_dmamap_unload( pCard->osti_dmat, pCard->osti_mapp ); 6439285809Sscottl } 6440285809Sscottl if( pCard->osti_mem != NULL ) { 6441285809Sscottl bus_dmamem_free( pCard->osti_dmat, pCard->osti_mem, pCard->osti_mapp ); 6442285809Sscottl } 6443285809Sscottl if( pCard->osti_dmat != NULL ) { 6444285809Sscottl bus_dma_tag_destroy( pCard->osti_dmat ); 6445285809Sscottl } 6446285809Sscottl 6447285809Sscottl /* unmap the mapped PCI memory */ 6448285809Sscottl /* calls bus_release_resource( ,SYS_RES_MEMORY, ..) */ 6449285809Sscottl agtiapi_ReleasePCIMem(thisCardInst); 6450285809Sscottl 6451285809Sscottl /* release all ccbs */ 6452285809Sscottl if (pCard->ccbTotal) 6453285809Sscottl { 6454285809Sscottl //calls bus_dmamap_destroy() for all pccbs 6455285809Sscottl agtiapi_ReleaseCCBs(pCard); 6456285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: CCB released\n"); 6457285809Sscottl } 6458285809Sscottl 6459285809Sscottl#ifdef HIALEAH_ENCRYPTION 6460285809Sscottl/*release encryption resources - Fix it*/ 6461285809Sscottl if(pCard->encrypt) 6462285809Sscottl { 6463285809Sscottl /*Check that all IO's are completed */ 6464285809Sscottl if(atomic_read (&outstanding_encrypted_io_count) > 0) 6465285809Sscottl { 6466285809Sscottl printf("%s: WARNING: %d outstanding encrypted IOs !\n", __FUNCTION__, atomic_read(&outstanding_encrypted_io_count)); 6467285809Sscottl } 6468285809Sscottl //agtiapi_CleanupEncryptionPools(pCard); 6469285809Sscottl } 6470285809Sscottl#endif 6471285809Sscottl 6472285809Sscottl 6473285809Sscottl /* release device list */ 6474285809Sscottl if( pCard->pDevList ) { 6475285809Sscottl free((caddr_t)pCard->pDevList, M_PMC_MDVT); 6476285809Sscottl pCard->pDevList = NULL; 6477285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: device list released\n"); 6478285809Sscottl } 6479285809Sscottl#ifdef LINUX_PERBI_SUPPORT // ## review use of PERBI 6480285809Sscottl AGTIAPI_PRINTK( "agtiapi_ReleaseHBA: WWN list %p \n", pCard->pWWNList ); 6481285809Sscottl if( pCard->pWWNList ) { 6482285809Sscottl free( (caddr_t)pCard->pWWNList, M_PMC_MTGT ); 6483285809Sscottl pCard->pWWNList = NULL; 6484285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: WWN list released\n"); 6485285809Sscottl } 6486285809Sscottl if( pCard->pSLRList ) { 6487285809Sscottl free( (caddr_t)pCard->pSLRList, M_PMC_MSLR ); 6488285809Sscottl pCard->pSLRList = NULL; 6489285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: SAS Local Remote list released\n"); 6490285809Sscottl } 6491285809Sscottl 6492285809Sscottl#endif 6493285809Sscottl if (pCard->pPortalData) 6494285809Sscottl { 6495285809Sscottl free((caddr_t)pCard->pPortalData, M_PMC_MPRT); 6496285809Sscottl pCard->pPortalData = NULL; 6497285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: PortalData released\n"); 6498285809Sscottl } 6499285809Sscottl //calls contigfree() or free() 6500285809Sscottl agtiapi_MemFree(pCardInfo); 6501285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: low level resource released\n"); 6502285809Sscottl 6503285809Sscottl#ifdef HOTPLUG_SUPPORT 6504285809Sscottl if (pCard->flags & AGTIAPI_PORT_INITIALIZED) 6505285809Sscottl { 6506285809Sscottl // agtiapi_FreeDevWorkList(pCard); 6507285809Sscottl AGTIAPI_PRINTK("agtiapi_ReleaseHBA: (HP dev) work resources released\n"); 6508285809Sscottl } 6509285809Sscottl#endif 6510285809Sscottl 6511285809Sscottl /* 6512285809Sscottl * TBD, scsi_unregister may release wrong host data structure 6513285809Sscottl * which cause NULL pointer shows up. 6514285809Sscottl */ 6515285809Sscottl if (pCard->flags & AGTIAPI_SCSI_REGISTERED) 6516285809Sscottl { 6517285809Sscottl pCard->flags &= ~AGTIAPI_SCSI_REGISTERED; 6518285809Sscottl 6519285809Sscottl 6520285809Sscottl#ifdef AGTIAPI_LOCAL_LOCK 6521285809Sscottl if (pCard->STLock) 6522285809Sscottl { 6523285809Sscottl //destroy mtx 6524285809Sscottl int maxLocks; 6525285809Sscottl maxLocks = pRscInfo->tiLoLevelResource.loLevelOption.numOfQueuesPerPort; 6526285809Sscottl 6527285809Sscottl for( i = 0; i < maxLocks; i++ ) 6528285809Sscottl { 6529285809Sscottl mtx_destroy(&pCard->STLock[i]); 6530285809Sscottl } 6531285809Sscottl free(pCard->STLock, M_PMC_MSTL); 6532285809Sscottl pCard->STLock = NULL; 6533285809Sscottl } 6534285809Sscottl#endif 6535285809Sscottl 6536285809Sscottl } 6537285809Sscottl ag_card_good--; 6538285809Sscottl 6539285809Sscottl /* reset agtiapi_1st_time if this is the only card */ 6540285809Sscottl if (!ag_card_good && !agtiapi_1st_time) 6541285809Sscottl { 6542285809Sscottl agtiapi_1st_time = 1; 6543285809Sscottl } 6544285809Sscottl 6545285809Sscottl /* for tiSgl_t memeory */ 6546285809Sscottl if (pCard->tisgl_busaddr != 0) 6547285809Sscottl { 6548285809Sscottl bus_dmamap_unload(pCard->tisgl_dmat, pCard->tisgl_map); 6549285809Sscottl } 6550285809Sscottl if (pCard->tisgl_mem != NULL) 6551285809Sscottl { 6552285809Sscottl bus_dmamem_free(pCard->tisgl_dmat, pCard->tisgl_mem, pCard->tisgl_map); 6553285809Sscottl } 6554285809Sscottl if (pCard->tisgl_dmat != NULL) 6555285809Sscottl { 6556285809Sscottl bus_dma_tag_destroy(pCard->tisgl_dmat); 6557285809Sscottl } 6558285809Sscottl 6559285809Sscottl if (pCard->buffer_dmat != agNULL) 6560285809Sscottl { 6561285809Sscottl bus_dma_tag_destroy(pCard->buffer_dmat); 6562285809Sscottl } 6563285809Sscottl 6564285809Sscottl if (pCard->sim != NULL) 6565285809Sscottl { 6566285809Sscottl mtx_lock(&thisCardInst->pmIOLock); 6567285809Sscottl xpt_setup_ccb(&csa.ccb_h, pCard->path, 5); 6568285809Sscottl csa.ccb_h.func_code = XPT_SASYNC_CB; 6569285809Sscottl csa.event_enable = 0; 6570285809Sscottl csa.callback = agtiapi_async; 6571285809Sscottl csa.callback_arg = pCard; 6572285809Sscottl xpt_action((union ccb *)&csa); 6573285809Sscottl xpt_free_path(pCard->path); 6574285809Sscottl // if (pCard->ccbTotal == 0) 6575285809Sscottl if (pCard->ccbTotal <= thisCard) 6576285809Sscottl { 6577285809Sscottl /* 6578285809Sscottl no link up so that simq has not been released. 6579285809Sscottl In order to remove cam, we call this. 6580285809Sscottl */ 6581285809Sscottl xpt_release_simq(pCard->sim, 1); 6582285809Sscottl } 6583285809Sscottl xpt_bus_deregister(cam_sim_path(pCard->sim)); 6584285809Sscottl cam_sim_free(pCard->sim, FALSE); 6585285809Sscottl mtx_unlock(&thisCardInst->pmIOLock); 6586285809Sscottl } 6587285809Sscottl if (pCard->devq != NULL) 6588285809Sscottl { 6589285809Sscottl cam_simq_free(pCard->devq); 6590285809Sscottl } 6591285809Sscottl 6592285809Sscottl //destroy mtx 6593285809Sscottl mtx_destroy( &thisCardInst->pmIOLock ); 6594285809Sscottl mtx_destroy( &pCard->sendLock ); 6595285809Sscottl mtx_destroy( &pCard->doneLock ); 6596285809Sscottl mtx_destroy( &pCard->sendSMPLock ); 6597285809Sscottl mtx_destroy( &pCard->doneSMPLock ); 6598285809Sscottl mtx_destroy( &pCard->ccbLock ); 6599285809Sscottl mtx_destroy( &pCard->devListLock ); 6600285809Sscottl mtx_destroy( &pCard->OS_timer_lock ); 6601285809Sscottl mtx_destroy( &pCard->devRmTimerLock ); 6602285809Sscottl mtx_destroy( &pCard->memLock ); 6603285809Sscottl mtx_destroy( &pCard->freezeLock ); 6604285809Sscottl 6605285809Sscottl destroy_dev( pCard->my_cdev ); 6606285809Sscottl memset((void *)pCardInfo, 0, sizeof(ag_card_info_t)); 6607285809Sscottl return 0; 6608285809Sscottl} 6609285809Sscottl 6610285809Sscottl 6611285809Sscottl// Called during system shutdown after sync 6612285809Sscottlstatic int agtiapi_shutdown( device_t dev ) 6613285809Sscottl{ 6614285809Sscottl AGTIAPI_PRINTK( "agtiapi_shutdown\n" ); 6615285809Sscottl return( 0 ); 6616285809Sscottl} 6617285809Sscottl 6618285809Sscottlstatic int agtiapi_suspend( device_t dev ) // Device suspend routine. 6619285809Sscottl{ 6620285809Sscottl AGTIAPI_PRINTK( "agtiapi_suspend\n" ); 6621285809Sscottl return( 0 ); 6622285809Sscottl} 6623285809Sscottl 6624285809Sscottlstatic int agtiapi_resume( device_t dev ) // Device resume routine. 6625285809Sscottl{ 6626285809Sscottl AGTIAPI_PRINTK( "agtiapi_resume\n" ); 6627285809Sscottl return( 0 ); 6628285809Sscottl} 6629285809Sscottl 6630285809Sscottlstatic device_method_t agtiapi_methods[] = { // Device interface 6631285809Sscottl DEVMETHOD( device_probe, agtiapi_probe ), 6632285809Sscottl DEVMETHOD( device_attach, agtiapi_attach ), 6633285809Sscottl DEVMETHOD( device_detach, agtiapi_ReleaseHBA ), 6634285809Sscottl DEVMETHOD( device_shutdown, agtiapi_shutdown ), 6635285809Sscottl DEVMETHOD( device_suspend, agtiapi_suspend ), 6636285809Sscottl DEVMETHOD( device_resume, agtiapi_resume ), 6637285809Sscottl { 0, 0 } 6638285809Sscottl}; 6639285809Sscottl 6640285809Sscottlstatic devclass_t pmspcv_devclass; 6641285809Sscottl 6642285809Sscottlstatic driver_t pmspcv_driver = { 6643285809Sscottl "pmspcv", 6644285809Sscottl agtiapi_methods, 6645285809Sscottl sizeof( struct agtiapi_softc ) 6646285809Sscottl}; 6647285809Sscottl 6648285809SscottlDRIVER_MODULE( pmspcv, pci, pmspcv_driver, pmspcv_devclass, 0, 0 ); 6649285809SscottlMODULE_DEPEND( pmspcv, cam, 1, 1, 1 ); 6650285809SscottlMODULE_DEPEND( pmspcv, pci, 1, 1, 1 ); 6651285809Sscottl 6652285809Sscottl#include <dev/pms/freebsd/driver/common/lxosapi.c> 6653285809Sscottl#include <dev/pms/freebsd/driver/ini/src/osapi.c> 6654285809Sscottl#include <dev/pms/freebsd/driver/common/lxutil.c> 6655285809Sscottl#include <dev/pms/freebsd/driver/common/lxencrypt.c> 6656285809Sscottl 6657285809Sscottl 6658