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