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