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