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