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