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