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