1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *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 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 ********************************************************************************/ 21 /*******************************************************************************/ 22 /** \file 23 * 24 * $RCSfile: ttdinit.c,v $ 25 * 26 * Copyright 2006 PMC-Sierra, Inc. 27 * 28 * $Author: vempatin $ 29 * $Revision: 113679 $ 30 * $Date: 2012-04-16 14:35:19 -0700 (Mon, 16 Apr 2012) $ 31 * 32 * This file contains initiator IO related functions in TD layer 33 * 34 */ 35 #include <osenv.h> 36 #include <ostypes.h> 37 #include <osdebug.h> 38 39 #include <sa.h> 40 #include <saapi.h> 41 #include <saosapi.h> 42 43 #include <titypes.h> 44 #include <ostiapi.h> 45 #include <tiapi.h> 46 #include <tiglobal.h> 47 48 #include <tdtypes.h> 49 #include <osstring.h> 50 #include <tdutil.h> 51 52 #ifdef INITIATOR_DRIVER 53 #include <itdtypes.h> 54 #include <itddefs.h> 55 #include <itdglobl.h> 56 #endif 57 58 #ifdef TARGET_DRIVER 59 #include "ttdglobl.h" 60 #include "ttdtxchg.h" 61 #include "ttdtypes.h" 62 #endif 63 64 #include <tdsatypes.h> 65 #include <tdproto.h> 66 67 /* io trace only */ 68 extern void TDTraceInit(void); 69 /* io trace only */ 70 71 72 osGLOBAL bit32 73 ttdssInit( 74 tiRoot_t *tiRoot, 75 tiTargetResource_t *targetResource, 76 tiTdSharedMem_t *tdSharedMem 77 ) 78 { 79 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 80 tiTargetMem_t *tgtMem; 81 ttdsaTgt_t *Target; 82 ttdssOperatingOption_t *OperatingOption; 83 char *buffer; 84 bit32 buffLen; 85 bit32 lenRecv = 0; 86 char *pLastUsedChar = agNULL; 87 char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE]; 88 char globalStr[] = "OSParms"; 89 90 TI_DBG5(("ttdssInit: start\n")); 91 92 /* 93 first set the values to Default values 94 Then, overwrite them using ostiGetTransportParam() 95 */ 96 97 /* to remove compiler warnings */ 98 buffer = &tmpBuffer[0]; 99 buffLen = sizeof (tmpBuffer); 100 101 osti_memset(buffer, 0, buffLen); 102 103 tgtMem = &targetResource->targetMem; 104 105 /* 106 * Cached mem for target Transport Dependent Layer main functionality 107 */ 108 Target = tgtMem->tdMem[0].virtPtr; 109 110 OperatingOption = &Target->OperatingOption; 111 /* 112 * Get default parameters from the OS Specific area 113 * and reads parameters from the configuration file 114 */ 115 ttdssGetOperatingOptionParams(tiRoot, OperatingOption); 116 117 118 /* 119 * Update TD operating options 120 */ 121 OperatingOption->UsecsPerTick = 122 targetResource->targetOption.usecsPerTick; 123 OperatingOption->numXchgs = tgtMem->tdMem[1].numElements; 124 125 126 if (ttdsaXchgInit(tiRoot, 127 &Target->ttdsaXchgData, 128 tgtMem, 129 OperatingOption->numXchgs 130 ) == agFALSE) 131 { 132 TI_DBG1(("ttdInit: ttdsaXchgInit failed\n")); 133 return tiError; 134 } 135 136 /* Get number of AutoGoodResponse entry */ 137 if ((ostiGetTransportParam( 138 tiRoot, 139 globalStr, 140 agNULL, 141 agNULL, 142 agNULL, 143 agNULL, 144 agNULL, 145 "AutoGoodResponse", 146 buffer, 147 buffLen, 148 &lenRecv 149 ) == tiSuccess) && (lenRecv != 0)) 150 { 151 if (osti_strncmp(buffer, "0x", 2) == 0) 152 { 153 tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 0); 154 } 155 else 156 { 157 tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 10); 158 } 159 160 } 161 162 return tiSuccess; 163 } 164 165 /* 166 this combines ttdGetDefaultParams and ttdGetTargetParms 167 168 */ 169 osGLOBAL void 170 ttdssGetOperatingOptionParams( 171 tiRoot_t *tiRoot, 172 ttdssOperatingOption_t *OperatingOption 173 ) 174 { 175 char *key = agNULL; 176 char *subkey1 = agNULL; 177 char *subkey2 = agNULL; 178 char *buffer; 179 bit32 buffLen; 180 bit32 lenRecv = 0; 181 char *pLastUsedChar = agNULL; 182 char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE]; 183 char globalStr[] = "Global"; 184 char iniParmsStr[] = "TargetParms"; 185 186 TI_DBG5(("ttdssGetOperatingOptionParams: start\n")); 187 188 /* 189 first set the values to Default values 190 Then, overwrite them using ostiGetTransportParam() 191 */ 192 193 194 /* to remove compiler warnings */ 195 pLastUsedChar = pLastUsedChar; 196 lenRecv = lenRecv; 197 subkey2 = subkey2; 198 subkey1 = subkey1; 199 key = key; 200 buffer = &tmpBuffer[0]; 201 buffLen = sizeof (tmpBuffer); 202 203 osti_memset(buffer, 0, buffLen); 204 205 206 /* in ttgglobl.h */ 207 OperatingOption->numXchgs = DEFAULT_XCHGS; 208 OperatingOption->UsecsPerTick = DEFAULT_TGT_TIMER_TICK; /* 1 sec */ 209 OperatingOption->MaxTargets = DEFAULT_MAX_TARGETS; 210 OperatingOption->BlockSize = DEFAULT_BLOCK_SIZE; 211 212 213 /* defaults are overwritten in the following */ 214 /* Get number of exchanges */ 215 if ((ostiGetTransportParam( 216 tiRoot, 217 globalStr, 218 iniParmsStr, 219 agNULL, 220 agNULL, 221 agNULL, 222 agNULL, 223 "NumberExchanges", 224 buffer, 225 buffLen, 226 &lenRecv 227 ) == tiSuccess) && (lenRecv != 0)) 228 { 229 if (osti_strncmp(buffer, "0x", 2) == 0) 230 { 231 OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 0); 232 } 233 else 234 { 235 OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 10); 236 } 237 238 } 239 240 osti_memset(buffer, 0, buffLen); 241 lenRecv = 0; 242 243 /* Get number of MaxTargets */ 244 if ((ostiGetTransportParam( 245 tiRoot, 246 globalStr, 247 iniParmsStr, 248 agNULL, 249 agNULL, 250 agNULL, 251 agNULL, 252 "MaxTargets", 253 buffer, 254 buffLen, 255 &lenRecv 256 ) == tiSuccess) && (lenRecv != 0)) 257 { 258 if (osti_strncmp(buffer, "0x", 2) == 0) 259 { 260 OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 0); 261 } 262 else 263 { 264 OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 10); 265 } 266 267 } 268 osti_memset(buffer, 0, buffLen); 269 lenRecv = 0; 270 271 /* Get number of BlockSize */ 272 if ((ostiGetTransportParam( 273 tiRoot, 274 globalStr, 275 iniParmsStr, 276 agNULL, 277 agNULL, 278 agNULL, 279 agNULL, 280 "BlockSize", 281 buffer, 282 buffLen, 283 &lenRecv 284 ) == tiSuccess) && (lenRecv != 0)) 285 { 286 if (osti_strncmp(buffer, "0x", 2) == 0) 287 { 288 OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 0); 289 } 290 else 291 { 292 OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 10); 293 } 294 } 295 osti_memset(buffer, 0, buffLen); 296 lenRecv = 0; 297 298 299 300 TI_DBG5(("ttdssGetOperatingOptionParams: NumberExchanges %d UsecsPerTick %d MaxTargets %d BlockSize %d\n", OperatingOption->numXchgs, OperatingOption->UsecsPerTick, OperatingOption->MaxTargets, OperatingOption->BlockSize)); 301 302 return; 303 } 304 305 /* not yet */ 306 osGLOBAL void 307 ttdssGetResource( 308 tiRoot_t *tiRoot, 309 tiTargetResource_t *targetResource 310 ) 311 { 312 tiTargetMem_t *tgtMem; 313 int i; 314 ttdssOperatingOption_t OperatingOption; 315 bit32 xchgSize; 316 bit32 respSize; 317 bit32 smprespSize; 318 319 TI_DBG4(("ttdssGetResource: start\n")); 320 321 tgtMem = &targetResource->targetMem; 322 323 /* 324 only 4 memory descriptors are used 325 */ 326 tgtMem->count = 4; 327 328 /* initiailization */ 329 for (i = 0 ; i < 10 ; i++) 330 { 331 tgtMem->tdMem[i].singleElementLength = 0; 332 tgtMem->tdMem[i].numElements = 0; 333 tgtMem->tdMem[i].totalLength = 0; 334 tgtMem->tdMem[i].alignment = 0; 335 tgtMem->tdMem[i].type = TI_CACHED_MEM; 336 tgtMem->tdMem[i].reserved = 0; 337 tgtMem->tdMem[i].virtPtr = agNULL; 338 tgtMem->tdMem[i].osHandle = agNULL; 339 tgtMem->tdMem[i].physAddrUpper = 0; 340 tgtMem->tdMem[i].physAddrLower = 0; 341 } 342 343 /* 344 * Get default parameters from the OS Specific area 345 * and reads parameters from the configuration file 346 */ 347 ttdssGetOperatingOptionParams(tiRoot, &OperatingOption); 348 349 /* target */ 350 tgtMem->tdMem[0].singleElementLength = sizeof(ttdsaTgt_t); 351 tgtMem->tdMem[0].numElements = 1; 352 tgtMem->tdMem[0].totalLength = 353 tgtMem->tdMem[0].singleElementLength * 354 tgtMem->tdMem[0].numElements; 355 tgtMem->tdMem[0].alignment = sizeof (void *); 356 tgtMem->tdMem[0].type = TI_CACHED_MEM; 357 tgtMem->tdMem[0].reserved = 0; 358 tgtMem->tdMem[0].virtPtr = agNULL; 359 tgtMem->tdMem[0].osHandle = agNULL; 360 tgtMem->tdMem[0].physAddrUpper = 0; 361 tgtMem->tdMem[0].physAddrLower = 0; 362 363 /* 364 * Cached memory for I/O exchange structures 365 */ 366 xchgSize = sizeof(ttdsaXchg_t); 367 xchgSize = AG_ALIGNSIZE(xchgSize, 8); 368 369 tgtMem->tdMem[1].singleElementLength = xchgSize; 370 tgtMem->tdMem[1].numElements = OperatingOption.numXchgs; 371 tgtMem->tdMem[1].totalLength = tgtMem->tdMem[1].singleElementLength * 372 tgtMem->tdMem[1].numElements; 373 tgtMem->tdMem[1].alignment = sizeof(void *); 374 tgtMem->tdMem[1].type = TI_CACHED_MEM; 375 tgtMem->tdMem[1].reserved = 0; 376 tgtMem->tdMem[1].virtPtr = agNULL; 377 tgtMem->tdMem[1].osHandle = agNULL; 378 tgtMem->tdMem[1].physAddrUpper = 0; 379 tgtMem->tdMem[1].physAddrLower = 0; 380 381 /* 382 * Uncached memory for response buffer structures 383 */ 384 TI_DBG4(("ttdssGetResource: sas_resp_t size 0x%x %d\n", 385 (unsigned int)sizeof(sas_resp_t), (int)sizeof(sas_resp_t))); 386 387 respSize = (sizeof(sas_resp_t) + AG_WORD_ALIGN_ADD) & AG_WORD_ALIGN_MASK; 388 TI_DBG4(("ttdssGetResource: response size 0x%x %d\n", respSize,respSize)); 389 respSize = AG_ALIGNSIZE(respSize, 8); 390 TI_DBG4(("ttdssGetResource: response size 0x%x %d\n", respSize,respSize)); 391 tgtMem->tdMem[2].singleElementLength = 0x1000; /* respSize; 0x1000; */ 392 tgtMem->tdMem[2].numElements = OperatingOption.numXchgs; /* Same as num of xchg */ 393 tgtMem->tdMem[2].totalLength = tgtMem->tdMem[2].singleElementLength * 394 tgtMem->tdMem[2].numElements; 395 /* 8;4;16;256;sizeof(void *); all worked */ 396 tgtMem->tdMem[2].alignment = 16; 397 tgtMem->tdMem[2].type = TI_DMA_MEM; /* uncached memory */ 398 tgtMem->tdMem[2].reserved = 0; 399 tgtMem->tdMem[2].virtPtr = agNULL; 400 tgtMem->tdMem[2].osHandle = agNULL; 401 tgtMem->tdMem[2].physAddrUpper = 0; 402 tgtMem->tdMem[2].physAddrLower = 0; 403 404 /* 405 * Uncached memory for SMP response buffer structures 406 */ 407 smprespSize = sizeof(smp_resp_t); 408 smprespSize = AG_ALIGNSIZE(smprespSize, 8); 409 TI_DBG4(("ttdssGetResource: SMP response size 0x%x %d\n", smprespSize,smprespSize)); 410 411 tgtMem->tdMem[3].singleElementLength = smprespSize; /*0x1000; smprespSize; */ 412 tgtMem->tdMem[3].numElements = OperatingOption.numXchgs; /* Same as num of xchg */ 413 tgtMem->tdMem[3].totalLength 414 = tgtMem->tdMem[3].singleElementLength * tgtMem->tdMem[3].numElements; 415 tgtMem->tdMem[3].alignment = 16; /* 4; 256; 16; sizeof(void *); */ 416 tgtMem->tdMem[3].type = TI_DMA_MEM; /* uncached memory */ 417 tgtMem->tdMem[3].reserved = 0; 418 tgtMem->tdMem[3].virtPtr = agNULL; 419 tgtMem->tdMem[3].osHandle = agNULL; 420 tgtMem->tdMem[3].physAddrUpper = 0; 421 tgtMem->tdMem[3].physAddrLower = 0; 422 423 424 425 targetResource->targetOption.usecsPerTick = OperatingOption.UsecsPerTick; 426 targetResource->targetOption.pageSize = 0; /* not applicable to SAS/SATA */ 427 targetResource->targetOption.numLgns = 0; /* not applicable to SAS/SATA */ 428 targetResource->targetOption.numSessions = 0; /* not applicable to SAS/SATA */ 429 targetResource->targetOption.numXchgs = OperatingOption.numXchgs; 430 431 432 /* 433 This is not used in OS like Linux which supports dynamic memeory allocation 434 In short, this is for Windows 435 */ 436 /* Estimate dynamic DMA memory */ 437 targetResource->targetOption.dynamicDmaMem.alignment = sizeof(void *); 438 439 targetResource->targetOption.dynamicDmaMem.numElements = 128; 440 targetResource->targetOption.dynamicDmaMem.singleElementLength = sizeof(tdssSMPRequestBody_t); 441 targetResource->targetOption.dynamicDmaMem.totalLength = 442 targetResource->targetOption.dynamicDmaMem.numElements * 443 targetResource->targetOption.dynamicDmaMem.singleElementLength; 444 445 /* Estimate dynamic cached memory */ 446 targetResource->targetOption.dynamicCachedMem.alignment = sizeof(void *); 447 targetResource->targetOption.dynamicCachedMem.numElements = 128; 448 targetResource->targetOption.dynamicCachedMem.singleElementLength = sizeof(tdssSMPRequestBody_t); 449 targetResource->targetOption.dynamicCachedMem.totalLength = 450 targetResource->targetOption.dynamicCachedMem.numElements * 451 targetResource->targetOption.dynamicCachedMem.singleElementLength; 452 453 454 return; 455 } 456 457 /* not in use */ 458 osGLOBAL void 459 ttdssGetTargetParams( 460 tiRoot_t *tiRoot 461 ) 462 { 463 TI_DBG6(("ttdssGetTargetParams: start\n")); 464 return; 465 } 466 467 osGLOBAL agBOOLEAN 468 ttdsaXchgInit( 469 tiRoot_t *tiRoot, 470 ttdsaXchgData_t *ttdsaXchgData, 471 tiTargetMem_t *tgtMem, 472 bit32 maxNumXchgs 473 ) 474 { 475 ttdsaXchg_t *ttdsaXchg; 476 bit32 i, respLen; 477 bit8 *virtualAddr; 478 bit32 phyAddrLower, phyAddrUpper; 479 bit32 smprespLen; 480 bit32 smpphyAddrLower, smpphyAddrUpper; 481 bit8 *smpvirtualAddr; 482 483 484 485 TI_DBG5(("ttdsaXchgInit: start\n")); 486 /* io trace only */ 487 TDTraceInit(); 488 /* io trace only */ 489 490 /* 491 * Set and initialize some global exchange information 492 */ 493 TDLIST_INIT_HDR(&ttdsaXchgData->xchgFreeList); 494 TDLIST_INIT_HDR(&ttdsaXchgData->xchgBusyList); 495 496 ttdsaXchgData->maxNumXchgs = maxNumXchgs; 497 498 /* Initialize exchange and response buffer structures */ 499 ttdsaXchg = (ttdsaXchg_t *) tgtMem->tdMem[1].virtPtr; 500 501 /* Initialize response buffer */ 502 virtualAddr = tgtMem->tdMem[2].virtPtr; 503 phyAddrUpper = tgtMem->tdMem[2].physAddrUpper; 504 phyAddrLower = tgtMem->tdMem[2].physAddrLower; 505 respLen = tgtMem->tdMem[2].singleElementLength; 506 507 ttdsaXchg->resp.virtAddr = virtualAddr; 508 ttdsaXchg->resp.phyAddrUpper = phyAddrUpper; 509 ttdsaXchg->resp.phyAddrLower = phyAddrLower; 510 ttdsaXchg->resp.length = respLen; 511 512 /* Initialize SMP response buffer */ 513 smpvirtualAddr = tgtMem->tdMem[3].virtPtr; 514 smpphyAddrUpper = tgtMem->tdMem[3].physAddrUpper; 515 smpphyAddrLower = tgtMem->tdMem[3].physAddrLower; 516 smprespLen = tgtMem->tdMem[3].singleElementLength; 517 518 ttdsaXchg->smpresp.virtAddr = smpvirtualAddr; 519 ttdsaXchg->smpresp.phyAddrUpper = smpphyAddrUpper; 520 ttdsaXchg->smpresp.phyAddrLower = smpphyAddrLower; 521 ttdsaXchg->smpresp.length = smprespLen; 522 523 /* Initialization of callback and etc */ 524 for (i=0;i<maxNumXchgs;i++) 525 { 526 ttdsaXchg->id = i; 527 ttdsaXchg->usedEsgl = agFALSE; 528 ttdsaXchg->io_found = agTRUE; 529 ttdsaXchg->DeviceData = agNULL; 530 /* callback for IO(ssp) and SMP */ 531 ttdsaXchg->IORequestBody.IOCompletionFunc = ttdsaIOCompleted; 532 ttdsaXchg->SMPRequestBody.SMPCompletionFunc = ttdsaSMPCompleted; 533 534 535 TDLIST_INIT_ELEMENT(&ttdsaXchg->XchgLinks ); 536 537 ttdsaXchg->IORequestBody.agIORequest.osData = (void *)ttdsaXchg; 538 ttdsaXchg->IORequestBody.tiIORequest 539 = &(ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest); 540 541 /* Init the tdData portion of tiIORequest context for this exchange */ 542 ttdsaXchg->IORequestBody.tiIORequest->tdData = ttdsaXchg; 543 544 /* SMP */ 545 ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)ttdsaXchg; 546 /* ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)&ttdsaXchg->SMPRequestBody; */ 547 /*ttdsaXchg->SMPRequestBody.tiIORequest.tdData = (void *)&ttdsaXchg->SMPRequestBody; */ 548 549 550 551 552 /* Initialize the CDB and LUN addresses */ 553 ttdsaXchg->tiTgtScsiCmnd.reqCDB = &(ttdsaXchg->agSSPCmndIU.cdb[0]); 554 ttdsaXchg->tiTgtScsiCmnd.scsiLun = &(ttdsaXchg->agSSPCmndIU.lun[0]); 555 556 ttdsaXchg->index = i; 557 ttdsaXchg->respLen = respLen; /* 100 */ 558 ttdsaXchg->smprespLen = smprespLen; /* 100 */ 559 ttdsaXchg->TLR = 0; 560 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE); 561 ttdsaXchg->retries = 0; 562 563 ttdsaXchgLinkInit(tiRoot,ttdsaXchg); 564 565 /* Save current response payload/buffer address */ 566 virtualAddr = ttdsaXchg->resp.virtAddr; 567 phyAddrLower = ttdsaXchg->resp.phyAddrLower; 568 smpvirtualAddr = ttdsaXchg->smpresp.virtAddr; 569 smpphyAddrLower = ttdsaXchg->smpresp.phyAddrLower; 570 571 TI_DBG5(("ttdsaXchgInit: +1 before\n")); 572 if (i == (maxNumXchgs - 1)) 573 { 574 /* at the last one */ 575 TI_DBG5(("ttdsaXchgInit: last one break\n")); 576 break; 577 } 578 579 /* Advance to next exchange */ 580 ttdsaXchg = ttdsaXchg + 1; 581 TI_DBG5(("ttdsaXchgInit: +1 after\n")); 582 583 /* Update response payload/buffer address */ 584 ttdsaXchg->resp.virtAddr = virtualAddr + respLen; 585 TI_DBG5(("ttdsaXchgInit: pos 1\n")); 586 ttdsaXchg->resp.phyAddrUpper = phyAddrUpper; 587 TI_DBG5(("ttdsaXchgInit: pos 2\n")); 588 ttdsaXchg->resp.phyAddrLower = phyAddrLower + respLen; 589 TI_DBG5(("ttdsaXchgInit: pos 3\n")); 590 ttdsaXchg->resp.length = respLen; 591 TI_DBG5(("ttdsaXchgInit: pos 4\n")); 592 593 /* Update SMP response payload/buffer address */ 594 ttdsaXchg->smpresp.virtAddr = smpvirtualAddr + smprespLen; 595 ttdsaXchg->smpresp.phyAddrUpper = smpphyAddrUpper; 596 ttdsaXchg->smpresp.phyAddrLower = smpphyAddrLower + smprespLen; 597 ttdsaXchg->smpresp.length = smprespLen; 598 599 } 600 601 /* Reinitialize counters. 602 * This must be done at the end 603 */ 604 TD_XCHG_CONTEXT_NO_USED(tiRoot) = 0; 605 TD_XCHG_CONTEXT_NO_FREED(tiRoot) = 0; 606 TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot) = 0; 607 TD_XCHG_CONTEXT_NO_START_IO(tiRoot) = 0; 608 TD_XCHG_CONTEXT_NO_SEND_RSP(tiRoot) = 0; 609 TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot) = 0; 610 611 TI_DBG5(("ttdsaXchgInit: end\n")); 612 return agTRUE; 613 } 614 615 osGLOBAL void 616 ttdsaXchgLinkInit( 617 tiRoot_t *tiRoot, 618 ttdsaXchg_t *ttdsaXchg 619 ) 620 { 621 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 622 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 623 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt; 624 bit32 i; 625 bit8 *data; 626 627 TI_DBG5(("ttdsaXchgLinkInit: start\n")); 628 TI_DBG5(("ttdsaXchgLinkInit: xchg %p\n",ttdsaXchg)); 629 TI_DBG5(("ttdsaXchgLinkInit: resp %p\n",ttdsaXchg->resp.virtAddr)); 630 TI_DBG5(("ttdsaXchgLinkInit: smpresp %p\n",ttdsaXchg->smpresp.virtAddr)); 631 632 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE) 633 { 634 TI_DBG1(("ttdsaXchgLinkInit: active xchg *****************; wrong\n")); 635 return; 636 } 637 638 ttdsaXchg->tag = 0xFFFF; 639 ttdsaXchg->IORequestBody.agIORequest.sdkData = agNULL; 640 ttdsaXchg->SMPRequestBody.agIORequest.sdkData = agNULL; 641 ttdsaXchg->statusSent = agFALSE; 642 ttdsaXchg->responseSent = agFALSE; 643 ttdsaXchg->readRspCollapsed = agFALSE; 644 ttdsaXchg->wrtRspCollapsed = agFALSE; 645 ttdsaXchg->pTMResp = agNULL; 646 ttdsaXchg->oustandingIos = 0; 647 ttdsaXchg->isAborting = agFALSE; 648 ttdsaXchg->oslayerAborting = agFALSE; 649 ttdsaXchg->isTMRequest = agFALSE; 650 ttdsaXchg->io_found = agTRUE; 651 ttdsaXchg->tiIOToBeAbortedRequest = agNULL; 652 ttdsaXchg->XchgToBeAborted = agNULL; 653 654 osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen); 655 osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen); 656 657 data = (bit8 *)ttdsaXchg->resp.virtAddr; 658 for (i = 0; i< ttdsaXchg->respLen; i++) 659 { 660 if (data[i] != 0) 661 { 662 TI_DBG5(("!! ttdsaXchgLinkInit: data[%d] 0x%x\n", i, data[i])); 663 } 664 } 665 666 ttdsaXchg->resp.length = 0; 667 668 ttdsaXchg->DeviceData = agNULL; 669 TI_DBG5(("ttdsaXchgLinkInit: id %d\n", ttdsaXchg->id)); 670 671 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE); 672 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK); 673 TDLIST_ENQUEUE_AT_TAIL( &ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList); 674 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 675 676 677 TD_XCHG_CONTEXT_NO_FREED(tiRoot) = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1; 678 TI_DBG5(("ttdsaXchgLinkInit: end\n")); 679 return; 680 } 681 682 /* 683 before: ttdsaXchg is in xchgBusyList 684 after: ttdsaXchg is in xchgFreeList 685 */ 686 osGLOBAL void 687 ttdsaXchgFreeStruct( 688 tiRoot_t *tiRoot, 689 ttdsaXchg_t *ttdsaXchg 690 ) 691 { 692 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData; 693 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 694 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt; 695 bit32 i; 696 bit8 *data; 697 698 TI_DBG5(("ttdsaXchgFreeStruct: start\n")); 699 TI_DBG5(("ttdsaXchgFreeStruct: xchg %p\n",ttdsaXchg)); 700 TI_DBG5(("ttdsaXchgFreeStruct: resp %p\n",ttdsaXchg->resp.virtAddr)); 701 TI_DBG5(("ttdsaXchgFreeStruct: smpresp %p\n",ttdsaXchg->smpresp.virtAddr)); 702 703 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE) 704 { 705 TI_DBG1(("tdsaXchgFreeStruct: INACTIVE xchg *****************, wrong\n")); 706 return; 707 } 708 709 ttdsaXchg->tag = 0xFFFF; 710 ttdsaXchg->IORequestBody.agIORequest.sdkData = agNULL; 711 ttdsaXchg->SMPRequestBody.agIORequest.sdkData = agNULL; 712 ttdsaXchg->statusSent = agFALSE; 713 ttdsaXchg->responseSent = agFALSE; 714 ttdsaXchg->readRspCollapsed = agFALSE; 715 ttdsaXchg->wrtRspCollapsed = agFALSE; 716 ttdsaXchg->pTMResp = agNULL; 717 ttdsaXchg->oustandingIos = 0; 718 ttdsaXchg->isAborting = agFALSE; 719 ttdsaXchg->oslayerAborting = agFALSE; 720 ttdsaXchg->isTMRequest = agFALSE; 721 ttdsaXchg->io_found = agTRUE; 722 ttdsaXchg->tiIOToBeAbortedRequest = agNULL; 723 ttdsaXchg->XchgToBeAborted = agNULL; 724 725 osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen); 726 osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen); 727 728 data = (bit8 *)ttdsaXchg->resp.virtAddr; 729 for (i = 0; i< ttdsaXchg->respLen; i++) 730 { 731 if (data[i] != 0) 732 { 733 TI_DBG5(("!! ttdsaXchgFreeStruct: data[%d] 0x%x\n", i, data[i])); 734 } 735 } 736 737 ttdsaXchg->resp.length = 0; 738 739 ttdsaXchg->DeviceData = agNULL; 740 TI_DBG5(("ttdsaXchgFreeStruct: id %d\n", ttdsaXchg->id)); 741 742 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK); 743 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE); 744 TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks); 745 TDLIST_ENQUEUE_AT_TAIL( &ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList); 746 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 747 748 TD_XCHG_CONTEXT_NO_FREED(tiRoot) = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1; 749 TI_DBG5(("ttdsaXchgFreeStruct: end\n")); 750 return; 751 } 752 753 754 /* 755 before: ttdsaXchg is in xchgFreeList 756 after: ttdsaXchg is in xchgBusyList 757 */ 758 osGLOBAL ttdsaXchg_t *ttdsaXchgGetStruct(agsaRoot_t *agRoot) 759 { 760 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 761 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 762 ttdsaTgt_t *Target = (ttdsaTgt_t *)osData->ttdsaTgt; 763 tdList_t *Link; 764 ttdsaXchg_t *ttdsaXchg = agNULL; 765 766 TI_DBG3 (("ttdsaXchgGetStruct: enter\n")); 767 768 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK); 769 if (TDLIST_EMPTY(&(Target->ttdsaXchgData.xchgFreeList))) 770 { 771 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 772 TI_DBG1(("ttdsaXchgGetStruct: no free ttdsaXchgData\n")); 773 // ttdsaDumpallXchg(tiRoot); 774 return agNULL; 775 } 776 777 TDLIST_DEQUEUE_FROM_HEAD(&Link, &Target->ttdsaXchgData.xchgFreeList); 778 if ( Link == agNULL ) 779 { 780 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 781 TI_DBG1(("ttdsaXchgGetStruct: Link NULL: PRBLM \n")); 782 return agNULL; 783 } 784 785 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, Link); 786 787 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE) 788 { 789 TI_DBG1(("ttdsaXchgGetStruct: ACTIVE xchg *****************, wrong\n")); 790 TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks); 791 TDLIST_ENQUEUE_AT_TAIL(&ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList); 792 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE); 793 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 794 795 return agNULL; 796 } 797 798 TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks); 799 TDLIST_ENQUEUE_AT_TAIL(&ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgBusyList); 800 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_ACTIVE); 801 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 802 803 TD_XCHG_CONTEXT_NO_USED(tiRoot) = TD_XCHG_CONTEXT_NO_USED(tiRoot) +1; 804 TI_DBG5(("ttdsaXchgGetStruct: id %d\n", ttdsaXchg->id)); 805 return ttdsaXchg; 806 } 807 808 /* for debugging */ 809 osGLOBAL void 810 ttdsaDumpallXchg(tiRoot_t *tiRoot) 811 { 812 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 813 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 814 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt; 815 ttdsaTgt_t *tmpTarget; 816 tdList_t *XchgList; 817 #ifdef TD_DEBUG_ENABLE 818 ttdsaXchg_t *ttdsaXchg = agNULL; 819 #endif 820 821 tmpTarget = Target; 822 823 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK); 824 if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgFreeList))) 825 { 826 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 827 TI_DBG1(("ttdsaDumpallXchg: no FREE ttdsaXchgData\n")); 828 } 829 else 830 { 831 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 832 XchgList = tmpTarget->ttdsaXchgData.xchgFreeList.flink; 833 834 while(XchgList != &(tmpTarget->ttdsaXchgData.xchgFreeList)) 835 { 836 #ifdef TD_DEBUG_ENABLE 837 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList); 838 #endif 839 TI_DBG1(("ttdsaDumpallXchg: FREE id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg))); 840 XchgList = XchgList->flink; 841 } 842 } 843 844 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK); 845 if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgBusyList))) 846 { 847 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 848 TI_DBG1(("ttdsaDumpallXchg: no BUSY ttdsaXchgData\n")); 849 } 850 else 851 { 852 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK); 853 XchgList = tmpTarget->ttdsaXchgData.xchgBusyList.flink; 854 855 while(XchgList != &(tmpTarget->ttdsaXchgData.xchgBusyList)) 856 { 857 #ifdef TD_DEBUG_ENABLE 858 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList); 859 #endif 860 TI_DBG1(("ttdsaDumpallXchg: BUSY id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg))); 861 XchgList = XchgList->flink; 862 } 863 } 864 865 866 return; 867 } 868 869 870 #ifdef PASSTHROUGH 871 872 osGLOBAL bit32 873 tiTGTPassthroughCmndRegister( 874 tiRoot_t *tiRoot, 875 tiPortalContext_t *tiportalContext, 876 tiPassthroughProtocol_t tiProtocol, 877 tiPassthroughSubProtocol_t tiSubProtocol, 878 tiPassthroughFrameType_t tiFrameType, 879 ostiProcessPassthroughCmnd_t agPasthroughCB 880 ) 881 { 882 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 883 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 884 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt; 885 886 TI_DBG1(("tiTGTPassthroughCmndRegister: start\n")); 887 /* error checking */ 888 if (tiProtocol != tiSASATA) 889 { 890 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported protocol %d\n", tiProtocol)); 891 return tiError; 892 } 893 894 if (tiSubProtocol != tiSSP || tiSubProtocol != tiSTP || tiSubProtocol != tiSMP) 895 { 896 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported sub protocol %d\n", tiSubProtocol)); 897 return tiError; 898 } 899 900 901 if (tiFrameType == tiSMPResponse) 902 { 903 TI_DBG1(("tiTGTPassthroughCmndRegister: SMP response frametype %d\n")); 904 Target->PasthroughCB = agPasthroughCB; 905 } 906 907 else if (tiFrameType == tiSSPPMC) 908 { 909 TI_DBG1(("tiTGTPassthroughCmndRegister: RMC response frametype %d\n")); 910 Target->PasthroughCB = agPasthroughCB; 911 } 912 else 913 { 914 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported frametype %d\n", tiFrameType)); 915 return tiError; 916 } 917 918 919 return tiSuccess; 920 } 921 922 #endif 923