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 #include <sys/cdefs.h> 23 #include <dev/pms/config.h> 24 25 #include <dev/pms/freebsd/driver/common/osenv.h> 26 #include <dev/pms/freebsd/driver/common/ostypes.h> 27 #include <dev/pms/freebsd/driver/common/osdebug.h> 28 29 #include <dev/pms/RefTisa/tisa/api/titypes.h> 30 31 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 34 35 #include <dev/pms/RefTisa/sat/api/sm.h> 36 #include <dev/pms/RefTisa/sat/api/smapi.h> 37 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 38 39 #include <dev/pms/RefTisa/sat/src/smdefs.h> 40 #include <dev/pms/RefTisa/sat/src/smproto.h> 41 #include <dev/pms/RefTisa/sat/src/smtypes.h> 42 43 #ifdef SM_DEBUG 44 bit32 gSMDebugLevel = 1; 45 #endif 46 smRoot_t *gsmRoot = agNULL; 47 48 /* start smapi defined APIS */ 49 osGLOBAL void 50 smGetRequirements( 51 smRoot_t *smRoot, 52 smSwConfig_t *swConfig, 53 smMemoryRequirement_t *memoryRequirement, 54 bit32 *usecsPerTick, 55 bit32 *maxNumLocks 56 ) 57 { 58 bit32 memoryReqCount = 0; 59 bit32 i; 60 bit32 max_dev = SM_MAX_DEV; 61 char *buffer; 62 bit32 buffLen; 63 bit32 lenRecv = 0; 64 static char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE]; 65 char *pLastUsedChar = agNULL; 66 char globalStr[] = "Global"; 67 char iniParmsStr[] = "InitiatorParms"; 68 SM_DBG2(("smGetRequirements: start\n")); 69 70 /* sanity check */ 71 SM_ASSERT((agNULL != swConfig), ""); 72 SM_ASSERT((agNULL != memoryRequirement), ""); 73 SM_ASSERT((agNULL != usecsPerTick), ""); 74 SM_ASSERT((agNULL != maxNumLocks), ""); 75 76 /* memory requirement for smRoot, CACHE memory */ 77 memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].singleElementLength = sizeof(smIntRoot_t); 78 memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].numElements = 1; 79 memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].totalLength = 80 (memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].numElements); 81 memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].alignment = 4; 82 memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].type = SM_CACHED_MEM; 83 memoryReqCount++; 84 85 /* reading the configurable parameter of MaxTargets */ 86 buffer = tmpBuffer; 87 buffLen = sizeof(tmpBuffer); 88 sm_memset(buffer, 0, buffLen); 89 lenRecv = 0; 90 if ((tdsmGetTransportParam( 91 smRoot, 92 globalStr, 93 iniParmsStr, 94 agNULL, 95 agNULL, 96 agNULL, 97 agNULL, 98 "MaxTargets", 99 buffer, 100 buffLen, 101 &lenRecv 102 ) == SM_RC_SUCCESS) && (lenRecv != 0)) 103 { 104 if (osti_strncmp(buffer, "0x", 2) == 0) 105 { 106 max_dev = osti_strtoul (buffer, &pLastUsedChar, 0); 107 } 108 else 109 { 110 max_dev = osti_strtoul (buffer, &pLastUsedChar, 10); 111 } 112 } 113 SM_DBG3(("smGetRequirements: max_expander %d\n", max_dev)); 114 /* memory requirement for Device Links, CACHE memory */ 115 memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].singleElementLength = sizeof(smDeviceData_t); 116 memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].numElements = max_dev; 117 memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].totalLength = 118 (memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].numElements); 119 memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].alignment = 4; 120 memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].type = SM_CACHED_MEM; 121 memoryReqCount++; 122 123 /* memory requirement for IO inks, CACHE memory */ 124 memoryRequirement->smMemory[SM_IO_MEM_INDEX].singleElementLength = sizeof(smIORequestBody_t); 125 memoryRequirement->smMemory[SM_IO_MEM_INDEX].numElements = SM_MAX_IO; 126 memoryRequirement->smMemory[SM_IO_MEM_INDEX].totalLength = 127 (memoryRequirement->smMemory[SM_IO_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_IO_MEM_INDEX].numElements); 128 memoryRequirement->smMemory[SM_IO_MEM_INDEX].alignment = 4; 129 memoryRequirement->smMemory[SM_IO_MEM_INDEX].type = SM_CACHED_MEM; 130 memoryReqCount++; 131 132 /* for debugging */ 133 for (i=0;i< memoryReqCount;i++) 134 { 135 SM_DBG3(("smGetRequirements: index %d numElements %d totalLength %d singleElementLength %d alignment %d\n", i 136 , memoryRequirement->smMemory[i].numElements, memoryRequirement->smMemory[i].totalLength, 137 memoryRequirement->smMemory[i].singleElementLength,memoryRequirement->smMemory[i].alignment )); 138 } 139 /* set up memory requirement count */ 140 memoryRequirement->count = memoryReqCount; 141 142 /* requirement for locks */ 143 *maxNumLocks = SM_MAX_LOCKS; 144 145 /* setup the time tick */ 146 *usecsPerTick = SM_USECS_PER_TICK; 147 148 /* set up the number of active IOs */ 149 swConfig->maxActiveIOs = SM_MAX_IO; 150 151 /* set up the number of device handles */ 152 swConfig->numDevHandles = SM_MAX_DEV; 153 154 155 return; 156 } 157 158 osGLOBAL bit32 159 smInitialize( 160 smRoot_t *smRoot, 161 agsaRoot_t *agRoot, 162 smMemoryRequirement_t *memoryAllocated, 163 smSwConfig_t *swConfig, 164 bit32 usecsPerTick 165 ) 166 { 167 smIntRoot_t *smIntRoot; 168 smDeviceData_t *smDevice; 169 smIORequestBody_t *smIORequest; 170 smIntContext_t *smAllShared; 171 bit32 i; 172 bit32 max_dev = SM_MAX_DEV; 173 char *buffer; 174 bit32 buffLen; 175 bit32 lenRecv = 0; 176 static char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE]; 177 char *pLastUsedChar = agNULL; 178 char globalStr[] = "Global"; 179 char iniParmsStr[] = "InitiatorParms"; 180 181 SM_DBG2(("smInitialize: start\n")); 182 183 /* sanity check */ 184 SM_ASSERT((agNULL != smRoot), ""); 185 SM_ASSERT((agNULL != agRoot), ""); 186 SM_ASSERT((agNULL != memoryAllocated), ""); 187 SM_ASSERT((agNULL != swConfig), ""); 188 SM_ASSERT((SM_ROOT_MEM_INDEX < memoryAllocated->count), ""); 189 SM_ASSERT((SM_DEVICE_MEM_INDEX < memoryAllocated->count), ""); 190 SM_ASSERT((SM_IO_MEM_INDEX < memoryAllocated->count), ""); 191 192 /* Check the memory allocated */ 193 for ( i = 0; i < memoryAllocated->count; i ++ ) 194 { 195 /* If memory allocatation failed */ 196 if (memoryAllocated->smMemory[i].singleElementLength && 197 memoryAllocated->smMemory[i].numElements) 198 { 199 if ( (0 != memoryAllocated->smMemory[i].numElements) 200 && (0 == memoryAllocated->smMemory[i].totalLength) ) 201 { 202 /* return failure */ 203 SM_DBG1(("smInitialize: Memory[%d] singleElementLength = 0x%x numElements = 0x%x NOT allocated!!!\n", 204 i, 205 memoryAllocated->smMemory[i].singleElementLength, 206 memoryAllocated->smMemory[i].numElements)); 207 return SM_RC_FAILURE; 208 } 209 } 210 } 211 212 /* for debugging */ 213 for ( i = 0; i < memoryAllocated->count; i ++ ) 214 { 215 SM_DBG3(("smInitialize: index %d virtPtr %p osHandle%p\n",i, memoryAllocated->smMemory[i].virtPtr, memoryAllocated->smMemory[i].osHandle)); 216 SM_DBG3(("smInitialize: index %d phyAddrUpper 0x%x phyAddrLower 0x%x totalLength %d numElements %d\n", i, 217 memoryAllocated->smMemory[i].physAddrUpper, 218 memoryAllocated->smMemory[i].physAddrLower, 219 memoryAllocated->smMemory[i].totalLength, 220 memoryAllocated->smMemory[i].numElements)); 221 SM_DBG3(("smInitialize: index %d singleElementLength 0x%x alignment 0x%x type %d reserved %d\n", i, 222 memoryAllocated->smMemory[i].singleElementLength, 223 memoryAllocated->smMemory[i].alignment, 224 memoryAllocated->smMemory[i].type, 225 memoryAllocated->smMemory[i].reserved)); 226 } 227 228 /* SM's internal root */ 229 smIntRoot = (smIntRoot_t *) (memoryAllocated->smMemory[SM_ROOT_MEM_INDEX].virtPtr); 230 smRoot->smData = (void *) smIntRoot; 231 232 smAllShared = (smIntContext_t *)&(smIntRoot->smAllShared); 233 /**< Initialize the TDM data part of the interrupt context */ 234 smAllShared->smRootOsData.smRoot = smRoot; 235 smAllShared->smRootOsData.smAllShared = (void *) smAllShared; 236 gsmRoot = smRoot; 237 smAllShared->FCA = agTRUE; 238 239 /* Devices */ 240 smDevice = (smDeviceData_t *) (memoryAllocated->smMemory[SM_DEVICE_MEM_INDEX].virtPtr); 241 smAllShared->DeviceMem = (smDeviceData_t *)smDevice; 242 243 /* IOs */ 244 smIORequest = (smIORequestBody_t *) (memoryAllocated->smMemory[SM_IO_MEM_INDEX].virtPtr); 245 smAllShared->IOMem = (smIORequestBody_t *)smIORequest; 246 247 smAllShared->agRoot = agRoot; 248 249 smAllShared->usecsPerTick = usecsPerTick; 250 251 /**< initializes timers */ 252 smInitTimers(smRoot); 253 254 /**< initializes devices */ 255 buffer = tmpBuffer; 256 buffLen = sizeof(tmpBuffer); 257 sm_memset(buffer, 0, buffLen); 258 lenRecv = 0; 259 if ((tdsmGetTransportParam( 260 smRoot, 261 globalStr, 262 iniParmsStr, 263 agNULL, 264 agNULL, 265 agNULL, 266 agNULL, 267 "MaxTargets", 268 buffer, 269 buffLen, 270 &lenRecv 271 ) == SM_RC_SUCCESS) && (lenRecv != 0)) 272 { 273 if (osti_strncmp(buffer, "0x", 2) == 0) 274 { 275 max_dev = osti_strtoul (buffer, &pLastUsedChar, 0); 276 } 277 else 278 { 279 max_dev = osti_strtoul (buffer, &pLastUsedChar, 10); 280 } 281 SM_DBG1(("smInitialize: MaxTargets %d\n", max_dev)); 282 } 283 284 smDeviceDataInit(smRoot, max_dev); 285 286 /**< initializes IOs */ 287 smIOInit(smRoot); 288 289 #ifdef SM_DEBUG 290 gSMDebugLevel = swConfig->SMDebugLevel; 291 #endif 292 293 return SM_RC_SUCCESS; 294 } 295 296 osGLOBAL void 297 smInitTimers( 298 smRoot_t *smRoot 299 ) 300 { 301 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 302 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 303 304 SM_DBG2(("smInitTimers: start\n")); 305 306 /* initialize the timerlist */ 307 SMLIST_INIT_HDR(&(smAllShared->timerlist)); 308 309 return; 310 } 311 312 osGLOBAL void 313 smDeviceDataReInit( 314 smRoot_t *smRoot, 315 smDeviceData_t *oneDeviceData 316 ) 317 { 318 int j=0; 319 smSatInternalIo_t *satIntIO; 320 321 SM_DBG2(("smDeviceDataReInit: start \n")); 322 323 if (oneDeviceData->satPendingIO != 0) 324 { 325 SM_DBG1(("smDeviceDataReInit: did %d\n", oneDeviceData->id)); 326 SM_DBG1(("smDeviceDataReInit: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO )); 327 SM_DBG1(("smDeviceDataReInit: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO)); 328 } 329 330 // oneDeviceData->smRoot = agNULL; 331 oneDeviceData->agDevHandle = agNULL; 332 oneDeviceData->valid = agFALSE; 333 oneDeviceData->SMAbortAll = agFALSE; 334 oneDeviceData->smDevHandle = agNULL; 335 oneDeviceData->directlyAttached = agFALSE; 336 oneDeviceData->agExpDevHandle = agNULL; 337 oneDeviceData->phyID = 0xFF; 338 oneDeviceData->SMNumOfFCA = 0; 339 340 /* default */ 341 oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL; 342 oneDeviceData->satNCQMaxIO =SAT_NCQ_MAX; 343 oneDeviceData->satPendingIO = 0; 344 oneDeviceData->satPendingNCQIO = 0; 345 oneDeviceData->satPendingNONNCQIO = 0; 346 oneDeviceData->IDDeviceValid = agFALSE; 347 oneDeviceData->freeSATAFDMATagBitmap = 0; 348 oneDeviceData->NumOfFCA = 0; 349 oneDeviceData->NumOfIDRetries = 0; 350 oneDeviceData->ID_Retries = 0; 351 oneDeviceData->OSAbortAll = agFALSE; 352 353 sm_memset(oneDeviceData->satMaxLBA, 0, sizeof(oneDeviceData->satMaxLBA)); 354 sm_memset(&(oneDeviceData->satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 355 356 oneDeviceData->satSaDeviceData = oneDeviceData; 357 358 satIntIO = (smSatInternalIo_t *)&(oneDeviceData->satIntIo[0]); 359 for (j = 0; j < SAT_MAX_INT_IO; j++) 360 { 361 SM_DBG2(("tdsaDeviceDataReInit: in loop of internal io free, id %d\n", satIntIO->id)); 362 smsatFreeIntIoResource(smRoot, oneDeviceData, satIntIO); 363 satIntIO = satIntIO + 1; 364 } 365 366 return; 367 } 368 osGLOBAL void 369 smDeviceDataInit( 370 smRoot_t *smRoot, 371 bit32 max_dev 372 ) 373 { 374 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 375 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 376 smDeviceData_t *smDeviceData = (smDeviceData_t *)smAllShared->DeviceMem; 377 int i,j; 378 smSatInternalIo_t *satIntIO; 379 380 SM_DBG2(("smDeviceDataInit: start \n")); 381 382 SMLIST_INIT_HDR(&(smAllShared->MainDeviceList)); 383 SMLIST_INIT_HDR(&(smAllShared->FreeDeviceList)); 384 385 for(i=0;i<(int)max_dev;i++) 386 { 387 SMLIST_INIT_ELEMENT(&(smDeviceData[i].FreeLink)); 388 SMLIST_INIT_ELEMENT(&(smDeviceData[i].MainLink)); 389 smDeviceData[i].id = i; 390 smDeviceData[i].smRoot = agNULL; 391 smDeviceData[i].agDevHandle = agNULL; 392 smDeviceData[i].valid = agFALSE; 393 smDeviceData[i].SMAbortAll = agFALSE; 394 smDeviceData[i].smDevHandle = agNULL; 395 smDeviceData[i].directlyAttached = agFALSE; 396 smDeviceData[i].agExpDevHandle = agNULL; 397 smDeviceData[i].phyID = 0xFF; 398 smDeviceData[i].SMNumOfFCA = 0; 399 400 401 SMLIST_INIT_HDR(&(smDeviceData[i].satIoLinkList)); 402 SMLIST_INIT_HDR(&(smDeviceData[i].satFreeIntIoLinkList)); 403 SMLIST_INIT_HDR(&(smDeviceData[i].satActiveIntIoLinkList)); 404 405 /* default */ 406 smDeviceData[i].satDriveState = SAT_DEV_STATE_NORMAL; 407 smDeviceData[i].satNCQMaxIO =SAT_NCQ_MAX; 408 smDeviceData[i].satPendingIO = 0; 409 smDeviceData[i].satPendingNCQIO = 0; 410 smDeviceData[i].satPendingNONNCQIO = 0; 411 smDeviceData[i].IDDeviceValid = agFALSE; 412 smDeviceData[i].freeSATAFDMATagBitmap = 0; 413 smDeviceData[i].NumOfFCA = 0; 414 smDeviceData[i].NumOfIDRetries = 0; 415 smDeviceData[i].ID_Retries = 0; 416 smDeviceData[i].OSAbortAll = agFALSE; 417 smInitTimerRequest(smRoot, &(smDeviceData[i].SATAIDDeviceTimer)); 418 419 sm_memset(&(smDeviceData[i].satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 420 sm_memset(smDeviceData[i].satMaxLBA, 0, sizeof(smDeviceData[i].satMaxLBA)); 421 422 smDeviceData[i].satSaDeviceData = &smDeviceData[i]; 423 424 #if 1 425 satIntIO = &smDeviceData[i].satIntIo[0]; 426 for (j = 0; j < SAT_MAX_INT_IO; j++) 427 { 428 SMLIST_INIT_ELEMENT (&satIntIO->satIntIoLink); 429 SMLIST_ENQUEUE_AT_TAIL (&satIntIO->satIntIoLink, 430 &smDeviceData[i].satFreeIntIoLinkList); 431 satIntIO->satOrgSmIORequest = agNULL; 432 satIntIO->id = j; 433 satIntIO = satIntIO + 1; 434 } 435 #endif 436 437 /* some other variables */ 438 SMLIST_ENQUEUE_AT_TAIL(&(smDeviceData[i].FreeLink), &(smAllShared->FreeDeviceList)); 439 } 440 441 return; 442 } 443 444 osGLOBAL void 445 smIOInit( 446 smRoot_t *smRoot 447 ) 448 { 449 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 450 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 451 smIORequestBody_t *smIOCommand = (smIORequestBody_t *)smAllShared->IOMem; 452 int i = 0; 453 454 SM_DBG3(("smIOInit: start\n")); 455 456 SMLIST_INIT_HDR(&(smAllShared->freeIOList)); 457 SMLIST_INIT_HDR(&(smAllShared->mainIOList)); 458 459 for(i=0;i<SM_MAX_IO;i++) 460 { 461 SMLIST_INIT_ELEMENT(&(smIOCommand[i].satIoBodyLink)); 462 smIOCommand[i].id = i; 463 smIOCommand[i].InUse = agFALSE; 464 smIOCommand[i].ioStarted = agFALSE; 465 smIOCommand[i].ioCompleted = agFALSE; 466 smIOCommand[i].reTries = 0; 467 468 smIOCommand[i].smDevHandle = agNULL; 469 smIOCommand[i].smIORequest = agNULL; 470 smIOCommand[i].smIOToBeAbortedRequest = agNULL; 471 smIOCommand[i].transport.SATA.satIOContext.satOrgIOContext = agNULL; 472 473 sm_memset(&(smIOCommand[i].transport.SATA.agSATARequestBody), 0, sizeof(agsaSATAInitiatorRequest_t)); 474 475 476 SMLIST_ENQUEUE_AT_TAIL(&(smIOCommand[i].satIoBodyLink), &(smAllShared->freeIOList)); 477 } 478 479 return; 480 } 481 482 FORCEINLINE void 483 smIOReInit( 484 smRoot_t *smRoot, 485 smIORequestBody_t *smIORequestBody 486 ) 487 { 488 SM_DBG3(("smIOReInit: start\n")); 489 smIORequestBody->InUse = agTRUE; 490 smIORequestBody->ioStarted = agFALSE; 491 smIORequestBody->ioCompleted = agFALSE; 492 smIORequestBody->reTries = 0; 493 smIORequestBody->smDevHandle = agNULL; 494 smIORequestBody->smIORequest = agNULL; 495 smIORequestBody->smIOToBeAbortedRequest = agNULL; 496 smIORequestBody->transport.SATA.satIOContext.satOrgIOContext = agNULL; 497 /*sm_memset(&(smIORequestBody->transport.SATA.agSATARequestBody), 0, sizeof(agsaSATAInitiatorRequest_t));*/ 498 return; 499 } 500 501 /* end smapi defined APIS */ 502 503