1285242Sachim/******************************************************************************* 2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285242Sachim* 4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285242Sachim*that the following conditions are met: 6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285242Sachim*following disclaimer. 8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice, 9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285242Sachim*with the distribution. 11285242Sachim* 12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285242Sachim* 21285242Sachim* $FreeBSD$ 22285242Sachim* 23285242Sachim*******************************************************************************/ 24285242Sachim/****************************************************************************** 25285242SachimPMC-Sierra TISA Initiator Device Driver for Linux 2.x.x. 26285242Sachim 27285242SachimModule Name: 28285242Sachim osapi.c 29285242SachimAbstract: 30285242Sachim Linux iSCSI/FC Initiator driver module itsdk required OS functions 31285242SachimEnvironment: 32285242Sachim Part of oslayer module, Kernel or loadable module 33285242Sachim 34285242Sachim******************************************************************************* 35285242SachimostiInitiatorEvent() 36285242Sachim 37285242SachimPurpose: 38285242Sachim TI layer call back to OSlayer to inform events 39285242SachimParameters: 40285242Sachim tiRoot_t *ptiRoot (IN) Pointer to HBA data structure 41285242Sachim tiDeviceHandle_t *ptiDevHandle (IN) Pointer to device handle 42285242Sachim tiIntrEvenType_t evenType (IN) Event type 43285242Sachim tiIntrEventStatus_t evetStatus (IN) Event status 44285242Sachim void *parm (IN) pointer to even specific data 45285242SachimReturn: 46285242SachimNote: 47285242Sachim TBD, further event process required. 48285242Sachim******************************************************************************/ 49285242Sachimvoid ostiInitiatorEvent( tiRoot_t *ptiRoot, 50285242Sachim tiPortalContext_t *ptiPortalContext, 51285242Sachim tiDeviceHandle_t *ptiDevHandle, 52285242Sachim tiIntrEventType_t eventType, 53285242Sachim U32 eventStatus, 54285242Sachim void *parm ) 55285242Sachim{ 56285242Sachim ag_portal_data_t *pPortalData; 57285242Sachim ag_portal_info_t *pPortalInfo; 58285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD( ptiRoot ); 59285242Sachim ccb_t *pccb; 60285242Sachim ccb_t *pTMccb; 61285242Sachim ccb_t *ccbIO; 62285242Sachim 63285242Sachim#ifdef AGTIAPI_EVENT_LOG 64285242Sachim AGTIAPI_PRINTK("Initiator Event:\n"); 65285242Sachim AGTIAPI_PRINTK("DevHandle %p, eventType 0x%x, eventStatus 0x%x\n", 66285242Sachim ptiDevHandle, eventType, eventStatus); 67285242Sachim AGTIAPI_PRINTK("Parameter: %s\n", (char *)parm); 68285242Sachim#endif 69285242Sachim 70285242Sachim AGTIAPI_PRINTK("ostiInitiatorEvent: eventType 0x%x eventStatus 0x%x\n", eventType, eventStatus); 71285242Sachim 72285242Sachim switch (eventType) 73285242Sachim { 74285242Sachim case tiIntrEventTypeCnxError: 75285242Sachim if (eventStatus == tiCnxUp) 76285242Sachim { 77285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxUp!\n"); 78285242Sachim } 79285242Sachim if (eventStatus == tiCnxDown) 80285242Sachim { 81285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeCnxError - tiCnxDown!\n"); 82285242Sachim } 83285242Sachim break; 84285242Sachim case tiIntrEventTypeDiscovery: 85285242Sachim pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext); 86285242Sachim pCard->flags |= AGTIAPI_CB_DONE; 87285242Sachim if (eventStatus == tiDiscOK) 88285242Sachim { 89285242Sachim AGTIAPI_PRINTK("eventStatus - tiDiscOK\n"); 90285242Sachim AGTIAPI_PRINTK("ostiInitiatorEvent: pcard %d eventStatus - tiDiscOK\n", pCard->cardNo ); 91285242Sachim PORTAL_STATUS(pPortalData) |= AGTIAPI_DISC_COMPLETE; 92285242Sachim#ifndef HOTPLUG_SUPPORT 93285242Sachim if (!(pCard->flags & AGTIAPI_INIT_TIME)) 94285242Sachim#else 95285242Sachim if (TRUE) 96285242Sachim#endif 97285242Sachim { 98285242Sachim 99285242Sachim agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 100285242Sachim tiIntrEventTypeDiscovery, tiDiscOK); 101285242Sachim PORTAL_STATUS(pPortalData) |= 102285242Sachim (AGTIAPI_DISC_DONE | AGTIAPI_PORT_LINK_UP); 103285242Sachim } 104285242Sachim /* Trigger CheckIOTimeout */ 105285242Sachim callout_reset(&pCard->IO_timer, 20*hz, agtiapi_CheckIOTimeout, pCard); 106285242Sachim } 107285242Sachim else if (eventStatus == tiDiscFailed) 108285242Sachim { 109285242Sachim AGTIAPI_PRINTK("eventStatus - tiDiscFailed\n"); 110285242Sachim agtiapi_GetDevHandle(pCard, &pPortalData->portalInfo, 111285242Sachim tiIntrEventTypeDiscovery, tiDiscFailed); 112285242Sachim PORTAL_STATUS(pPortalData) &= ~AGTIAPI_DISC_DONE; 113285242Sachim } 114285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeDiscovery - portal %p, status 0x%x\n", 115285242Sachim pPortalData, 116285242Sachim PORTAL_STATUS(pPortalData)); 117285242Sachim break; 118285242Sachim case tiIntrEventTypeDeviceChange: 119285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeDeviceChange - portal %p es %d\n", 120285242Sachim ptiPortalContext->osData, eventStatus); 121285242Sachim pPortalData = PORTAL_CONTEXT_TO_PORTALDATA(ptiPortalContext); 122285242Sachim pPortalInfo = &pPortalData->portalInfo; 123285242Sachim#ifndef HOTPLUG_SUPPORT 124285242Sachim if (!(pCard->flags & AGTIAPI_INIT_TIME)) 125285242Sachim#else 126285242Sachim if (TRUE) 127285242Sachim#endif 128285242Sachim { 129285242Sachim agtiapi_GetDevHandle(pCard, pPortalInfo, tiIntrEventTypeDeviceChange, 130285242Sachim eventStatus); 131285242Sachim// agtiapi_StartIO(pCard); 132285242Sachim } 133285242Sachim break; 134285242Sachim case tiIntrEventTypeTransportRecovery: 135285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTransportRecovery!\n"); 136285242Sachim break; 137285242Sachim case tiIntrEventTypeTaskManagement: 138285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement!\n"); 139285242Sachim pccb = (pccb_t)((tiIORequest_t *)parm)->osData; 140285242Sachim if (pccb->flags & TASK_TIMEOUT) 141285242Sachim { 142285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM timeout!\n"); 143285242Sachim agtiapi_FreeTMCCB(pCard, pccb); 144285242Sachim } 145285242Sachim else 146285242Sachim { 147285242Sachim pccb->flags |= AGTIAPI_CB_DONE; 148285242Sachim if (eventStatus == tiTMOK) 149285242Sachim { 150285242Sachim pccb->flags |= TASK_SUCCESS; 151285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: pTMccb %p flag %x \n", 152285242Sachim pccb, pccb->flags); 153285242Sachim 154285242Sachim /* Incase of TM_DEV_RESET, issue LocalAbort to abort pending IO */ 155285242Sachim if (pccb->flags & DEV_RESET) 156285242Sachim { 157285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Target Reset\n"); 158285242Sachim ccbIO = pccb->pccbIO; 159285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: IO to be aborted locally %p flag %x \n", 160285242Sachim ccbIO, ccbIO->flags); 161285242Sachim if (ccbIO->startTime == 0) /* IO has been completed. No local abort */ 162285242Sachim { 163285242Sachim } 164285242Sachim else if (tiINIIOAbort(&pCard->tiRoot, &ccbIO->tiIORequest) != tiSuccess) 165285242Sachim { 166285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: Local Abort failed\n"); 167285242Sachim /* TODO: call Soft reset here */ 168285242Sachim } 169285242Sachim } 170285242Sachim else if (eventStatus == tiTMFailed) 171285242Sachim { 172285242Sachim ccbIO = pccb->pccbIO; 173285242Sachim if (ccbIO->startTime == 0) /* IO has been completed. */ 174285242Sachim { 175299081Spfg AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed because IO has been completed! pTMccb %p flag %x \n", 176285242Sachim pccb, pccb->flags); 177285242Sachim } 178285242Sachim else 179285242Sachim { 180285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed! pTMccb %p flag %x \n", 181285242Sachim pccb, pccb->flags); 182285242Sachim /* TODO:*/ 183285242Sachim /* if TM_ABORT_TASK, call TM_TARGET_RESET */ 184285242Sachim /* if TM_TARGET_RESET, call Soft_Reset */ 185285242Sachim } 186285242Sachim } 187285242Sachim /* Free TM_DEV_RESET ccb */ 188285242Sachim agtiapi_FreeTMCCB(pCard, pccb); 189285242Sachim } 190285242Sachim } 191285242Sachim break; 192285242Sachim case tiIntrEventTypeLocalAbort: 193285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort!\n"); 194285242Sachim pccb = (pccb_t)((tiIORequest_t *)parm)->osData; 195285242Sachim pccb->flags |= AGTIAPI_CB_DONE; 196285242Sachim if (eventStatus == tiAbortOK) 197285242Sachim { 198285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: taskTag pccb %p flag %x \n", 199285242Sachim pccb, pccb->flags); 200285242Sachim /* If this was LocalAbort for TM ABORT_TASK, issue TM_DEV_RESET */ 201285242Sachim if (pccb->flags & TASK_MANAGEMENT) 202285242Sachim { 203285242Sachim if ((pTMccb = agtiapi_GetCCB(pCard)) == NULL) 204285242Sachim { 205285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM resource unavailable!\n"); 206285242Sachim /* TODO: SoftReset here? */ 207285242Sachim } 208285242Sachim pTMccb->pmcsc = pCard; 209285242Sachim pTMccb->targetId = pccb->targetId; 210285242Sachim pTMccb->devHandle = pccb->devHandle; 211285242Sachim 212285242Sachim /* save pending io to issue local abort at Task mgmt CB */ 213285242Sachim pTMccb->pccbIO = pccb->pccbIO; 214285242Sachim pTMccb->flags &= ~(TASK_SUCCESS | ACTIVE); 215285242Sachim pTMccb->flags |= DEV_RESET; 216285242Sachim if (tiINITaskManagement(&pCard->tiRoot, 217285242Sachim pccb->devHandle, 218285242Sachim AG_TARGET_WARM_RESET, 219285242Sachim &pccb->tiSuperScsiRequest.scsiCmnd.lun, 220285242Sachim &pccb->tiIORequest, 221285242Sachim &pTMccb->tiIORequest) 222285242Sachim == tiSuccess) 223285242Sachim { 224285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request success ccb %p, pTMccb %p\n", 225285242Sachim pccb, pTMccb); 226285242Sachim pTMccb->startTime = ticks; 227285242Sachim } 228285242Sachim else 229285242Sachim { 230285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: TM_TARGET_RESET request failed ccb %p, pTMccb %p\n", 231285242Sachim pccb, pTMccb); 232285242Sachim agtiapi_FreeTMCCB(pCard, pTMccb); 233285242Sachim /* TODO: SoftReset here? */ 234285242Sachim } 235285242Sachim /* Free ABORT_TASK TM ccb */ 236285242Sachim agtiapi_FreeTMCCB(pCard, pccb); 237285242Sachim } 238285242Sachim } 239285242Sachim else if (eventStatus == tiAbortFailed) 240285242Sachim { 241285242Sachim /* TODO: */ 242285242Sachim /* If TM_ABORT_TASK fails, issue TM_DEV_RESET */ 243285242Sachim /* if TM_DEV_RESET fails, issue Soft_Reset */ 244285242Sachim AGTIAPI_PRINTK("tiIntrEventTypeLocalAbort: Abort Failed pccb %p\n", pccb); 245285242Sachim } 246285242Sachim break; 247285242Sachim default: 248285242Sachim AGTIAPI_PRINTK("tiIntrEventType default!\n"); 249285242Sachim break; 250285242Sachim } 251285242Sachim} 252285242Sachim 253285242Sachim 254285242Sachim/****************************************************************************** 255285242SachimostiInitiatorIOCompleted() 256285242Sachim 257285242SachimPurpose: 258285242Sachim IO request completion call back 259285242SachimParameters: 260285242Sachim tiRoot_t *ptiRoot (IN) Pointer to the HBA tiRoot 261285242Sachim tiIORequest_t *ptiIORequest (IN) Pointer to the tiIORequest structure 262285242Sachim tiIOStatus_t IOStatus (IN) I/O complated status 263285242Sachim U32 statusDetail (IN) Additional information on status 264285242Sachim tiSenseData_t *pSensedata (IN) Sense data buffer pointer 265285242Sachim U32 context (IN) Interrupt dealing context 266285242SachimReturns: 267285242SachimNote: 268285242Sachim******************************************************************************/ 269285242Sachimvoid 270285242SachimostiInitiatorIOCompleted(tiRoot_t *ptiRoot, 271285242Sachim tiIORequest_t *ptiIORequest, 272285242Sachim tiIOStatus_t IOStatus, 273285242Sachim U32 statusDetail, 274285242Sachim tiSenseData_t *pSenseData, 275285242Sachim U32 context ) 276285242Sachim{ 277285242Sachim struct agtiapi_softc *pCard; 278285242Sachim ccb_t *pccb; 279285242Sachim 280285242Sachim pCard = TIROOT_TO_CARD(ptiRoot); 281285242Sachim pccb = (ccb_t *)ptiIORequest->osData; 282285242Sachim 283285242Sachim AGTIAPI_IO( "ostiInitiatorIOCompleted: start\n" ); 284285242Sachim 285285242Sachim if (IOStatus == tiIODifError) 286285242Sachim { 287285242Sachim return; 288285242Sachim } 289285242Sachim OSTI_OUT_ENTER(ptiRoot); 290285242Sachim 291285242Sachim pccb->ccbStatus = (U16)IOStatus; 292285242Sachim pccb->scsiStatus = statusDetail; 293285242Sachim 294285242Sachim if ((IOStatus == tiIOSuccess) && (statusDetail == SCSI_CHECK_CONDITION)) 295285242Sachim { 296285242Sachim if (pSenseData == (tiSenseData_t *)agNULL) 297285242Sachim { 298285242Sachim AGTIAPI_PRINTK( "ostiInitiatorIOCompleted: " 299285242Sachim "check condition without sense data!\n" ); 300285242Sachim } 301285242Sachim else 302285242Sachim { 303285242Sachim union ccb *ccb = pccb->ccb; 304285242Sachim struct ccb_scsiio *csio = &ccb->csio; 305285242Sachim int sense_len = 0; 306285242Sachim if (pccb->senseLen > pSenseData->senseLen) 307285242Sachim { 308285242Sachim csio->sense_resid = pccb->senseLen - pSenseData->senseLen; 309285242Sachim } 310285242Sachim else 311285242Sachim { 312285242Sachim csio->sense_resid = 0; 313285242Sachim } 314285242Sachim sense_len = MIN( pSenseData->senseLen, 315285242Sachim pccb->senseLen - csio->sense_resid ); 316295861Spfg bzero(&csio->sense_data, sizeof(csio->sense_data)); 317285242Sachim AGTIAPI_PRINTK("ostiInitiatorIOCompleted: check condition copying\n"); 318285242Sachim memcpy( (void *)pccb->pSenseData, 319285242Sachim pSenseData->senseData, 320285242Sachim sense_len ); 321285242Sachim agtiapi_hexdump( "ostiInitiatorIOCompleted check condition", 322285242Sachim (bit8 *)&csio->sense_data, sense_len ); 323285242Sachim } 324285242Sachim } 325285242Sachim if ((IOStatus == tiIOFailed) && (statusDetail == tiDetailAborted)) 326285242Sachim { 327285242Sachim AGTIAPI_PRINTK("ostiInitiatorIOCompleted - aborted ccb %p, flag %x\n", 328285242Sachim pccb, pccb->flags); 329285242Sachim /* indicate aborted IO completion */ 330285242Sachim pccb->startTime = 0; 331285242Sachim agtiapi_Done(pCard, pccb); 332285242Sachim } 333285242Sachim else 334285242Sachim { 335285242Sachim#ifdef AGTIAPI_SA 336285242Sachim /* 337285242Sachim * SAS no data command does not trigger interrupt. 338285242Sachim * Command is completed in tdlayer and IO completion is called directly. 339285242Sachim * The completed IO therefore is not post processed. 340285242Sachim * Flag is raised and TDTimer will check and process IO for SAS. 341285242Sachim * This is a temporary solution. - Eddie, 07-17-2006 342285242Sachim */ 343285242Sachim pCard->flags |= AGTIAPI_FLAG_UP; 344285242Sachim#endif 345285242Sachim pccb->flags |= REQ_DONE; 346285242Sachim agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail 347285242Sachim AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb); 348285242Sachim } 349285242Sachim OSTI_OUT_LEAVE(ptiRoot); 350285242Sachim return; 351285242Sachim} 352285242Sachim#ifdef HIALEAH_ENCRYPTION 353285242SachimosGLOBAL void 354285242SachimostidisableEncryption(tiRoot_t *ptiRoot) 355285242Sachim{ 356285242Sachim struct agtiapi_softc *pCard; 357285242Sachim pCard = TIROOT_TO_CARD(ptiRoot); 358285242Sachim pCard->encrypt=agFALSE; 359285242Sachim} 360285242Sachim#endif 361285242Sachim/* device Handle */ 362285242SachimosGLOBAL //FORCEINLINE 363285242SachimtiDeviceHandle_t* 364285242SachimostiGetDevHandleFromSasAddr( 365285242Sachim tiRoot_t *root, 366285242Sachim unsigned char *sas_addr 367285242Sachim) 368285242Sachim{ 369285242Sachim int i; 370285242Sachim unsigned long x; 371285242Sachim 372285242Sachim ag_portal_data_t *pPortal = NULL; 373285242Sachim tiDeviceHandle_t *devHandle = NULL; 374285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD(root); 375285242Sachim bit8 sas_addr_hi[4], sas_addr_lo[4]; 376285242Sachim 377285242Sachim 378285242Sachim for(i=0; i<4; i++) 379285242Sachim { 380285242Sachim sas_addr_hi[i] = sas_addr[3-i]; 381285242Sachim } 382285242Sachim 383285242Sachim for(i=0; i<4; i++) 384285242Sachim { 385285242Sachim sas_addr_lo[i] = sas_addr[7-i]; 386285242Sachim } 387285242Sachim 388285242Sachim /* Retrieve the handles for each portal */ 389285242Sachim for (x=0; x < pCard->portCount; x++) 390285242Sachim { 391285242Sachim pPortal = &pCard->pPortalData[x]; 392285242Sachim devHandle = tiINIGetExpDeviceHandleBySasAddress(&pCard->tiRoot, 393285242Sachim &pPortal->portalInfo.tiPortalContext, 394285242Sachim *(bit32*)sas_addr_hi, 395285242Sachim *(bit32*)sas_addr_lo, 396285242Sachim (bit32)1024/*gMaxTargets*/); 397285242Sachim if(devHandle != NULL) 398285242Sachim break; 399285242Sachim } 400285242Sachim return devHandle; 401285242Sachim 402285242Sachim return NULL; 403285242Sachim} 404285242Sachim/****************************************************************************** 405285242SachimostiInitiatorSMPCompleted() 406285242Sachim 407285242SachimPurpose: 408285242Sachim IO request completion call back 409285242SachimParameters: 410285242Sachim tiRoot_t *ptiRoot (IN) Pointer to the HBA tiRoot 411285242Sachim tiIORequest_t *ptiSMPRequest (IN) Pointer to the SMP request structure 412285242Sachim tiIOStatus_t IOStatus (IN) I/O complated status 413285242Sachim U32 tiSMPInfoLen (IN) Number of bytes of response frame len 414285242Sachim tiFrameHandle (IN) Handle that referes to response frame 415285242Sachim U32 context (IN) Interrupt dealing context 416285242SachimReturns: 417285242SachimNote: 418285242Sachim******************************************************************************/ 419285242Sachimvoid 420285242SachimostiInitiatorSMPCompleted(tiRoot_t *ptiRoot, 421285242Sachim tiIORequest_t *ptiSMPRequest, 422285242Sachim tiSMPStatus_t smpStatus, 423285242Sachim bit32 tiSMPInfoLen, 424285242Sachim void *tiFrameHandle, 425285242Sachim bit32 context) 426285242Sachim{ 427285242Sachim struct agtiapi_softc *pCard; 428285242Sachim ccb_t *pccb; 429285242Sachim pCard = TIROOT_TO_CARD(ptiRoot); 430285242Sachim pccb = (ccb_t *)ptiSMPRequest->osData; 431285242Sachim 432285242Sachim AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: start\n"); 433285242Sachim 434285242Sachim OSTI_OUT_ENTER(ptiRoot); 435285242Sachim pccb->ccbStatus = (U16)smpStatus; 436285242Sachim if(smpStatus != tiSMPSuccess) 437285242Sachim { 438285242Sachim AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: SMP Error\n"); 439285242Sachim } 440285242Sachim else 441285242Sachim { 442285242Sachim union ccb *ccb = pccb->ccb; 443285242Sachim struct ccb_smpio *csmpio = &ccb->smpio; 444285242Sachim memcpy(csmpio->smp_response, tiFrameHandle, tiSMPInfoLen); 445285242Sachim csmpio->smp_response_len = tiSMPInfoLen; 446299081Spfg agtiapi_hexdump("ostiInitiatorSMPCompleted: Response Payload in CAM", (bit8 *)csmpio->smp_response, csmpio->smp_response_len); 447285242Sachim } 448285242Sachim pccb->flags |= REQ_DONE; 449285242Sachim agtiapi_QueueCCB(pCard, &pCard->smpDoneHead, &pCard->smpDoneTail 450285242Sachim AG_CARD_LOCAL_LOCK(&pCard->doneSMPLock), pccb); 451285242Sachim AGTIAPI_PRINTK("ostiInitiatorSMPCompleted: Done\n"); 452285242Sachim OSTI_OUT_LEAVE(ptiRoot); 453285242Sachim 454285242Sachim return; 455285242Sachim} 456285242Sachim 457285242Sachim#ifdef FAST_IO_TEST 458285242Sachimvoid 459285242Sachimosti_FastIOCb(tiRoot_t *ptiRoot, 460285242Sachim void *arg, 461285242Sachim tiIOStatus_t IOStatus, 462285242Sachim U32 statusDetail) 463285242Sachim{ 464285242Sachim ccb_t *pccb = (ccb_t*)arg; 465285242Sachim ag_card_t *pCard; 466285242Sachim 467285242Sachim static int callNum = 0; 468285242Sachim 469285242Sachim callNum++; 470285242Sachim 471285242Sachim BUG_ON(!pccb); 472285242Sachim 473285242Sachim if ((callNum % CMDS_PER_IO_DUP) != 0) 474285242Sachim { 475285242Sachim goto err; 476285242Sachim } 477285242Sachim 478285242Sachim pccb->ccbStatus = IOStatus; 479285242Sachim pccb->scsiStatus = statusDetail; 480285242Sachim 481285242Sachim /* pccb->pSenseData is copied already */ 482285242Sachim 483285242Sachim if (pccb->flags & AGTIAPI_ABORT) 484285242Sachim { 485285242Sachim AGTIAPI_PRINTK("agtiapi_SuperIOCb: aborted ccb %p, flag %x\n", 486285242Sachim pccb, pccb->flags); 487285242Sachim pccb->startTime = 0; /* indicate aborted IO completion */ 488285242Sachim BUG_ON(1); 489285242Sachim goto err; 490285242Sachim } 491285242Sachim pCard = TIROOT_TO_CARD(ptiRoot); 492285242Sachim pccb->flags |= REQ_DONE; 493285242Sachim agtiapi_QueueCCB(pCard, &pCard->ccbDoneHead, &pCard->ccbDoneTail 494285242Sachim AG_CARD_LOCAL_LOCK(&pCard->doneLock), pccb); 495285242Sachimerr: 496285242Sachim return; 497285242Sachim} /* osti_FastIOCb */ 498285242Sachim#endif 499285242Sachim 500285242Sachim 501285242Sachim/****************************************************************************** 502285242SachimostiSingleThreadedEnter() 503285242Sachim 504285242SachimPurpose: 505285242Sachim Critical region code excution protection. 506285242SachimParameters: 507285242Sachim tiRoot_t *ptiRoot (IN) Pointer to tiRoot data structure 508285242Sachim U32 queueId (IN) spinlock Id 509285242SachimReturns: 510285242SachimNote: 511285242Sachim Lock is held by oslayer. 512285242Sachim******************************************************************************/ 513285242Sachimvoid 514285242SachimostiSingleThreadedEnter(tiRoot_t *ptiRoot, U32 queueId) 515285242Sachim{ 516285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot); 517285242Sachim mtx_lock( &pCard->STLock[queueId] ); // review: need irq save? ## 518285242Sachim} 519285242Sachim 520285242Sachim 521285242Sachim/****************************************************************************** 522285242SachimostiSingleThreadedLeave() 523285242Sachim 524285242SachimPurpose: 525285242Sachim Restore multi-threading environment. 526285242SachimParameters: 527285242Sachim tiRoot_t *ptiRoot (IN) Pointer to the tiRoot data structure 528285242Sachim U32 queueId (IN) spinlock Id 529285242SachimReturns: 530285242SachimNote: 531285242Sachim Lock is held by oslayer. 532285242Sachim******************************************************************************/ 533285242Sachimvoid 534285242SachimostiSingleThreadedLeave(tiRoot_t *ptiRoot, U32 queueId) 535285242Sachim{ 536285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD(ptiRoot); 537285242Sachim mtx_unlock( &pCard->STLock[queueId] ); // review: need irq restore? ## 538285242Sachim} 539285242Sachim 540285242Sachim 541285242SachimosGLOBAL tiDeviceHandle_t* 542285242SachimostiMapToDevHandle(tiRoot_t *root, 543285242Sachim bit8 pathId, 544285242Sachim bit8 targetId, 545285242Sachim bit8 LUN 546285242Sachim ) 547285242Sachim{ 548285242Sachim tiDeviceHandle_t *dev = NULL; 549285242Sachim struct agtiapi_softc *pCard; 550285242Sachim bit32 offset; 551285242Sachim 552285242Sachim pCard = TIROOT_TO_CARD(root); 553285242Sachim 554285242Sachim offset = pathId * pCard->tgtCount + targetId; 555285242Sachim 556285242Sachim if (offset > (pCard->tgtCount - 1) ) 557285242Sachim { 558285242Sachim dev = NULL; 559285242Sachim } 560285242Sachim else 561285242Sachim { 562285242Sachim dev = pCard->pDevList[offset].pDevHandle; 563285242Sachim } 564285242Sachim 565285242Sachim return dev; 566285242Sachim} 567285242Sachim 568285242Sachim 569285242Sachim 570285242Sachim#ifdef PERF_COUNT 571285242Sachim 572285242Sachim#ifdef AGTIAPI_LOCAL_LOCK 573285242Sachim#define OSTI_SPIN_LOCK(lock) spin_lock(lock) 574285242Sachim#define OSTI_SPIN_UNLOCK(lock) spin_unlock(lock) 575285242Sachim#else 576285242Sachim#define OSTI_SPIN_LOCK(lock) 577285242Sachim#define OSTI_SPIN_UNLOCK(lock) 578285242Sachim#endif 579285242Sachim 580285242Sachim 581285242Sachimvoid 582285242SachimostiEnter(tiRoot_t *ptiRoot, U32 layer, int io) 583285242Sachim{ 584285242Sachim ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard; 585285242Sachim int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME); 586285242Sachim 587285242Sachim BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2)); 588285242Sachim if (!ini) 589285242Sachim { 590285242Sachim unsigned long long cycles = get_cycles(); 591285242Sachim 592285242Sachim OSTI_SPIN_LOCK(&pCard->latLock); 593285242Sachim BUG_ON(pCard->callLevel[io] >= sizeof(pCard->layer[0]) / 594285242Sachim sizeof(pCard->layer[0][0])); 595285242Sachim if (pCard->callLevel[io] > 0) 596285242Sachim { 597285242Sachim unsigned int prev_layer = pCard->layer[io][pCard->callLevel[io] - 1]; 598285242Sachim 599285242Sachim pCard->totalCycles[io][prev_layer] += cycles - 600285242Sachim pCard->enterCycles[io][prev_layer]; 601285242Sachim } 602285242Sachim pCard->enterCycles[io][layer] = cycles; 603285242Sachim pCard->layer[io][pCard->callLevel[io]] = layer; 604285242Sachim pCard->callLevel[io]++; 605285242Sachim OSTI_SPIN_UNLOCK(&pCard->latLock); 606285242Sachim } 607285242Sachim} 608285242Sachim 609285242Sachimvoid 610285242SachimostiLeave(tiRoot_t *ptiRoot, U32 layer, int io) 611285242Sachim{ 612285242Sachim ag_card_t *pCard = ((ag_card_info_t*)ptiRoot->osData)->pCard; 613285242Sachim int ini = ((pCard->flags & AGTIAPI_INIT_TIME) == AGTIAPI_INIT_TIME); 614285242Sachim 615285242Sachim BUG_ON((io != 0 && io != 1) || (layer != 0 && layer != 1 && layer != 2)); 616285242Sachim if (!ini) 617285242Sachim { 618285242Sachim unsigned long long cycles = get_cycles(); 619285242Sachim 620285242Sachim OSTI_SPIN_LOCK(&pCard->latLock); 621285242Sachim pCard->callLevel[io]--; 622285242Sachim 623285242Sachim BUG_ON(pCard->callLevel[io] < 0); 624285242Sachim BUG_ON(pCard->layer[io][pCard->callLevel[io]] != layer); 625285242Sachim 626285242Sachim pCard->totalCycles[io][layer] += cycles - pCard->enterCycles[io][layer]; 627285242Sachim if (pCard->callLevel[io] > 0) 628285242Sachim pCard->enterCycles[io][pCard->layer[io][pCard->callLevel[io] - 1]] = 629285242Sachim cycles; 630285242Sachim OSTI_SPIN_UNLOCK(&pCard->latLock); 631285242Sachim } 632285242Sachim} 633285242Sachim#endif 634285242Sachim 635285242Sachim 636285242Sachim 637285242SachimosGLOBAL FORCEINLINE bit8 638285242SachimostiBitScanForward( 639285242Sachim tiRoot_t *root, 640285242Sachim bit32 *Index, 641285242Sachim bit32 Mask 642285242Sachim ) 643285242Sachim{ 644285242Sachim return 1; 645285242Sachim 646285242Sachim} 647285242Sachim 648285242Sachim#ifdef REMOVED 649285242SachimosGLOBAL sbit32 650285242SachimostiAtomicIncrement( 651285242Sachim tiRoot_t *root, 652285242Sachim sbit32 volatile *Addend 653285242Sachim ) 654285242Sachim{ 655285242Sachim return 1; 656285242Sachim 657285242Sachim} 658285242Sachim 659285242SachimosGLOBAL sbit32 660285242SachimostiAtomicDecrement( 661285242Sachim tiRoot_t *root, 662285242Sachim sbit32 volatile *Addend 663285242Sachim ) 664285242Sachim{ 665285242Sachim 666285242Sachim return 1; 667285242Sachim 668285242Sachim} 669285242Sachim 670285242SachimosGLOBAL sbit32 671285242SachimostiAtomicBitClear( 672285242Sachim tiRoot_t *root, 673285242Sachim sbit32 volatile *Destination, 674285242Sachim sbit32 Value 675285242Sachim ) 676285242Sachim{ 677285242Sachim 678285242Sachim return 0; 679285242Sachim 680285242Sachim} 681285242Sachim 682285242SachimosGLOBAL sbit32 683285242SachimostiAtomicBitSet( 684285242Sachim tiRoot_t *root, 685285242Sachim sbit32 volatile *Destination, 686285242Sachim sbit32 Value 687285242Sachim ) 688285242Sachim{ 689285242Sachim return 0; 690285242Sachim 691285242Sachim /* 692285242Sachim set_bit(Value, (volatile unsigned long *)Destination); 693285242Sachim return 0; 694285242Sachim */ 695285242Sachim} 696285242Sachim 697285242SachimosGLOBAL sbit32 698285242SachimostiAtomicExchange( 699285242Sachim tiRoot_t *root, 700285242Sachim sbit32 volatile *Target, 701285242Sachim sbit32 Value 702285242Sachim ) 703285242Sachim{ 704285242Sachim return 0; 705285242Sachim 706285242Sachim} 707285242Sachim#endif 708285242Sachim 709285242SachimosGLOBAL FORCEINLINE sbit32 710285242SachimostiInterlockedExchange( 711285242Sachim tiRoot_t *root, 712285242Sachim sbit32 volatile *Target, 713285242Sachim sbit32 Value 714285242Sachim ) 715285242Sachim{ 716285242Sachim return 0; 717285242Sachim} 718285242Sachim 719285242SachimosGLOBAL FORCEINLINE sbit32 720285242SachimostiInterlockedIncrement( 721285242Sachim tiRoot_t *root, 722285242Sachim sbit32 volatile *Addend 723285242Sachim ) 724285242Sachim{ 725285242Sachim return 0; 726285242Sachim} 727285242Sachim 728285242SachimosGLOBAL FORCEINLINE sbit32 729285242SachimostiInterlockedDecrement( 730285242Sachim tiRoot_t *root, 731285242Sachim sbit32 volatile *Addend 732285242Sachim ) 733285242Sachim{ 734285242Sachim return 0; 735285242Sachim} 736285242Sachim 737285242SachimosGLOBAL FORCEINLINE sbit32 738285242SachimostiInterlockedAnd( 739285242Sachim tiRoot_t *root, 740285242Sachim sbit32 volatile *Destination, 741285242Sachim sbit32 Value 742285242Sachim ) 743285242Sachim{ 744285242Sachim return 0; 745285242Sachim} 746285242Sachim 747285242SachimosGLOBAL FORCEINLINE sbit32 748285242SachimostiInterlockedOr( 749285242Sachim tiRoot_t *root, 750285242Sachim sbit32 volatile *Destination, 751285242Sachim sbit32 Value 752285242Sachim ) 753285242Sachim{ 754285242Sachim return 0; 755285242Sachim} 756285242Sachim 757285242Sachim// this is just stub code to allow compile and use of the module ... 758285242Sachim// now that a call to this function has been added with windows specific 759285242Sachim// intentions. 760285242SachimosGLOBAL bit32 761285242SachimostiSetDeviceQueueDepth( tiRoot_t *tiRoot, 762285242Sachim tiIORequest_t *tiIORequest, 763285242Sachim bit32 QueueDepth 764285242Sachim ) 765285242Sachim{ 766285242Sachim bit32 retVal = 0; 767285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD(tiRoot); 768285242Sachim ccb_t *pccb = (ccb_t *) tiIORequest->osData; 769285242Sachim tiDeviceHandle_t *tiDeviceHandle = pccb->devHandle; 770285242Sachim ag_device_t *pDevice = (ag_device_t *)tiDeviceHandle->osData; 771285242Sachim AGTIAPI_PRINTK( "ostiSetDeviceQueueDepth stub only: root%p, req%p, qdeep%d\n", 772285242Sachim tiRoot, tiIORequest, QueueDepth ); 773285242Sachim pDevice->qdepth = QueueDepth; 774285242Sachim return retVal; 775285242Sachim} 776285242Sachim 777285242Sachim 778285242Sachim// this is just stub code to allow compile and use of the module ... 779285242Sachim// now that a call to this function has been added with windows specific 780285242Sachim// intentions. 781285242SachimosGLOBAL void 782285242SachimostiGetSenseKeyCount(tiRoot_t *root, 783285242Sachim bit32 fIsClear, 784285242Sachim void *SenseKeyCount, 785285242Sachim bit32 length 786285242Sachim ) 787285242Sachim{ 788285242Sachim AGTIAPI_PRINTK( "ostiGetSenseKeyCount stub only: rt%p, fcl%d, kyCt%p, ln%d\n", 789285242Sachim root, fIsClear, SenseKeyCount, length ); 790285242Sachim} 791285242Sachim 792285242SachimosGLOBAL void 793285242SachimostiGetSCSIStatusCount(tiRoot_t *root, 794285242Sachim bit32 fIsClear, 795285242Sachim void *ScsiStatusCount, 796285242Sachim bit32 length 797285242Sachim ) 798285242Sachim{ 799285242Sachim AGTIAPI_PRINTK( "ostiGetSCSIStatusCount: stub only rt%p, fcl%d, kyCt%p, ln%d\n", 800285242Sachim root, fIsClear, ScsiStatusCount, length ); 801285242Sachim 802285242Sachim} 803285242Sachim 804285242SachimosGLOBAL void ostiPCI_TRIGGER( tiRoot_t *tiRoot ) 805285242Sachim{ 806285242Sachim ostiChipReadBit32Ext(tiRoot, 0, 0x5C); 807285242Sachim 808285242Sachim} 809285242Sachim 810285242SachimosGLOBAL bit32 811285242SachimostiNumOfLUNIOCTLreq( tiRoot_t *root, 812285242Sachim void *param1, 813285242Sachim void *param2, 814285242Sachim void **tiRequestBody, 815285242Sachim tiIORequest_t **tiIORequest 816285242Sachim ) 817285242Sachim{ 818285242Sachim bit32 status = IOCTL_CALL_SUCCESS; 819285242Sachim pccb_t pccb; 820285242Sachim AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq: start\n"); 821285242Sachim struct agtiapi_softc *pCard = TIROOT_TO_CARD(root); 822285242Sachim /* get a ccb */ 823285242Sachim if ((pccb = agtiapi_GetCCB(pCard)) == NULL) 824285242Sachim { 825285242Sachim printf("ostiNumOfLUNIOCTLreq - GetCCB ERROR\n"); 826285242Sachim status = IOCTL_CALL_FAIL; 827285242Sachim //BUG_ON(1); 828285242Sachim } 829285242Sachim 830285242Sachim *tiIORequest = (tiIORequest_t*)&pccb->tiIORequest; 831285242Sachim *tiRequestBody = &pccb->tdIOReqBody; 832285242Sachim AGTIAPI_PRINTK("ostiNumOfLUNIOCTLreq:end\n"); 833285242Sachim return status; 834285242Sachim} 835285242Sachim 836