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