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