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 /*******************************************************************************/ 23 /** \file 24 * 25 * 26 * This file contains TB misc. functions 27 * 28 */ 29 #include <sys/cdefs.h> 30 #include <dev/pms/config.h> 31 32 #include <dev/pms/freebsd/driver/common/osenv.h> 33 #include <dev/pms/freebsd/driver/common/ostypes.h> 34 #include <dev/pms/freebsd/driver/common/osdebug.h> 35 36 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 37 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 38 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 39 40 #include <dev/pms/RefTisa/tisa/api/titypes.h> 41 #include <dev/pms/RefTisa/tisa/api/ostiapi.h> 42 #include <dev/pms/RefTisa/tisa/api/tiapi.h> 43 #include <dev/pms/RefTisa/tisa/api/tiglobal.h> 44 45 #ifdef FDS_SM 46 #include <dev/pms/RefTisa/sat/api/sm.h> 47 #include <dev/pms/RefTisa/sat/api/smapi.h> 48 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 49 #endif 50 51 #ifdef FDS_DM 52 #include <dev/pms/RefTisa/discovery/api/dm.h> 53 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 54 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 55 #endif 56 57 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h> 58 #include <dev/pms/freebsd/driver/common/osstring.h> 59 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h> 60 61 #ifdef INITIATOR_DRIVER 62 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h> 63 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h> 64 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h> 65 #endif 66 67 #ifdef TARGET_DRIVER 68 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h> 69 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h> 70 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h> 71 #endif 72 73 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 74 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h> 75 76 /***************************************************************************** 77 *! \brief tiINIIOAbort 78 * 79 * Purpose: This function is called to abort an I/O request previously started 80 * by a call to tiINIIOStart() or tiINIIOStartDif() . 81 * 82 * \param tiRoot: Pointer to initiator driver/port instance. 83 * \param taskTag: Pointer to the associated task to be aborted 84 * 85 * \return: 86 * 87 * tiSuccess: I/O request successfully initiated. 88 * tiBusy: No resources available, try again later. 89 * tiIONoDevice: Invalid device handle. 90 * tiError: Other errors that prevent the I/O request to be 91 * started. 92 * 93 *****************************************************************************/ 94 #ifdef INITIATOR_DRIVER /*TBD: INITIATOR SPECIFIC API in tiapi.h (TP)*/ 95 osGLOBAL bit32 96 tiINIIOAbort( 97 tiRoot_t *tiRoot, 98 tiIORequest_t *taskTag 99 ) 100 { 101 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 102 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 103 agsaRoot_t *agRoot = agNULL; 104 tdIORequestBody_t *tdIORequestBody = agNULL; 105 agsaIORequest_t *agIORequest = agNULL; 106 bit32 sasStatus = AGSA_RC_FAILURE; 107 tdsaDeviceData_t *oneDeviceData; 108 bit32 status= tiError; 109 agsaIORequest_t *agAbortIORequest; 110 tdIORequestBody_t *tdAbortIORequestBody; 111 bit32 PhysUpper32; 112 bit32 PhysLower32; 113 bit32 memAllocStatus; 114 void *osMemHandle; 115 agsaDevHandle_t *agDevHandle = agNULL; 116 #ifdef FDS_SM 117 smRoot_t *smRoot; 118 tdIORequestBody_t *ToBeAbortedtdIORequestBody; 119 smIORequest_t *ToBeAborted = agNULL; 120 #endif 121 TI_DBG2(("tiINIIOAbort: start\n")); 122 123 if(taskTag == agNULL) 124 { 125 TI_DBG1(("tiINIIOAbort: taskTag is NULL\n")); 126 return tiError; 127 } 128 129 agRoot = &(tdsaAllShared->agRootNonInt); 130 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 131 agIORequest = &(tdIORequestBody->agIORequest); 132 oneDeviceData = tdIORequestBody->tiDevHandle->tdData; 133 134 if(oneDeviceData == agNULL) 135 { 136 TI_DBG1(("tiINIIOAbort: DeviceData is NULL\n")); 137 return tiSuccess; 138 } 139 140 agDevHandle = oneDeviceData->agDevHandle; 141 142 TI_DBG2(("tiINIIOAbort: did %d\n", oneDeviceData->id)); 143 144 /* for hotplug */ 145 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 146 oneDeviceData->tdPortContext == agNULL ) 147 { 148 TI_DBG1(("tiINIIOAbort: NO Device did %d\n", oneDeviceData->id )); 149 TI_DBG1(("tiINIIOAbort: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 150 TI_DBG1(("tiINIIOAbort: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 151 return tiError; 152 } 153 154 /* allocating agIORequest for abort itself */ 155 memAllocStatus = ostiAllocMemory( 156 tiRoot, 157 &osMemHandle, 158 (void **)&tdAbortIORequestBody, 159 &PhysUpper32, 160 &PhysLower32, 161 8, 162 sizeof(tdIORequestBody_t), 163 agTRUE 164 ); 165 if (memAllocStatus != tiSuccess) 166 { 167 /* let os process IO */ 168 TI_DBG1(("tiINIIOAbort: ostiAllocMemory failed...\n")); 169 return tiError; 170 } 171 172 if (tdAbortIORequestBody == agNULL) 173 { 174 /* let os process IO */ 175 TI_DBG1(("tiINIIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 176 return tiError; 177 } 178 179 /* setup task management structure */ 180 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 181 /* setting callback */ 182 tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler; 183 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; 184 185 /* initialize agIORequest */ 186 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 187 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 188 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 189 190 /* remember IO to be aborted */ 191 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag; 192 193 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 194 { 195 sasStatus = saSSPAbort(agRoot, 196 agAbortIORequest, 197 tdsaRotateQnumber(tiRoot, oneDeviceData), 198 agDevHandle, 199 0/* flag */, 200 agIORequest, 201 agNULL); 202 203 if (sasStatus == AGSA_RC_SUCCESS) 204 { 205 return tiSuccess; 206 } 207 else 208 { 209 return tiError; 210 } 211 } 212 213 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 214 { 215 TI_DBG2(("tiINIIOAbort: calling satIOAbort() oneDeviceData=%p\n", oneDeviceData)); 216 #ifdef FDS_SM 217 smRoot = &(tdsaAllShared->smRoot); 218 if ( taskTag != agNULL) 219 { 220 ToBeAbortedtdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 221 ToBeAborted = &(ToBeAbortedtdIORequestBody->smIORequest); 222 status = smIOAbort(smRoot, ToBeAborted); 223 return status; 224 } 225 else 226 { 227 TI_DBG1(("tiINIIOAbort: taskTag is NULL!!!\n")); 228 return tiError; 229 } 230 231 #else 232 233 #ifdef SATA_ENABLE 234 status = satIOAbort(tiRoot, taskTag ); 235 #endif 236 237 return status; 238 #endif /* else FDS_SM */ 239 } 240 241 else 242 { 243 return tiError; 244 } 245 246 } 247 248 osGLOBAL bit32 249 tiINIIOAbortAll( 250 tiRoot_t *tiRoot, 251 tiDeviceHandle_t *tiDeviceHandle 252 ) 253 { 254 agsaRoot_t *agRoot = agNULL; 255 tdsaDeviceData_t *oneDeviceData = agNULL; 256 bit32 status = tiError; 257 #ifdef FDS_SM 258 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 259 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 260 smRoot_t *smRoot = &(tdsaAllShared->smRoot); 261 smDeviceHandle_t *smDeviceHandle; 262 #endif 263 264 TI_DBG1(("tiINIIOAbortAll: start\n")); 265 266 if (tiDeviceHandle == agNULL) 267 { 268 TI_DBG1(("tiINIIOAbortAll: tiDeviceHandle is NULL!!!\n")); 269 return tiError; 270 } 271 272 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 273 274 if (oneDeviceData == agNULL) 275 { 276 TI_DBG1(("tiINIIOAbortAll: oneDeviceData is NULL!!!\n")); 277 return tiError; 278 } 279 280 /* for hotplug */ 281 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 282 oneDeviceData->tdPortContext == agNULL ) 283 { 284 TI_DBG1(("tiINIIOAbortAll: NO Device did %d\n", oneDeviceData->id )); 285 TI_DBG1(("tiINIIOAbortAll: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 286 TI_DBG1(("tiINIIOAbortAll: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 287 return tiError; 288 } 289 290 agRoot = oneDeviceData->agRoot; 291 292 if (agRoot == agNULL) 293 { 294 TI_DBG1(("tiINIIOAbortAll: agRoot is NULL!!!\n")); 295 return tiError; 296 } 297 298 /* this is processed in ossaSSPAbortCB, ossaSATAAbortCB, ossaSMPAbortCB */ 299 if (oneDeviceData->OSAbortAll == agTRUE) 300 { 301 TI_DBG1(("tiINIIOAbortAll: already pending!!!\n")); 302 return tiBusy; 303 } 304 else 305 { 306 oneDeviceData->OSAbortAll = agTRUE; 307 } 308 309 #ifdef FDS_SM 310 if ( DEVICE_IS_SSP_TARGET(oneDeviceData) || DEVICE_IS_SMP_TARGET(oneDeviceData)) 311 { 312 status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 313 } 314 else if (DEVICE_IS_SATA_DEVICE(oneDeviceData) || 315 DEVICE_IS_STP_TARGET(oneDeviceData) 316 ) 317 { 318 TI_DBG2(("tiINIIOAbortAll: calling smIOAbortAll\n")); 319 smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle); 320 smDeviceHandle->tdData = oneDeviceData; 321 status = smIOAbortAll(smRoot, smDeviceHandle); 322 } 323 else 324 { 325 TI_DBG1(("tiINIIOAbortAll: unknow device type!!! 0x%x\n", oneDeviceData->target_ssp_stp_smp)); 326 status = AGSA_RC_FAILURE; 327 } 328 #else 329 status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 330 #endif 331 332 return status; 333 334 } 335 #endif /* INITIATOR_DRIVER */ 336 337 /***************************************************************************** 338 *! \brief tdsaAbortAll 339 * 340 * Purpose: This function is called to abort an all pending I/O request on a 341 * device 342 * 343 * \param tiRoot: Pointer to initiator driver/port instance. 344 * \param agRoot: Pointer to chip/driver Instance. 345 * \param oneDeviceData: Pointer to the device 346 * 347 * \return: 348 * 349 * None 350 * 351 *****************************************************************************/ 352 osGLOBAL bit32 353 tdsaAbortAll( 354 tiRoot_t *tiRoot, 355 agsaRoot_t *agRoot, 356 tdsaDeviceData_t *oneDeviceData 357 ) 358 { 359 agsaIORequest_t *agAbortIORequest = agNULL; 360 tdIORequestBody_t *tdAbortIORequestBody = agNULL; 361 bit32 PhysUpper32; 362 bit32 PhysLower32; 363 bit32 memAllocStatus; 364 void *osMemHandle; 365 bit32 status = AGSA_RC_FAILURE; 366 367 TI_DBG1(("tdsaAbortAll: did %d\n", oneDeviceData->id)); 368 369 /* allocating agIORequest for abort itself */ 370 memAllocStatus = ostiAllocMemory( 371 tiRoot, 372 &osMemHandle, 373 (void **)&tdAbortIORequestBody, 374 &PhysUpper32, 375 &PhysLower32, 376 8, 377 sizeof(tdIORequestBody_t), 378 agTRUE 379 ); 380 if (memAllocStatus != tiSuccess) 381 { 382 /* let os process IO */ 383 TI_DBG1(("tdsaAbortAll: ostiAllocMemory failed...\n")); 384 return tiError; 385 } 386 387 if (tdAbortIORequestBody == agNULL) 388 { 389 /* let os process IO */ 390 TI_DBG1(("tdsaAbortAll: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 391 return tiError; 392 } 393 394 /* setup task management structure */ 395 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 396 /* setting callback but not used later */ 397 tdAbortIORequestBody->IOCompletionFunc = agNULL; 398 //tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler; 399 400 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle); 401 402 /* initialize agIORequest */ 403 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 404 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 405 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 406 407 if ( DEVICE_IS_SSP_TARGET(oneDeviceData)) 408 { 409 /* SSPAbort */ 410 status = saSSPAbort(agRoot, 411 agAbortIORequest, 412 tdsaRotateQnumber(tiRoot, oneDeviceData), //0, 413 oneDeviceData->agDevHandle, 414 1, /* abort all */ 415 agNULL, 416 agNULL 417 ); 418 } 419 else if (DEVICE_IS_SATA_DEVICE(oneDeviceData) || 420 DEVICE_IS_STP_TARGET(oneDeviceData) 421 ) 422 { 423 /* SATAAbort*/ 424 if (oneDeviceData->satDevData.IDDeviceValid == agFALSE) 425 { 426 TI_DBG2(("tdsaAbortAll: saSATAAbort\n")); 427 status = saSATAAbort(agRoot, 428 agAbortIORequest, 429 0, 430 oneDeviceData->agDevHandle, 431 1, /* abort all */ 432 agNULL, 433 agNULL 434 ); 435 } 436 else 437 { 438 TI_DBG2(("tdsaAbortAll: saSATAAbort IDDeviceValid\n")); 439 status = saSATAAbort(agRoot, 440 agAbortIORequest, 441 tdsaRotateQnumber(tiRoot, oneDeviceData), //0, 442 oneDeviceData->agDevHandle, 443 1, /* abort all */ 444 agNULL, 445 agNULL 446 ); 447 } 448 } 449 else if (DEVICE_IS_SMP_TARGET(oneDeviceData)) 450 { 451 /* SMPAbort*/ 452 TI_DBG2(("tdsaAbortAll: saSMPAbort \n")); 453 status = saSMPAbort(agRoot, 454 agAbortIORequest, 455 tdsaRotateQnumber(tiRoot, oneDeviceData), //0, 456 oneDeviceData->agDevHandle, 457 1, /* abort all */ 458 agNULL, 459 agNULL 460 ); 461 } 462 else 463 { 464 TI_DBG1(("tdsaAbortAll: unknown device type!!! 0x%x\n", oneDeviceData->target_ssp_stp_smp)); 465 status = AGSA_RC_FAILURE; 466 } 467 468 if (status == AGSA_RC_SUCCESS) 469 { 470 return tiSuccess; 471 } 472 else 473 { 474 TI_DBG1(("tdsaAbortAll: failed status=%d\n", status)); 475 //failed to send abort command, we need to free the memory 476 ostiFreeMemory( 477 tiRoot, 478 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, 479 sizeof(tdIORequestBody_t) 480 ); 481 return tiError; 482 } 483 484 } 485 486 487 488 /***************************************************************************** 489 *! \brief tiCOMReset 490 * 491 * Purpose: This function is called to trigger soft or hard reset 492 * 493 * \param tiRoot: Pointer to initiator driver/port instance. 494 * \param option: Options 495 * 496 * \return: 497 * 498 * None 499 * 500 *****************************************************************************/ 501 osGLOBAL void 502 tiCOMReset( 503 tiRoot_t *tiRoot, 504 bit32 option 505 ) 506 { 507 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 508 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 509 agsaRoot_t *agRoot = agNULL; 510 511 512 #ifdef TI_GETFOR_ONRESET 513 agsaControllerStatus_t controllerStatus; 514 agsaForensicData_t forensicData; 515 bit32 once = 1; 516 bit32 status; 517 #endif /* TI_GETFOR_ONRESET */ 518 519 TI_DBG1(("tiCOMReset: start option 0x%x\n",option)); 520 tdsaAllShared->resetCount++; 521 TI_DBG2(("tiCOMReset: reset count %d\n", tdsaAllShared->resetCount)); 522 523 agRoot = &(tdsaAllShared->agRootNonInt); 524 525 if (tdsaAllShared->flags.resetInProgress == agTRUE) 526 { 527 TI_DBG1(("tiCOMReset : Reset is already in progress : \n")); 528 529 /* don't do anything : just return */ 530 return; 531 } 532 533 tdsaAllShared->flags.resetInProgress = agTRUE; 534 535 #ifdef TI_GETFOR_ONRESET 536 saGetControllerStatus(agRoot, &controllerStatus); 537 if(controllerStatus.fatalErrorInfo.errorInfo1) 538 { 539 540 bit8 * DirectData = (bit8 * )tdsaAllShared->FatalErrorData; 541 forensicData.DataType = TYPE_FATAL; 542 forensicData.dataBuf.directLen = (8 * 1024); 543 forensicData.dataBuf.directOffset = 0; /* current offset */ 544 forensicData.dataBuf.readLen = 0; /* Data read */ 545 getmoreData: 546 forensicData.dataBuf.directData = DirectData; 547 status = saGetForensicData( agRoot, agNULL, &forensicData); 548 TI_DBG1(("tiCOMReset:status %d readLen 0x%x directLen 0x%x directOffset 0x%x\n", 549 status, 550 forensicData.dataBuf.readLen, 551 forensicData.dataBuf.directLen, 552 forensicData.dataBuf.directOffset)); 553 554 if( forensicData.dataBuf.readLen == forensicData.dataBuf.directLen && !status && once) 555 { 556 DirectData += forensicData.dataBuf.readLen; 557 goto getmoreData; 558 } 559 TI_DBG1(("tiCOMReset:saGetForensicData type %d read 0x%x bytes\n", forensicData.DataType, forensicData.dataBuf.directOffset )); 560 } 561 562 #endif /* TI_GETFOR_ONRESET */ 563 if (option == tiSoftReset) 564 { 565 /* soft reset */ 566 TI_DBG6(("tiCOMReset: soft reset\n")); 567 saHwReset(agRoot, AGSA_SOFT_RESET, 0); 568 return; 569 } 570 else 571 { 572 saHwReset(agRoot, AGSA_SOFT_RESET, 0); 573 #ifdef NOT_YET 574 /* hard reset */ 575 saHwReset(agRoot, AGSA_CHIP_RESET, 0); 576 #endif 577 } 578 return; 579 } 580 581 582 /*****************************************************************************/ 583 /*! \biref tiINIReportErrorToEventLog 584 * 585 * Purpose: This function is called to report errors that needs to be logged 586 * into event log. 587 * 588 * \param tiRoot: Pointer to initiator specific root data structure for this 589 * instance of the driver. 590 * \param agEventData: Event data structure. 591 * 592 * \return None. 593 * 594 */ 595 /*****************************************************************************/ 596 #ifdef INITIATOR_DRIVER 597 osGLOBAL bit32 598 tiINIReportErrorToEventLog( 599 tiRoot_t *tiRoot, 600 tiEVTData_t *agEventData 601 ) 602 { 603 TI_DBG6(("tiINIReportErrorToEventLog: start\n")); 604 return tiError; 605 } 606 #endif /* INITIATOR_DRIVER */ 607 608 /*****************************************************************************/ 609 /*! \brief ossaReenableInterrupts 610 * 611 * 612 * Purpose: This routine is called to enable interrupt 613 * 614 * 615 * \param agRoot: Pointer to chip/driver Instance. 616 * \param outboundChannelNum: Zero-base channel number 617 * 618 * 619 * \return None. 620 * 621 * \note - The scope is shared target and initiator. 622 * 623 */ 624 /*****************************************************************************/ 625 #ifndef ossaReenableInterrupts 626 osGLOBAL void 627 ossaReenableInterrupts( 628 agsaRoot_t *agRoot, 629 bit32 outboundChannelNum 630 ) 631 { 632 tdsaRootOsData_t *osData = (tdsaRootOsData_t *) (agRoot->osData); 633 634 ostiInterruptEnable( 635 osData->tiRoot, 636 outboundChannelNum 637 ); 638 return; 639 } 640 641 #endif 642 643 644 645 646 /* 647 1. initiator 648 send task management 649 call saSSPAbort() 650 651 2. Target 652 call saSSPAbort() 653 654 */ 655 656 /***************************************************************************** 657 *! \brief tiINITaskManagement 658 * 659 * Purpose: This routine is called to explicitly ask the Transport Dependent 660 * Layer to issue a Task Management command to a device. 661 * 662 * \param tiRoot: Pointer to driver instance 663 * \param tiDeviveHandle: Pointer to the device handle for this session. 664 * \param task: SAM-2 task management request. 665 * \param lun: Pointer to the SCSI-3 LUN information 666 * when applicable. Set to zero when not applicable. 667 * \param taskTag: Pointer to the associated task where the task 668 * management command is to be applied. Set to agNULL 669 * if not applicable for the specific Task Management 670 * task. 671 * \param currentTaskTag: The current context or task tag for this task. This 672 * task tag will be passed back in ostiInitiatorEvent() 673 * when this task management is completed. 674 * 675 * \return: 676 * tiSuccess TM request successfully initiated. 677 * tiBusy No resources available, try again later. 678 * tiIONoDevice Invalid device handle. 679 * tiError Other errors that prevent the TM request to be started. 680 * 681 *****************************************************************************/ 682 /* 683 warm reset->smp phy control(hard reset) or saLocalPhyControl(AGSA_PHY_HARD_RESET) 684 685 */ 686 #ifdef INITIATOR_DRIVER 687 osGLOBAL bit32 688 tiINITaskManagement ( 689 tiRoot_t *tiRoot, 690 tiDeviceHandle_t *tiDeviceHandle, 691 bit32 task, 692 tiLUN_t *lun, 693 tiIORequest_t *taskTag, /* being aborted one */ 694 tiIORequest_t *currentTaskTag /* task management itself */ 695 ) 696 { 697 698 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 699 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 700 itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; 701 agsaRoot_t *agRoot = agNULL; 702 bit32 tiStatus = tiError; 703 bit32 notImplemented = agFALSE; 704 tdsaDeviceData_t *oneDeviceData = agNULL; 705 void *osMemHandle; 706 tdIORequestBody_t *TMtdIORequestBody; 707 bit32 PhysUpper32; 708 bit32 PhysLower32; 709 bit32 memAllocStatus; 710 bit32 agRequestType; 711 agsaIORequest_t *agIORequest = agNULL; /* task management itself */ 712 agsaIORequest_t *agTMRequest = agNULL; /* IO being task managed */ 713 agsaDevHandle_t *agDevHandle = agNULL; 714 agsaSASRequestBody_t *agSASRequestBody = agNULL; 715 agsaSSPScsiTaskMgntReq_t *agSSPTaskMgntRequest; 716 bit32 saStatus; 717 tdIORequestBody_t *tdIORequestBody; 718 #ifdef FDS_SM 719 smRoot_t *smRoot; 720 smDeviceHandle_t *smDeviceHandle; 721 smIORequest_t *ToBeAborted = agNULL; 722 smIORequest_t *TaskManagement; 723 tdIORequestBody_t *ToBeAbortedtdIORequestBody; 724 tdIORequestBody_t *SMTMtdIORequestBody; 725 void *SMosMemHandle; 726 bit32 SMPhysUpper32; 727 bit32 SMPhysLower32; 728 bit32 SMmemAllocStatus; 729 #endif 730 731 TI_DBG2(("tiINITaskManagement: start\n")); 732 733 /* just for testing only */ 734 #ifdef REMOVED 735 //start temp 736 if(tiDeviceHandle == agNULL) 737 { 738 TI_DBG1(("tiINITaskManagement: tiDeviceHandle is NULL\n")); 739 return tiError; 740 } 741 742 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 743 if(oneDeviceData == agNULL) 744 { 745 TI_DBG1(("tiINITaskManagement: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle)); 746 return tiError; 747 } 748 TI_DBG1(("tiINITaskManagement: did %d\n", oneDeviceData->id )); 749 return tiError; 750 //end temp 751 752 // just for testing 753 if (task == AG_LOGICAL_UNIT_RESET) 754 { 755 TI_DBG1(("tiINITaskManagement: failing LUN RESET for testing\n")); 756 return tiError; 757 } 758 759 #endif 760 761 switch(task) 762 { 763 case AG_ABORT_TASK: 764 TI_DBG6(("tiINITaskManagement: ABORT_TASK\n")); 765 break; 766 case AG_ABORT_TASK_SET: 767 TI_DBG6(("tiINITaskManagement: ABORT_TASK_SET\n")); 768 break; 769 case AG_CLEAR_ACA: 770 TI_DBG6(("tiINITaskManagement: CLEAR_ACA\n")); 771 break; 772 case AG_CLEAR_TASK_SET: 773 TI_DBG6(("tiINITaskManagement: CLEAR_TASK_SET\n")); 774 break; 775 case AG_LOGICAL_UNIT_RESET: 776 TI_DBG6(("tiINITaskManagement: LOGICAL_UNIT_RESET\n")); 777 break; 778 case AG_TARGET_WARM_RESET: 779 TI_DBG6(("tiINITaskManagement: TARGET_WARM_RESET\n")); 780 break; 781 case AG_QUERY_TASK: 782 TI_DBG6(("tiINITaskManagement: QUERY_TASK\n")); 783 break; 784 default: 785 TI_DBG1(("tiINITaskManagement: notImplemented 0x%0x !!!\n",task)); 786 notImplemented = agTRUE; 787 break; 788 } 789 790 if (notImplemented) 791 { 792 TI_DBG1(("tiINITaskManagement: not implemented 0x%0x !!!\n",task)); 793 return tiStatus; 794 } 795 796 if(tiDeviceHandle == agNULL) 797 { 798 TI_DBG1(("tiINITaskManagement: tiDeviceHandle is NULL\n")); 799 return tiError; 800 } 801 802 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 803 if(oneDeviceData == agNULL) 804 { 805 TI_DBG1(("tiINITaskManagement: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle)); 806 return tiIONoDevice; 807 } 808 809 /* for hotplug */ 810 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 811 oneDeviceData->tdPortContext == agNULL ) 812 { 813 TI_DBG1(("tiINITaskManagement: NO Device did %d Addr 0x%08x:0x%08x\n", oneDeviceData->id , oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 814 return tiIONoDevice; 815 } 816 817 /* 1. call tiINIOAbort() 818 2. call tdssTaskXmit() 819 */ 820 821 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 822 { 823 agRoot = oneDeviceData->agRoot; 824 agDevHandle = oneDeviceData->agDevHandle; 825 TI_DBG1(("tiINITaskManagement: SAS Device\n")); 826 827 /* 828 WARM_RESET is experimental code. 829 Needs more testing and debugging 830 */ 831 if (task == AG_TARGET_WARM_RESET) 832 { 833 agsaContext_t *agContext; 834 tdsaDeviceData_t *tdsaDeviceData; 835 836 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 837 currentTaskTag->tdData = tdsaDeviceData; 838 agContext = &(tdsaDeviceData->agDeviceResetContext); 839 agContext->osData = currentTaskTag; 840 841 TI_DBG2(("tiINITaskManagement: did %d device reset for SAS\n", oneDeviceData->id)); 842 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY); 843 844 /* warm reset by saLocalPhyControl or SMP PHY control */ 845 if (oneDeviceData->directlyAttached == agTRUE) 846 { 847 TI_DBG2(("tiINITaskManagement: device reset directly attached\n")); 848 saLocalPhyControl(agRoot, 849 agContext, 850 tdsaRotateQnumber(tiRoot, oneDeviceData), 851 oneDeviceData->phyID, 852 AGSA_PHY_HARD_RESET, 853 agNULL 854 ); 855 return tiSuccess; 856 } 857 else 858 { 859 TI_DBG2(("tiINITaskManagement: device reset expander attached\n")); 860 saStatus = tdsaPhyControlSend(tiRoot, 861 oneDeviceData, 862 SMP_PHY_CONTROL_HARD_RESET, 863 currentTaskTag, 864 tdsaRotateQnumber(tiRoot, oneDeviceData) 865 ); 866 return saStatus; 867 } 868 } 869 else 870 { 871 /* task management */ 872 TI_DBG6(("tiINITaskManagement: making task management frame \n")); 873 /* 1. create task management frame 874 2. sends it using "saSSPStart()" 875 */ 876 /* Allocate memory for task management */ 877 memAllocStatus = ostiAllocMemory( 878 tiRoot, 879 &osMemHandle, 880 (void **)&TMtdIORequestBody, 881 &PhysUpper32, 882 &PhysLower32, 883 8, 884 sizeof(tdIORequestBody_t), 885 agTRUE 886 ); 887 888 if (memAllocStatus != tiSuccess) 889 { 890 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed...\n")); 891 return tiError; 892 } 893 894 if (TMtdIORequestBody == agNULL) 895 { 896 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody\n")); 897 return tiError; 898 } 899 900 /* initialize */ 901 osti_memset(TMtdIORequestBody, 0, sizeof(tdIORequestBody_t)); 902 903 /* setup task management structure */ 904 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 905 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag; 906 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag; 907 908 /* let's initialize tdIOrequestBody */ 909 /* initialize jump table */ 910 911 /* direct callback for task management */ 912 TMtdIORequestBody->IOCompletionFunc = itdssTaskCompleted; 913 /* to be removed */ 914 /* TMtdIORequestBody->IOCompletionFunc = itdssIOCompleted; */ 915 916 /* initialize tiDevhandle */ 917 TMtdIORequestBody->tiDevHandle = tiDeviceHandle; 918 919 /* initialize tiIORequest */ 920 TMtdIORequestBody->tiIORequest = currentTaskTag; 921 /* save context if we need to abort later */ 922 currentTaskTag->tdData = TMtdIORequestBody; 923 924 /* initialize agIORequest */ 925 agIORequest = &(TMtdIORequestBody->agIORequest); 926 agIORequest->osData = (void *) TMtdIORequestBody; 927 agIORequest->sdkData = agNULL; /* SA takes care of this */ 928 929 /* request type */ 930 agRequestType = AGSA_SSP_TASK_MGNT_REQ; 931 TMtdIORequestBody->agRequestType = AGSA_SSP_TASK_MGNT_REQ; 932 /* 933 initialize 934 tdIORequestBody_t tdIORequestBody -> agSASRequestBody 935 */ 936 agSASRequestBody = &(TMtdIORequestBody->transport.SAS.agSASRequestBody); 937 agSSPTaskMgntRequest = &(agSASRequestBody->sspTaskMgntReq); 938 939 TI_DBG2(("tiINITaskManagement: did %d LUN reset for SAS\n", oneDeviceData->id)); 940 /* fill up LUN field */ 941 if (lun == agNULL) 942 { 943 osti_memset(agSSPTaskMgntRequest->lun, 0, 8); 944 } 945 else 946 { 947 osti_memcpy(agSSPTaskMgntRequest->lun, lun->lun, 8); 948 } 949 950 /* default: unconditionally set device state to SA_DS_IN_RECOVERY 951 bit1 (DS) bit0 (ADS) 952 bit1: 1 bit0: 0 953 */ 954 agSSPTaskMgntRequest->tmOption = 2; 955 956 /* sets taskMgntFunction field */ 957 switch(task) 958 { 959 case AG_ABORT_TASK: 960 agSSPTaskMgntRequest->taskMgntFunction = AGSA_ABORT_TASK; 961 /* For abort task management, unconditionally set device state to SA_DS_IN_RECOVERY 962 and if can't find, set device state to SA_DS_IN_RECOVERY 963 bit1 (DS) bit0 (ADS) 964 bit1: 1; bit0: 1 965 */ 966 agSSPTaskMgntRequest->tmOption = 3; 967 break; 968 case AG_ABORT_TASK_SET: 969 agSSPTaskMgntRequest->taskMgntFunction = AGSA_ABORT_TASK_SET; 970 break; 971 case AG_CLEAR_ACA: 972 agSSPTaskMgntRequest->taskMgntFunction = AGSA_CLEAR_ACA; 973 break; 974 case AG_CLEAR_TASK_SET: 975 agSSPTaskMgntRequest->taskMgntFunction = AGSA_CLEAR_TASK_SET; 976 break; 977 case AG_LOGICAL_UNIT_RESET: 978 agSSPTaskMgntRequest->taskMgntFunction = AGSA_LOGICAL_UNIT_RESET; 979 break; 980 case AG_QUERY_TASK: 981 agSSPTaskMgntRequest->taskMgntFunction = AGSA_QUERY_TASK; 982 break; 983 default: 984 TI_DBG1(("tiINITaskManagement: notImplemented task\n")); 985 break; 986 } 987 988 if (task == AGSA_ABORT_TASK || task == AGSA_QUERY_TASK) 989 { 990 /* set agTMRequest, which is IO being task managed */ 991 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 992 if (tdIORequestBody == agNULL) 993 { 994 /* to be aborted IO has been completed. */ 995 /* free up allocated memory */ 996 TI_DBG1(("tiINITaskManagement: IO has been completed\n")); 997 ostiFreeMemory( 998 tiRoot, 999 osMemHandle, 1000 sizeof(tdIORequestBody_t) 1001 ); 1002 return tiIONoDevice; 1003 } 1004 else 1005 { 1006 agTMRequest = &(tdIORequestBody->agIORequest); 1007 } 1008 } 1009 else 1010 { 1011 /* 1012 For LUN RESET, WARM_RESET, ABORT_TASK_SET, CLEAR_ACA and CLEAR_TASK_SET 1013 no tag to be managed. 1014 Therefore, set it to zero. 1015 */ 1016 agSSPTaskMgntRequest->tagOfTaskToBeManaged = 0; 1017 agTMRequest = agNULL; 1018 1019 } 1020 1021 TDLIST_INIT_HDR(&TMtdIORequestBody->EsglPageList); 1022 /* debuggging */ 1023 if (TMtdIORequestBody->IOCompletionFunc == agNULL) 1024 { 1025 TI_DBG1(("tiINITaskManagement: Error!!!!! IOCompletionFunc is NULL\n")); 1026 } 1027 saStatus = saSSPStart(agRoot, 1028 agIORequest, /* task management itself */ 1029 tdsaRotateQnumber(tiRoot, oneDeviceData), 1030 agDevHandle, 1031 agRequestType, 1032 agSASRequestBody, /* task management itself */ 1033 agTMRequest, /* io to be aborted if exits */ 1034 &ossaSSPCompleted); 1035 1036 1037 if (saStatus == AGSA_RC_SUCCESS) 1038 { 1039 Initiator->NumIOsActive++; 1040 tiStatus = tiSuccess; 1041 } 1042 else 1043 { 1044 TI_DBG1(("tiINITaskManagement: saSSPStart failed 0x%x\n",saStatus)); 1045 /* free up allocated memory */ 1046 ostiFreeMemory( 1047 tiRoot, 1048 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 1049 sizeof(tdIORequestBody_t) 1050 ); 1051 if (saStatus == AGSA_RC_FAILURE) 1052 { 1053 tiStatus = tiError; 1054 } 1055 else 1056 { 1057 /* AGSA_RC_BUSY */ 1058 tiStatus = tiBusy; 1059 } 1060 } 1061 } 1062 } /* end of sas device */ 1063 1064 #ifdef FDS_SM 1065 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1066 { 1067 agsaContext_t *agContext = agNULL; 1068 1069 /* save the task tag in tdsaDeviceData_t structure, for handling PORT_RESET_COMPLETE hw event */ 1070 agContext = &(oneDeviceData->agDeviceResetContext); 1071 agContext->osData = currentTaskTag; 1072 1073 #ifdef REMOVED 1074 /* for directly attached SATA, do localphycontrol for LUN and target reset, not smTaskManagement*/ 1075 if (oneDeviceData->directlyAttached == agTRUE && 1076 (task == AG_LOGICAL_UNIT_RESET || task == AG_TARGET_WARM_RESET)) 1077 { 1078 agRoot = oneDeviceData->agRoot; 1079 agDevHandle = oneDeviceData->agDevHandle; 1080 1081 currentTaskTag->tdData = oneDeviceData; 1082 1083 if (task == AG_LOGICAL_UNIT_RESET) 1084 { 1085 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 1086 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 1087 { 1088 TI_DBG1(("tiINITaskManagement: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n", 1089 tiDeviceHandle)); 1090 return tiError; 1091 } 1092 } 1093 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY); 1094 tiStatus = saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL); 1095 } 1096 else 1097 #endif 1098 { 1099 smRoot = &(tdsaAllShared->smRoot); 1100 smDeviceHandle = &(oneDeviceData->smDeviceHandle); 1101 TI_DBG1(("tiINITaskManagement: FDS_SM SATA Device\n")); 1102 1103 if ( taskTag != agNULL) 1104 { 1105 ToBeAbortedtdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 1106 ToBeAborted = &(ToBeAbortedtdIORequestBody->smIORequest); 1107 } 1108 SMmemAllocStatus = ostiAllocMemory( 1109 tiRoot, 1110 &SMosMemHandle, 1111 (void **)&SMTMtdIORequestBody, 1112 &SMPhysUpper32, 1113 &SMPhysLower32, 1114 8, 1115 sizeof(tdIORequestBody_t), 1116 agTRUE 1117 ); 1118 if (SMmemAllocStatus != tiSuccess) 1119 { 1120 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed... loc 2\n")); 1121 return tiError; 1122 } 1123 1124 if (SMTMtdIORequestBody == agNULL) 1125 { 1126 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody loc 2\n")); 1127 return tiError; 1128 } 1129 1130 /* initialize */ 1131 osti_memset(SMTMtdIORequestBody, 0, sizeof(tdIORequestBody_t)); 1132 1133 /* setup task management structure */ 1134 SMTMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = SMosMemHandle; 1135 SMTMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag; 1136 SMTMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag; 1137 1138 /* initialize tiDevhandle */ 1139 SMTMtdIORequestBody->tiDevHandle = tiDeviceHandle; 1140 1141 /* initialize tiIORequest */ 1142 SMTMtdIORequestBody->tiIORequest = currentTaskTag; 1143 /* save context if we need to abort later */ 1144 currentTaskTag->tdData = SMTMtdIORequestBody; 1145 1146 TaskManagement = &(SMTMtdIORequestBody->smIORequest); 1147 1148 TaskManagement->tdData = SMTMtdIORequestBody; 1149 TaskManagement->smData = &SMTMtdIORequestBody->smIORequestBody; 1150 1151 tiStatus = smTaskManagement(smRoot, 1152 smDeviceHandle, 1153 task, 1154 (smLUN_t*)lun, 1155 ToBeAborted, 1156 TaskManagement 1157 ); 1158 if (tiStatus != SM_RC_SUCCESS) 1159 { 1160 TI_DBG1(("tiINITaskManagement: smTaskManagement failed... loc 2\n")); 1161 /* free up allocated memory */ 1162 ostiFreeMemory( 1163 tiRoot, 1164 SMTMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 1165 sizeof(tdIORequestBody_t) 1166 ); 1167 } 1168 } /* else */ 1169 } 1170 #else 1171 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1172 { 1173 agRoot = oneDeviceData->agRoot; 1174 agDevHandle = oneDeviceData->agDevHandle; 1175 TI_DBG1(("tiINITaskManagement: not FDS_SM SATA Device\n")); 1176 /* 1177 WARM_RESET is experimental 1178 Needs more testing and debugging 1179 Soft reset for SATA as LUN RESET tends not to work. 1180 Let's do hard reset 1181 */ 1182 if (task == AG_LOGICAL_UNIT_RESET || task == AG_TARGET_WARM_RESET) 1183 { 1184 1185 agsaContext_t *agContext; 1186 satDeviceData_t *satDevData; 1187 tdsaDeviceData_t *tdsaDeviceData; 1188 1189 TI_DBG2(("tiINITaskManagement: did %d LUN reset or device reset for SATA\n", oneDeviceData->id)); 1190 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1191 satDevData = &tdsaDeviceData->satDevData; 1192 currentTaskTag->tdData = tdsaDeviceData; 1193 agContext = &(tdsaDeviceData->agDeviceResetContext); 1194 agContext->osData = currentTaskTag; 1195 1196 1197 if (task == AG_LOGICAL_UNIT_RESET) 1198 { 1199 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 1200 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 1201 { 1202 TI_DBG1(("tiINITaskManagement: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n", 1203 tiDeviceHandle)); 1204 return tiError; 1205 } 1206 1207 /* 1208 * Check if there is other TM request pending 1209 */ 1210 if (satDevData->satTmTaskTag != agNULL) 1211 { 1212 TI_DBG1(("tiINITaskManagement: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 1213 tiDeviceHandle)); 1214 return tiError; 1215 } 1216 } 1217 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 1218 satDevData->satAbortAfterReset = agFALSE; 1219 1220 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY); 1221 1222 /* 1223 warm reset by saLocalPhyControl or SMP PHY control 1224 */ 1225 if (oneDeviceData->directlyAttached == agTRUE) 1226 { 1227 TI_DBG1(("tiINITaskManagement: LUN reset or device reset directly attached\n")); 1228 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL); 1229 return tiSuccess; 1230 } 1231 else 1232 { 1233 TI_DBG1(("tiINITaskManagement: LUN reset or device reset expander attached\n")); 1234 saStatus = tdsaPhyControlSend(tiRoot, 1235 oneDeviceData, 1236 SMP_PHY_CONTROL_HARD_RESET, 1237 currentTaskTag, 1238 tdsaRotateQnumber(tiRoot, oneDeviceData) 1239 ); 1240 return saStatus; 1241 } 1242 } 1243 else 1244 { 1245 TI_DBG2(("tiINITaskManagement: calling satTM().\n")); 1246 /* allocation tdIORequestBody and pass it to satTM() */ 1247 memAllocStatus = ostiAllocMemory( 1248 tiRoot, 1249 &osMemHandle, 1250 (void **)&TMtdIORequestBody, 1251 &PhysUpper32, 1252 &PhysLower32, 1253 8, 1254 sizeof(tdIORequestBody_t), 1255 agTRUE 1256 ); 1257 1258 if (memAllocStatus != tiSuccess) 1259 { 1260 TI_DBG1(("tiINITaskManagement: ostiAllocMemory failed... loc 2\n")); 1261 return tiError; 1262 } 1263 1264 if (TMtdIORequestBody == agNULL) 1265 { 1266 TI_DBG1(("tiINITaskManagement: ostiAllocMemory returned NULL TMIORequestBody loc 2\n")); 1267 return tiError; 1268 1269 } 1270 1271 /* initialize */ 1272 osti_memset(TMtdIORequestBody, 0, sizeof(tdIORequestBody_t)); 1273 1274 /* setup task management structure */ 1275 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 1276 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = currentTaskTag; 1277 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = taskTag; 1278 1279 /* initialize tiDevhandle */ 1280 TMtdIORequestBody->tiDevHandle = tiDeviceHandle; 1281 1282 /* initialize tiIORequest */ 1283 TMtdIORequestBody->tiIORequest = currentTaskTag; 1284 /* save context if we need to abort later */ 1285 currentTaskTag->tdData = TMtdIORequestBody; 1286 1287 /* initialize agIORequest */ 1288 agIORequest = &(TMtdIORequestBody->agIORequest); 1289 agIORequest->osData = (void *) TMtdIORequestBody; 1290 agIORequest->sdkData = agNULL; /* SA takes care of this */ 1291 1292 1293 #ifdef SATA_ENABLE 1294 tiStatus = satTM( tiRoot, 1295 tiDeviceHandle, 1296 task, 1297 lun, 1298 taskTag, 1299 currentTaskTag, 1300 TMtdIORequestBody, 1301 agTRUE 1302 ); 1303 #endif 1304 } 1305 } 1306 #endif /* FDS_SM else*/ 1307 1308 return tiStatus; 1309 } 1310 #endif /* INITIATOR_DRIVER */ 1311 1312 #ifdef PASSTHROUGH 1313 osGLOBAL bit32 1314 tiCOMPassthroughCmndStart( 1315 tiRoot_t *tiRoot, 1316 tiPassthroughRequest_t *tiPassthroughRequest, 1317 tiDeviceHandle_t *tiDeviceHandle, 1318 tiPassthroughCmnd_t *tiPassthroughCmnd, 1319 void *tiPassthroughBody, 1320 tiPortalContext_t *tiportalContext, 1321 ostiPassthroughCmndEvent_t agEventCB 1322 ) 1323 { 1324 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1325 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1326 tdsaDeviceData_t *oneDeviceData; 1327 agsaRoot_t *agRoot = agNULL; 1328 agsaIORequest_t *agIORequest = agNULL; 1329 agsaDevHandle_t *agDevHandle = agNULL; 1330 bit32 agRequestType; 1331 agsaSASRequestBody_t *agSASRequestBody = agNULL; 1332 1333 tdPassthroughCmndBody_t *tdPTCmndBody; 1334 tdssSMPRequestBody_t *tdssSMPRequestBody; 1335 agsaSMPFrame_t *agSMPFrame; 1336 agsaSSPVSFrame_t *agSSPVendorFrame; /* RMC */ 1337 bit32 SMPFn, SMPFnResult, SMPFrameLen; 1338 bit32 tiStatus = tiError; 1339 bit32 saStatus = AGSA_RC_FAILURE; 1340 tdsaPortStartInfo_t *tdsaPortStartInfo; 1341 tdsaPortContext_t *tdsaPortContext; 1342 1343 TI_DBG2(("tiCOMPassthroughCmndStart: start\n")); 1344 1345 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1346 1347 TI_DBG6(("tiCOMPassthroughCmndStart: onedevicedata %p\n", oneDeviceData)); 1348 1349 1350 tdPTCmndBody = (tdPassthroughCmndBody_t *)tiPassthroughBody; 1351 1352 1353 if (tiPassthroughCmnd->passthroughCmnd != tiSMPCmnd || 1354 tiPassthroughCmnd->passthroughCmnd != tiRMCCmnd) 1355 { 1356 return tiNotSupported; 1357 } 1358 1359 1360 if (oneDeviceData == agNULL && tiPassthroughCmnd->passthroughCmnd != tiSMPCmnd) 1361 { 1362 TI_DBG1(("tiCOMPassthroughCmndStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle )); 1363 return tiIONoDevice; 1364 } 1365 1366 /* starting IO with SAS device */ 1367 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 1368 { 1369 if (tiPassthroughCmnd->passthroughCmnd == tiSMPCmnd) 1370 { 1371 TI_DBG2(("tiCOMPassthroughCmndStart: SMP\n")); 1372 if (oneDeviceData == agNULL) 1373 { 1374 tdsaPortStartInfo = (tdsaPortStartInfo_t *)tiportalContext->tdData; 1375 tdsaPortContext = tdsaPortStartInfo->portContext; 1376 agRoot = tdsaPortContext->agRoot; 1377 } 1378 else 1379 { 1380 agRoot = oneDeviceData->agRoot; 1381 agDevHandle = oneDeviceData->agDevHandle; 1382 } 1383 1384 1385 tdssSMPRequestBody = &(tdPTCmndBody->protocol.SMP.SMPBody); 1386 agSASRequestBody = &(tdssSMPRequestBody->agSASRequestBody); 1387 agSMPFrame = &(agSASRequestBody->smpFrame); 1388 1389 /* saves callback function */ 1390 tdPTCmndBody->EventCB = agEventCB; 1391 1392 /* initialize command type */ 1393 tdPTCmndBody->tiPassthroughCmndType = tiSMPCmnd; 1394 1395 /* initialize tipassthroughrequest */ 1396 tdPTCmndBody->tiPassthroughRequest = tiPassthroughRequest; 1397 tiPassthroughRequest->tdData = tdPTCmndBody; 1398 1399 /* initialize tiDevhandle */ 1400 tdPTCmndBody->tiDevHandle = tiDeviceHandle; 1401 1402 /* fill in SMP header */ 1403 agSMPFrame->frameHeader.smpFrameType 1404 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFrameType; 1405 agSMPFrame->frameHeader.smpFunction 1406 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFunction; 1407 agSMPFrame->frameHeader.smpFunctionResult 1408 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpFunctionResult; 1409 agSMPFrame->frameHeader.smpReserved 1410 = tiPassthroughCmnd->protocol.SMP.SMPHeader.smpReserved; 1411 1412 if (tiPassthroughCmnd->protocol.SMP.IT == SMP_INITIATOR) 1413 { 1414 agRequestType = AGSA_SMP_INIT_REQ; 1415 } 1416 else 1417 { 1418 agRequestType = AGSA_SMP_TGT_RESPONSE; 1419 /* this is only for SMP target */ 1420 agSMPFrame->phyId = tiPassthroughCmnd->protocol.SMP.phyID; 1421 } 1422 1423 /* fill in payload */ 1424 /* assumption: SMP payload is in tisgl1 */ 1425 agSMPFrame->frameAddrUpper32 = tiPassthroughCmnd->tiSgl.upper; 1426 agSMPFrame->frameAddrLower32 = tiPassthroughCmnd->tiSgl.lower; 1427 1428 /* This length excluding SMP header (4 bytes) and CRC field */ 1429 agSMPFrame->frameLen = tiPassthroughCmnd->tiSgl.len; 1430 1431 /* initialize agIORequest */ 1432 /* 1433 Compare: 1434 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 1435 */ 1436 agIORequest = &(tdssSMPRequestBody->agIORequest); 1437 agIORequest->osData = (void *) tdPTCmndBody; 1438 agIORequest->sdkData = agNULL; /* LL takes care of this */ 1439 1440 1441 1442 /* not work yet because of high priority q */ 1443 saStatus = saSMPStart( 1444 agRoot, 1445 agIORequest, 1446 agDevHandle, 1447 agRequestType, 1448 agSASRequestBody, 1449 &ossaSMPCompleted 1450 ); 1451 1452 if (saStatus == AGSA_RC_SUCCESS) 1453 { 1454 tiStatus = tiSuccess; 1455 } 1456 else if (saStatus == AGSA_RC_FAILURE) 1457 { 1458 TI_DBG1(("tiCOMPassthroughCmndStart: saSMPStart failed\n")); 1459 tiStatus = tiError; 1460 } 1461 else 1462 { 1463 /* AGSA_RC_BUSY */ 1464 TI_DBG1(("tiCOMPassthroughCmndStart: saSMPStart busy\n")); 1465 tiStatus = tiBusy; 1466 } 1467 return tiStatus; 1468 1469 1470 #ifdef TO_DO 1471 /* fill in SMP header */ 1472 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1473 { 1474 agSMPFrame->frameHeader.smpFrameType = SMP_REQUEST; /* SMP REQUEST */ 1475 agRequestType = AGSA_SMP_INIT_REQ; 1476 } 1477 else 1478 { 1479 /* SMP target */ 1480 agSMPFrame->frameHeader.smpFrameType = SMP_RESPONSE; /* SMP RESPONSE */ 1481 agRequestType = AGSA_SMP_TGT_RESPONSE; 1482 switch (tdPTCmndBody->protocol.SMP.SMPFnResult) 1483 { 1484 case tiSMPFunctionAccepted: 1485 SMPFnResult = SMP_FUNCTION_ACCEPTED; 1486 break; 1487 case tiUnknownSMPFunction: 1488 SMPFnResult = UNKNOWN_SMP_FUNCTION; 1489 break; 1490 case tiSMPFunctionFailed: 1491 SMPFnResult = SMP_FUNCTION_FAILED; 1492 break; 1493 case tiInvalidRequestFrameLength: 1494 SMPFnResult = INVALID_REQUEST_FRAME_LENGTH; 1495 break; 1496 case tiPhyDoesNotExist: 1497 SMPFnResult =PHY_DOES_NOT_EXIST; 1498 break; 1499 case tiIndexDoesNotExist: 1500 SMPFnResult = INDEX_DOES_NOT_EXIST; 1501 break; 1502 case tiPhyDoesNotSupportSATA: 1503 SMPFnResult = PHY_DOES_NOT_SUPPORT_SATA; 1504 break; 1505 case tiUnknownPhyOperation: 1506 SMPFnResult = UNKNOWN_PHY_OPERATION; 1507 break; 1508 case tiUnknownPhyTestFunction: 1509 SMPFnResult = UNKNOWN_PHY_TEST_FUNCTION; 1510 break; 1511 case tiPhyTestFunctionInProgress: 1512 SMPFnResult = PHY_TEST_FUNCTION_IN_PROGRESS; 1513 break; 1514 case tiPhyVacant: 1515 SMPFnResult = PHY_VACANT; 1516 break; 1517 1518 default: 1519 TI_DBG1(("tiCOMPassthroughCmndStart: unknown SMP function result %d\n", tdPTCmndBody->protocol.SMP.SMPFnResult)); 1520 return tiError; 1521 } 1522 agSMPFrame->frameHeader.smpFunctionResult = SMPFnResult; 1523 } 1524 1525 /* common */ 1526 switch (tdPTCmndBody->protocol.SMP.SMPFn) 1527 { 1528 case tiGeneral: 1529 SMPFn = SMP_REPORT_GENERAL; 1530 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1531 { 1532 SMPFrameLen = 0; 1533 } 1534 else 1535 { 1536 SMPFrameLen = sizeof(smpRespReportGeneral_t); 1537 } 1538 break; 1539 1540 case tiManufacturerInfo: 1541 SMPFn = SMP_REPORT_MANUFACTURE_INFORMATION; 1542 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1543 { 1544 SMPFrameLen = 0; 1545 } 1546 else 1547 { 1548 SMPFrameLen = sizeof(smpRespReportManufactureInfo_t); 1549 } 1550 break; 1551 1552 case tiDiscover: 1553 SMPFn = SMP_DISCOVER; 1554 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1555 { 1556 SMPFrameLen = sizeof(smpReqDiscover_t); 1557 } 1558 else 1559 { 1560 SMPFrameLen = sizeof(smpRespDiscover_t); 1561 } 1562 break; 1563 1564 case tiReportPhyErrLog: 1565 SMPFn = SMP_REPORT_PHY_ERROR_LOG; 1566 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1567 { 1568 SMPFrameLen = 8; 1569 } 1570 else 1571 { 1572 SMPFrameLen = 24; 1573 } 1574 break; 1575 1576 case tiReportPhySATA: 1577 SMPFn = SMP_REPORT_PHY_SATA; 1578 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1579 { 1580 SMPFrameLen = sizeof(SmpReqReportPhySata_t); 1581 } 1582 else 1583 { 1584 SMPFrameLen = sizeof(SmpRespReportPhySata_t); 1585 } 1586 break; 1587 1588 case tiReportRteInfo: 1589 SMPFn = SMP_REPORT_ROUTING_INFORMATION; 1590 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1591 { 1592 SMPFrameLen = sizeof(SmpReqReportRouteTable_t); 1593 } 1594 else 1595 { 1596 SMPFrameLen = sizeof(SmpRespReportRouteTable_t); 1597 } 1598 break; 1599 1600 case tiConfigureRteInfo: 1601 SMPFn = SMP_CONFIGURE_ROUTING_INFORMATION; 1602 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1603 { 1604 SMPFrameLen = sizeof(SmpReqConfigureRouteInformation_t); 1605 } 1606 else 1607 { 1608 SMPFrameLen = 0; 1609 } 1610 break; 1611 1612 case tiPhyCtrl: 1613 SMPFn = SMP_PHY_CONTROL; 1614 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1615 { 1616 SMPFrameLen = sizeof(SmpReqPhyControl_t); 1617 } 1618 else 1619 { 1620 SMPFrameLen = 0; 1621 } 1622 break; 1623 1624 case tiPhyTestFn: 1625 SMPFn = SMP_PHY_TEST_FUNCTION; 1626 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1627 { 1628 SMPFrameLen = 36; 1629 } 1630 else 1631 { 1632 SMPFrameLen = 0; 1633 } 1634 break; 1635 1636 case tiPMC: 1637 SMPFn = SMP_PMC_SPECIFIC; 1638 if (tdPTCmndBody->protocol.SMP.IT == SMP_INITIATOR) 1639 { 1640 SMPFrameLen = 0; 1641 } 1642 else 1643 { 1644 SMPFrameLen = 0; 1645 } 1646 break; 1647 1648 1649 default: 1650 TI_DBG1(("tiCOMPassthroughCmndStart: unknown SMP function %d\n", tdPTCmndBody->protocol.SMP.SMPFn)); 1651 return tiError; 1652 } 1653 agSMPFrame->frameHeader.smpFunction = SMPFn; 1654 1655 1656 /* assumption: SMP payload is in tisgl1 */ 1657 agSMPFrame->frameAddrUpper32 = tdPTCmndBody->tiSgl.upper; 1658 agSMPFrame->frameAddrLower32 = tdPTCmndBody->tiSgl.lower; 1659 1660 /* This length excluding SMP header (4 bytes) and CRC field */ 1661 agSMPFrame->frameLen = SMPFrameLen; 1662 1663 1664 1665 1666 1667 1668 #endif 1669 1670 1671 } 1672 else if (tiPassthroughCmnd->passthroughCmnd == tiRMCCmnd) 1673 { 1674 TI_DBG2(("tiCOMPassthroughCmndStart: RMC\n")); 1675 } 1676 else 1677 { 1678 TI_DBG1(("tiCOMPassthroughCmndStart: unknown protocol %d\n", tiPassthroughCmnd->passthroughCmnd)); 1679 } 1680 1681 1682 } 1683 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 1684 { 1685 TI_DBG1(("tiCOMPassthroughCmndStart: error !!! no SATA support\n")); 1686 return tiError; 1687 } 1688 else 1689 { 1690 TI_DBG1(("tiCOMPassthroughCmndStart: error !!! unknown devietype %d\n", oneDeviceData->DeviceType)); 1691 return tiError; 1692 1693 } 1694 1695 return tiSuccess; 1696 } 1697 1698 1699 osGLOBAL bit32 1700 tiCOMPassthroughCmndAbort( 1701 tiRoot_t *tiRoot, 1702 tiPassthroughRequest_t *taskTag 1703 ) 1704 { 1705 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1706 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1707 agsaRoot_t *agRoot = agNULL; 1708 tdPassthroughCmndBody_t *tdPTCmndBody = agNULL; 1709 tdssSMPRequestBody_t *tdssSMPRequestBody = agNULL; 1710 agsaIORequest_t *agIORequest = agNULL; 1711 bit32 saStatus, tiStatus = tiError; 1712 1713 TI_DBG2(("tiCOMPassthroughCmndAbort: start\n")); 1714 1715 agRoot = &(tdsaAllShared->agRootNonInt); 1716 tdPTCmndBody = (tdPassthroughCmndBody_t *)taskTag->tdData; 1717 1718 if (tdPTCmndBody->tiPassthroughCmndType == tiSMPCmnd) 1719 { 1720 tdssSMPRequestBody = &(tdPTCmndBody->protocol.SMP.SMPBody); 1721 agIORequest = &(tdssSMPRequestBody->agIORequest); 1722 1723 saStatus = saSMPAbort(agRoot, agIORequest); 1724 1725 if (saStatus == AGSA_RC_SUCCESS) 1726 { 1727 tiStatus = tiSuccess; 1728 } 1729 else if (saStatus == AGSA_RC_FAILURE) 1730 { 1731 TI_DBG1(("tiCOMPassthroughCmndAbort: saSMPAbort failed\n")); 1732 tiStatus = tiError; 1733 } 1734 else 1735 { 1736 /* AGSA_RC_BUSY */ 1737 TI_DBG1(("tiCOMPassthroughCmndAbort: saSMPAbort busy\n")); 1738 tiStatus = tiBusy; 1739 } 1740 return tiStatus; 1741 } 1742 else if (tdPTCmndBody->tiPassthroughCmndType == tiRMCCmnd) 1743 { 1744 TI_DBG1(("tiCOMPassthroughCmndAbort: RMC passthrough command type, not yet\n")); 1745 1746 } 1747 else 1748 { 1749 TI_DBG1(("tiCOMPassthroughCmndAbort: unknown passthrough command type %d\n", tdPTCmndBody->tiPassthroughCmndType)); 1750 return tiStatus; 1751 } 1752 1753 1754 } 1755 1756 osGLOBAL bit32 1757 tiINIPassthroughCmndRemoteAbort( 1758 tiRoot_t *tiRoot, 1759 tiDeviceHandle_t *tiDeviceHandle, 1760 tiPassthroughRequest_t *taskTag, 1761 tiPassthroughRequest_t *currentTaskTag, 1762 tiPortalContext_t *tiportalContext 1763 ) 1764 { 1765 TI_DBG2(("tiINIPassthroughCmndRemoteAbort: start\n")); 1766 /* 1767 for SMP, nothing. Can't abot remotely 1768 */ 1769 return tiSuccess; 1770 } 1771 #endif /* PASSTHROUGH */ 1772 1773 1774 /***************************************************************************** 1775 *! \brief tiCOMShutDown 1776 * 1777 * Purpose: This function is called to shutdown the initiator and/or target 1778 * operation. Following the completion of this call, the state is 1779 * equivalent to the state prior to tiCOMInit() 1780 * 1781 * \param tiRoot: Pointer to root data structure. 1782 * 1783 * \return None 1784 * 1785 * 1786 *****************************************************************************/ 1787 osGLOBAL void 1788 tiCOMShutDown( tiRoot_t *tiRoot) 1789 { 1790 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1791 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1792 1793 // #define TI_GETFOR_ONSHUTDOWN 1794 #ifdef TI_GETFOR_ONSHUTDOWN 1795 agsaForensicData_t forensicData; 1796 bit32 once = 1; 1797 bit32 status; 1798 #endif /* TI_GETFOR_ONSHUTDOWN */ 1799 1800 agsaRoot_t *agRoot = agNULL; 1801 1802 TI_DBG1(("tiCOMShutDown: start\n")); 1803 1804 1805 agRoot = &(tdsaAllShared->agRootNonInt); 1806 /* 1807 1. free up cardID 1808 2. call saHwShutdown() 1809 3. tdInitEsgl(tiRoot); 1810 4. tdsaResetComMemFlags(tiRoot) 1811 5. ostiPortEvent() 1812 */ 1813 1814 tdsaFreeCardID(tiRoot, tdsaAllShared->CardID); 1815 1816 #ifdef TI_GETFOR_ONSHUTDOWN 1817 forensicData.DataType = TYPE_NON_FATAL; 1818 forensicData.dataBuf.directLen = (8 * 1024); 1819 forensicData.dataBuf.directOffset = 0; /* current offset */ 1820 forensicData.dataBuf.directData = agNULL; 1821 forensicData.dataBuf.readLen = 0; /* Data read */ 1822 1823 getmoreData: 1824 status = saGetForensicData( agRoot, agNULL, &forensicData); 1825 1826 TI_DBG1(("tiCOMShutDown:readLen 0x%x directLen 0x%x directOffset 0x%x\n", 1827 forensicData.dataBuf.readLen, 1828 forensicData.dataBuf.directLen, 1829 forensicData.dataBuf.directOffset)); 1830 if( forensicData.dataBuf.readLen == forensicData.dataBuf.directLen && !status && once) 1831 { 1832 goto getmoreData; 1833 } 1834 1835 TI_DBG1(("tiCOMShutDown:saGetForensicData type %d read 0x%x bytes\n", forensicData.DataType, forensicData.dataBuf.directOffset )); 1836 #endif /* TI_GETFOR_ONSHUTDOWN */ 1837 1838 saHwShutdown(agRoot); 1839 1840 /* resets all the relevant flags */ 1841 tdsaResetComMemFlags(tiRoot); 1842 1843 /* 1844 * send an event to the oslayer 1845 */ 1846 ostiPortEvent ( 1847 tiRoot, 1848 tiPortShutdown, 1849 tiSuccess, 1850 agNULL 1851 ); 1852 1853 return; 1854 } 1855 1856 #ifdef INITIATOR_DRIVER 1857 osGLOBAL void 1858 tiINITimerTick( tiRoot_t *tiRoot ) 1859 { 1860 /* 1861 no timer is used in SAS TD layer. 1862 Therefore, this function is null. 1863 */ 1864 // TI_DBG2(("tiINITimerTick: start\n")); 1865 /*itdsaProcessTimers(tiRoot);*/ 1866 return; 1867 } 1868 #endif 1869 1870 /*****************************************************************************/ 1871 /*! \brief ossaDisableInterrupts 1872 * 1873 * 1874 * Purpose: This routine is called to disable interrupt 1875 * 1876 * 1877 * \param agRoot: Pointer to chip/driver Instance. 1878 * \param outboundChannelNum: Zero-base channel number 1879 * 1880 * 1881 * \return None. 1882 * 1883 * \note - The scope is shared target and initiator. 1884 * 1885 */ 1886 /*****************************************************************************/ 1887 #ifndef ossaDisableInterrupts 1888 osGLOBAL void 1889 ossaDisableInterrupts( 1890 agsaRoot_t *agRoot, 1891 bit32 outboundChannelNum 1892 ) 1893 { 1894 tdsaRootOsData_t *osData = (tdsaRootOsData_t *) (agRoot->osData); 1895 1896 ostiInterruptDisable( 1897 osData->tiRoot, 1898 outboundChannelNum 1899 ); 1900 return; 1901 } 1902 1903 #endif 1904 1905 1906 osGLOBAL void 1907 tiCOMFrameReadBlock( 1908 tiRoot_t *tiRoot, 1909 void *agFrame, 1910 bit32 FrameOffset, 1911 void *FrameBuffer, 1912 bit32 FrameBufLen ) 1913 { 1914 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 1915 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 1916 agsaRoot_t *agRoot = agNULL; 1917 1918 TI_DBG6(("tiCOMFrameReadBlock: start\n")); 1919 1920 1921 agRoot = &(tdsaAllShared->agRootNonInt); 1922 1923 1924 TI_DBG6(("tiCOMFrameReadBlock: start\n")); 1925 1926 saFrameReadBlock(agRoot, agFrame, FrameOffset, FrameBuffer, FrameBufLen); 1927 1928 return; 1929 } 1930 1931 1932 1933 /***************************************************************************** 1934 *! \brief tiINITransportRecovery 1935 * 1936 * Purpose: This routine is called to explicitly ask the Transport Dependent 1937 * Layer to initiate the recovery for the transport/protocol specific 1938 * error for a specific device connection. 1939 * 1940 * \param tiRoot: Pointer to driver instance 1941 * \param tiDeviveHandle: Pointer to the device handle for this session. 1942 * 1943 * \return: None 1944 * 1945 * 1946 *****************************************************************************/ 1947 #ifdef INITIATOR_DRIVER 1948 osGLOBAL void 1949 tiINITransportRecovery ( 1950 tiRoot_t *tiRoot, 1951 tiDeviceHandle_t *tiDeviceHandle 1952 ) 1953 { 1954 agsaRoot_t *agRoot = agNULL; 1955 tdsaDeviceData_t *oneDeviceData = agNULL; 1956 tdsaPortContext_t *onePortContext = agNULL; 1957 tiPortalContext_t *tiPortalContext = agNULL; 1958 tiIORequest_t *currentTaskTag; 1959 agsaDevHandle_t *agDevHandle = agNULL; 1960 1961 TI_DBG1(("tiINITransportRecovery: start\n")); 1962 1963 if (tiDeviceHandle == agNULL) 1964 { 1965 TI_DBG1(("tiINITransportRecovery: tiDeviceHandle is NULL\n")); 1966 1967 return; 1968 } 1969 1970 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 1971 1972 if (oneDeviceData == agNULL) 1973 { 1974 TI_DBG1(("tiINITransportRecovery: oneDeviceData is NULL\n")); 1975 return; 1976 } 1977 1978 /* for hotplug */ 1979 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE || 1980 oneDeviceData->tdPortContext == agNULL ) 1981 { 1982 TI_DBG1(("tiINITransportRecovery: NO Device did %d\n", oneDeviceData->id )); 1983 TI_DBG1(("tiINITransportRecovery: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1984 TI_DBG1(("tiINITransportRecovery: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1985 return; 1986 } 1987 1988 onePortContext = oneDeviceData->tdPortContext; 1989 1990 if (onePortContext == agNULL) 1991 { 1992 TI_DBG1(("tiINITransportRecovery: onePortContext is NULL\n")); 1993 return; 1994 } 1995 1996 tiPortalContext = onePortContext->tiPortalContext; 1997 currentTaskTag = &(oneDeviceData->TransportRecoveryIO); 1998 currentTaskTag->osData = agNULL; 1999 agRoot = oneDeviceData->agRoot; 2000 agDevHandle = oneDeviceData->agDevHandle; 2001 2002 if (oneDeviceData->DeviceType == TD_SAS_DEVICE) 2003 { 2004 agsaContext_t *agContext; 2005 currentTaskTag->tdData = oneDeviceData; 2006 agContext = &(oneDeviceData->agDeviceResetContext); 2007 agContext->osData = currentTaskTag; 2008 oneDeviceData->TRflag = agTRUE; 2009 2010 TI_DBG2(("tiINITransportRecovery: SAS device\n")); 2011 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY); 2012 2013 if (oneDeviceData->directlyAttached == agTRUE) 2014 { 2015 TI_DBG2(("tiINITransportRecovery: saLocalPhyControl\n")); 2016 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_HARD_RESET, agNULL); 2017 ostiInitiatorEvent(tiRoot, 2018 tiPortalContext, 2019 tiDeviceHandle, 2020 tiIntrEventTypeTransportRecovery, 2021 tiRecStarted, 2022 agNULL 2023 ); 2024 2025 return; 2026 } 2027 else 2028 { 2029 TI_DBG2(("tiINITransportRecovery: device reset expander attached\n")); 2030 tdsaPhyControlSend(tiRoot, 2031 oneDeviceData, 2032 SMP_PHY_CONTROL_HARD_RESET, 2033 currentTaskTag, 2034 tdsaRotateQnumber(tiRoot, oneDeviceData) 2035 ); 2036 ostiInitiatorEvent(tiRoot, 2037 tiPortalContext, 2038 tiDeviceHandle, 2039 tiIntrEventTypeTransportRecovery, 2040 tiRecStarted, 2041 agNULL 2042 ); 2043 return; 2044 } 2045 } 2046 else if (oneDeviceData->DeviceType == TD_SATA_DEVICE) 2047 { 2048 agsaContext_t *agContext; 2049 currentTaskTag->tdData = oneDeviceData; 2050 agContext = &(oneDeviceData->agDeviceResetContext); 2051 agContext->osData = currentTaskTag; 2052 oneDeviceData->TRflag = agTRUE; 2053 2054 TI_DBG2(("tiINITransportRecovery: SATA device\n")); 2055 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_IN_RECOVERY); 2056 2057 if (oneDeviceData->directlyAttached == agTRUE) 2058 { 2059 TI_DBG2(("tiINITransportRecovery: saLocalPhyControl\n")); 2060 saLocalPhyControl(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), oneDeviceData->phyID, AGSA_PHY_LINK_RESET, agNULL); 2061 ostiInitiatorEvent(tiRoot, 2062 tiPortalContext, 2063 tiDeviceHandle, 2064 tiIntrEventTypeTransportRecovery, 2065 tiRecStarted, 2066 agNULL 2067 ); 2068 2069 return; 2070 } 2071 else 2072 { 2073 TI_DBG2(("tiINITransportRecovery: device reset expander attached\n")); 2074 tdsaPhyControlSend(tiRoot, 2075 oneDeviceData, 2076 SMP_PHY_CONTROL_LINK_RESET, 2077 currentTaskTag, 2078 tdsaRotateQnumber(tiRoot, oneDeviceData) 2079 ); 2080 ostiInitiatorEvent(tiRoot, 2081 tiPortalContext, 2082 tiDeviceHandle, 2083 tiIntrEventTypeTransportRecovery, 2084 tiRecStarted, 2085 agNULL 2086 ); 2087 return; 2088 } 2089 } 2090 else 2091 { 2092 TI_DBG1(("tiINITransportRecovery: wrong device type %d\n", oneDeviceData->DeviceType)); 2093 } 2094 2095 2096 return; 2097 } 2098 #endif 2099 2100 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 2101 /***************************************************************************** 2102 *! \brief tdsaPhyControlSend 2103 * 2104 * Purpose: This function sends Phy Control to a device. 2105 * 2106 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2107 * instance. 2108 * \param oneDeviceData: Pointer to the device data. 2109 * \param phyId: Phy Identifier. 2110 * \param queueNumber: bits 0-15: inbound queue number. 2111 * bits 16-31: outbound queue number. 2112 * 2113 * \return: 2114 * Status 2115 * 2116 * \note: 2117 * 2118 *****************************************************************************/ 2119 /* phyop of interest 2120 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION 2121 if CurrentTaskTag == agNULL, clear affiliation 2122 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset) 2123 2124 */ 2125 osGLOBAL bit32 2126 tdsaPhyControlSend( 2127 tiRoot_t *tiRoot, 2128 tdsaDeviceData_t *oneDeviceData, /* taget disk */ 2129 bit8 phyOp, 2130 tiIORequest_t *CurrentTaskTag, 2131 bit32 queueNumber 2132 ) 2133 { 2134 return 0; 2135 } 2136 #endif 2137 2138 #ifdef TARGET_DRIVER 2139 /***************************************************************************** 2140 *! \brief tdsaPhyControlSend 2141 * 2142 * Purpose: This function sends Phy Control to a device. 2143 * 2144 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2145 * instance. 2146 * \param oneDeviceData: Pointer to the device data. 2147 * \param phyId: Phy Identifier. 2148 * \param queueNumber: bits 0-15: inbound queue number. 2149 * bits 16-31: outbound queue number. 2150 * 2151 * \return: 2152 * Status 2153 * 2154 * \note: 2155 * 2156 *****************************************************************************/ 2157 /* phyop of interest 2158 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION 2159 if CurrentTaskTag == agNULL, clear affiliation 2160 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset) 2161 2162 */ 2163 osGLOBAL bit32 2164 tdsaPhyControlSend( 2165 tiRoot_t *tiRoot, 2166 tdsaDeviceData_t *oneDeviceData, /* taget disk */ 2167 bit8 phyOp, 2168 tiIORequest_t *CurrentTaskTag, 2169 bit32 queueNumber 2170 ) 2171 { 2172 return 0; 2173 } 2174 #endif 2175 2176 2177 #ifdef INITIATOR_DRIVER 2178 /***************************************************************************** 2179 *! \brief tdsaPhyControlSend 2180 * 2181 * Purpose: This function sends Phy Control to a device. 2182 * 2183 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2184 * instance. 2185 * \param oneDeviceData: Pointer to the device data. 2186 * \param phyId: Phy Identifier. 2187 * \param queueNumber: bits 0-15: inbound queue number. 2188 * bits 16-31: outbound queue number. 2189 * 2190 * \return: 2191 * Status 2192 * 2193 * \note: 2194 * 2195 *****************************************************************************/ 2196 /* phyop of interest 2197 SMP_PHY_CONTROL_HARD_RESET or SMP_PHY_CONTROL_CLEAR_AFFILIATION 2198 if CurrentTaskTag == agNULL, clear affiliation 2199 if CurrentTaskTag != agNULL, PHY_CONTROL (device reset) 2200 2201 */ 2202 osGLOBAL bit32 2203 tdsaPhyControlSend( 2204 tiRoot_t *tiRoot, 2205 tdsaDeviceData_t *oneDeviceData, /* taget disk */ 2206 bit8 phyOp, 2207 tiIORequest_t *CurrentTaskTag, 2208 bit32 queueNumber 2209 ) 2210 { 2211 agsaRoot_t *agRoot; 2212 tdsaDeviceData_t *oneExpDeviceData; 2213 tdsaPortContext_t *onePortContext; 2214 smpReqPhyControl_t smpPhyControlReq; 2215 bit8 phyID; 2216 bit32 status; 2217 2218 TI_DBG3(("tdsaPhyControlSend: start\n")); 2219 2220 agRoot = oneDeviceData->agRoot; 2221 onePortContext = oneDeviceData->tdPortContext; 2222 oneExpDeviceData = oneDeviceData->ExpDevice; 2223 phyID = oneDeviceData->phyID; 2224 2225 if (oneDeviceData->directlyAttached == agTRUE) 2226 { 2227 TI_DBG1(("tdsaPhyControlSend: Error!!! deivce is directly attached\n")); 2228 return AGSA_RC_FAILURE; 2229 } 2230 if (onePortContext == agNULL) 2231 { 2232 TI_DBG1(("tdsaPhyControlSend: Error!!! portcontext is NULL\n")); 2233 return AGSA_RC_FAILURE; 2234 } 2235 2236 if (oneExpDeviceData == agNULL) 2237 { 2238 TI_DBG1(("tdsaPhyControlSend: Error!!! expander is NULL\n")); 2239 return AGSA_RC_FAILURE; 2240 } 2241 2242 if (phyOp == SMP_PHY_CONTROL_HARD_RESET) 2243 { 2244 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_HARD_RESET\n")); 2245 } 2246 if (phyOp == SMP_PHY_CONTROL_LINK_RESET) 2247 { 2248 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_LINK_RESET\n")); 2249 } 2250 if (phyOp == SMP_PHY_CONTROL_CLEAR_AFFILIATION) 2251 { 2252 TI_DBG3(("tdsaPhyControlSend: SMP_PHY_CONTROL_CLEAR_AFFILIATION\n")); 2253 } 2254 TI_DBG3(("tdsaPhyControlSend: target device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 2255 TI_DBG3(("tdsaPhyControlSend: target device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 2256 TI_DBG3(("tdsaPhyControlSend: expander AddrHi 0x%08x\n", oneExpDeviceData->SASAddressID.sasAddressHi)); 2257 TI_DBG3(("tdsaPhyControlSend: expander AddrLo 0x%08x\n", oneExpDeviceData->SASAddressID.sasAddressLo)); 2258 TI_DBG3(("tdsaPhyControlSend: did %d expander did %d phyid %d\n", oneDeviceData->id, oneExpDeviceData->id, phyID)); 2259 2260 2261 osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t)); 2262 2263 /* fill in SMP payload */ 2264 smpPhyControlReq.phyIdentifier = phyID; 2265 smpPhyControlReq.phyOperation = phyOp; 2266 2267 status = tdSMPStart( 2268 tiRoot, 2269 agRoot, 2270 oneExpDeviceData, 2271 SMP_PHY_CONTROL, 2272 (bit8 *)&smpPhyControlReq, 2273 sizeof(smpReqPhyControl_t), 2274 AGSA_SMP_INIT_REQ, 2275 CurrentTaskTag, 2276 queueNumber 2277 ); 2278 return status; 2279 } 2280 #endif 2281 2282 /***************************************************************************** 2283 *! \brief tdsaPhyControlFailureRespRcvd 2284 * 2285 * Purpose: This function processes the failure of Phy Control response. 2286 * 2287 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2288 * instance. 2289 * \param agRoot: Pointer to chip/driver Instance. 2290 * \param oneDeviceData: Pointer to the device data. 2291 * \param frameHeader: Pointer to SMP frame header. 2292 * \param frameHandle: A Handle used to refer to the response frame 2293 * 2294 * \return: 2295 * None 2296 * 2297 * \note: 2298 * 2299 *****************************************************************************/ 2300 osGLOBAL void 2301 tdsaPhyControlFailureRespRcvd( 2302 tiRoot_t *tiRoot, 2303 agsaRoot_t *agRoot, 2304 tdsaDeviceData_t *oneDeviceData, 2305 tdssSMPFrameHeader_t *frameHeader, 2306 agsaFrameHandle_t frameHandle, 2307 tiIORequest_t *CurrentTaskTag 2308 ) 2309 { 2310 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE) 2311 tdsaDeviceData_t *TargetDeviceData = agNULL; 2312 #endif 2313 #ifdef TD_DEBUG_ENABLE 2314 satDeviceData_t *pSatDevData = agNULL; 2315 #endif 2316 // agsaDevHandle_t *agDevHandle = agNULL; 2317 2318 TI_DBG1(("tdsaPhyControlFailureRespRcvd: start\n")); 2319 2320 TI_DBG3(("tdsaPhyControlFailureRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 2321 TI_DBG3(("tdsaPhyControlFailureRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 2322 2323 if (CurrentTaskTag != agNULL ) 2324 { 2325 /* This was set in tiINITaskmanagement() */ 2326 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE) 2327 TargetDeviceData = (tdsaDeviceData_t *)CurrentTaskTag->tdData; 2328 #endif 2329 #ifdef TD_DEBUG_ENABLE 2330 pSatDevData = (satDeviceData_t *)&(TargetDeviceData->satDevData); 2331 #endif 2332 // agDevHandle = TargetDeviceData->agDevHandle; 2333 TI_DBG2(("tdsaPhyControlFailureRespRcvd: target AddrHi 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressHi)); 2334 TI_DBG2(("tdsaPhyControlFailureRespRcvd: target AddrLo 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressLo)); 2335 2336 #ifdef TD_DEBUG_ENABLE 2337 TI_DBG2(("tdsaPhyControlFailureRespRcvd: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 2338 TI_DBG2(("tdsaPhyControlFailureRespRcvd: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 2339 #endif 2340 } 2341 2342 #ifdef INITIATOR_DRIVER 2343 if (CurrentTaskTag != agNULL ) 2344 { 2345 TI_DBG1(("tdsaPhyControlRespRcvd: callback to OS layer with failure\n")); 2346 if (TargetDeviceData->TRflag == agTRUE) 2347 { 2348 TargetDeviceData->TRflag = agFALSE; 2349 ostiInitiatorEvent(tiRoot, 2350 TargetDeviceData->tdPortContext->tiPortalContext, 2351 &(TargetDeviceData->tiDeviceHandle), 2352 tiIntrEventTypeTransportRecovery, 2353 tiRecFailed , 2354 agNULL 2355 ); 2356 } 2357 else 2358 { 2359 ostiInitiatorEvent( tiRoot, 2360 NULL, 2361 NULL, 2362 tiIntrEventTypeTaskManagement, 2363 tiTMFailed, 2364 CurrentTaskTag ); 2365 } 2366 } 2367 #endif 2368 return; 2369 } 2370 /***************************************************************************** 2371 *! \brief tdsaPhyControlRespRcvd 2372 * 2373 * Purpose: This function processes Phy Control response. 2374 * 2375 * \param tiRoot: Pointer to the OS Specific module allocated tiRoot_t 2376 * instance. 2377 * \param agRoot: Pointer to chip/driver Instance. 2378 * \param oneDeviceData: Pointer to the device data. 2379 * \param frameHeader: Pointer to SMP frame header. 2380 * \param frameHandle: A Handle used to refer to the response frame 2381 * 2382 * \return: 2383 * None 2384 * 2385 * \note: 2386 * 2387 *****************************************************************************/ 2388 osGLOBAL void 2389 tdsaPhyControlRespRcvd( 2390 tiRoot_t *tiRoot, 2391 agsaRoot_t *agRoot, 2392 agsaIORequest_t *agIORequest, 2393 tdsaDeviceData_t *oneDeviceData, 2394 tdssSMPFrameHeader_t *frameHeader, 2395 agsaFrameHandle_t frameHandle, 2396 tiIORequest_t *CurrentTaskTag 2397 ) 2398 { 2399 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE) 2400 tdsaDeviceData_t *TargetDeviceData = agNULL; 2401 #endif 2402 #ifdef INITIATOR_DRIVER 2403 satDeviceData_t *pSatDevData = agNULL; 2404 agsaDevHandle_t *agDevHandle = agNULL; 2405 #endif 2406 2407 TI_DBG3(("tdsaPhyControlRespRcvd: start\n")); 2408 2409 TI_DBG3(("tdsaPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 2410 TI_DBG3(("tdsaPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 2411 2412 if (CurrentTaskTag != agNULL ) 2413 { 2414 /* This was set in tiINITaskmanagement() */ 2415 #if defined(INITIATOR_DRIVER) || defined(TD_DEBUG_ENABLE) 2416 TargetDeviceData = (tdsaDeviceData_t *)CurrentTaskTag->tdData; 2417 #endif 2418 #ifdef INITIATOR_DRIVER 2419 pSatDevData = (satDeviceData_t *)&(TargetDeviceData->satDevData); 2420 agDevHandle = TargetDeviceData->agDevHandle; 2421 #endif 2422 TI_DBG2(("tdsaPhyControlRespRcvd: target AddrHi 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressHi)); 2423 TI_DBG2(("tdsaPhyControlRespRcvd: target AddrLo 0x%08x\n", TargetDeviceData->SASAddressID.sasAddressLo)); 2424 2425 #ifdef INITIATOR_DRIVER 2426 TI_DBG2(("tdsaPhyControlRespRcvd: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 2427 TI_DBG2(("tdsaPhyControlRespRcvd: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 2428 #endif 2429 } 2430 2431 #ifdef INITIATOR_DRIVER 2432 /* no payload */ 2433 if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2434 { 2435 TI_DBG3(("tdsaPhyControlRespRcvd: SMP success\n")); 2436 2437 /* warm reset or clear affiliation is done 2438 call ostiInitiatorEvent() 2439 */ 2440 if (CurrentTaskTag != agNULL ) 2441 { 2442 TI_DBG3(("tdsaPhyControlRespRcvd: callback to OS layer with success\n")); 2443 pSatDevData->satDriveState = SAT_DEV_STATE_NORMAL; 2444 saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, TargetDeviceData), agDevHandle, SA_DS_OPERATIONAL); 2445 2446 if (TargetDeviceData->TRflag == agTRUE) 2447 { 2448 TargetDeviceData->TRflag = agFALSE; 2449 ostiInitiatorEvent(tiRoot, 2450 TargetDeviceData->tdPortContext->tiPortalContext, 2451 &(TargetDeviceData->tiDeviceHandle), 2452 tiIntrEventTypeTransportRecovery, 2453 tiRecOK, 2454 agNULL 2455 ); 2456 } 2457 else 2458 { 2459 agDevHandle = TargetDeviceData->agDevHandle; 2460 if (agDevHandle == agNULL) 2461 { 2462 TI_DBG1(("tdsaPhyControlRespRcvd: wrong, agDevHandle is NULL\n")); 2463 } 2464 ostiInitiatorEvent( tiRoot, 2465 NULL, 2466 NULL, 2467 tiIntrEventTypeTaskManagement, 2468 tiTMOK, 2469 CurrentTaskTag ); 2470 } 2471 } 2472 2473 } 2474 else 2475 { 2476 TI_DBG1(("tdsaPhyControlRespRcvd: SMP failure; result %d\n", frameHeader->smpFunctionResult)); 2477 /* warm reset or clear affiliation is done 2478 */ 2479 if (CurrentTaskTag != agNULL ) 2480 { 2481 TI_DBG1(("tdsaPhyControlRespRcvd: callback to OS layer with failure\n")); 2482 if (TargetDeviceData->TRflag == agTRUE) 2483 { 2484 TargetDeviceData->TRflag = agFALSE; 2485 ostiInitiatorEvent(tiRoot, 2486 TargetDeviceData->tdPortContext->tiPortalContext, 2487 &(TargetDeviceData->tiDeviceHandle), 2488 tiIntrEventTypeTransportRecovery, 2489 tiRecFailed , 2490 agNULL 2491 ); 2492 } 2493 else 2494 { 2495 ostiInitiatorEvent( tiRoot, 2496 NULL, 2497 NULL, 2498 tiIntrEventTypeTaskManagement, 2499 tiTMFailed, 2500 CurrentTaskTag ); 2501 } 2502 } 2503 2504 } 2505 #endif 2506 return; 2507 } 2508 2509 2510 #ifdef TARGET_DRIVER 2511 /***************************************************************************** 2512 *! \brief ttdsaAbortAll 2513 * 2514 * Purpose: This function is called to abort an all pending I/O request on a 2515 * device 2516 * 2517 * \param tiRoot: Pointer to initiator driver/port instance. 2518 * \param agRoot: Pointer to chip/driver Instance. 2519 * \param oneDeviceData: Pointer to the device 2520 * 2521 * \return: 2522 * 2523 * None 2524 * 2525 *****************************************************************************/ 2526 /* 2527 for abort itself, 2528 should we allocate tdAbortIORequestBody or get one from ttdsaXchg_t? 2529 Currently, we allocate tdAbortIORequestBody. 2530 */ 2531 osGLOBAL void 2532 ttdsaAbortAll( 2533 tiRoot_t *tiRoot, 2534 agsaRoot_t *agRoot, 2535 tdsaDeviceData_t *oneDeviceData 2536 ) 2537 { 2538 agsaIORequest_t *agAbortIORequest = agNULL; 2539 tdIORequestBody_t *tdAbortIORequestBody = agNULL; 2540 bit32 PhysUpper32; 2541 bit32 PhysLower32; 2542 bit32 memAllocStatus; 2543 void *osMemHandle; 2544 2545 TI_DBG3(("tdsaAbortAll: start\n")); 2546 2547 TI_DBG3(("tdsaAbortAll: did %d\n", oneDeviceData->id)); 2548 2549 2550 /* allocating agIORequest for abort itself */ 2551 memAllocStatus = ostiAllocMemory( 2552 tiRoot, 2553 &osMemHandle, 2554 (void **)&tdAbortIORequestBody, 2555 &PhysUpper32, 2556 &PhysLower32, 2557 8, 2558 sizeof(tdIORequestBody_t), 2559 agTRUE 2560 ); 2561 if (memAllocStatus != tiSuccess) 2562 { 2563 /* let os process IO */ 2564 TI_DBG1(("tdsaAbortAll: ostiAllocMemory failed...\n")); 2565 return; 2566 } 2567 2568 if (tdAbortIORequestBody == agNULL) 2569 { 2570 /* let os process IO */ 2571 TI_DBG1(("tdsaAbortAll: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 2572 return; 2573 } 2574 2575 /* setup task management structure */ 2576 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 2577 /* setting callback */ 2578 /* not needed; it is already set to be ossaSSPAbortCB() */ 2579 tdAbortIORequestBody->IOCompletionFunc = ttdssIOAbortedHandler; 2580 2581 tdAbortIORequestBody->tiDevHandle = (tiDeviceHandle_t *)&(oneDeviceData->tiDeviceHandle); 2582 2583 /* initialize agIORequest */ 2584 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 2585 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 2586 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 2587 2588 /* SSPAbort */ 2589 saSSPAbort(agRoot, 2590 agAbortIORequest, 2591 0, 2592 oneDeviceData->agDevHandle, 2593 1, /* abort all */ 2594 agNULL, 2595 agNULL 2596 ); 2597 return; 2598 } 2599 #endif /* TARGET_DRIVER */ 2600 2601 2602 osGLOBAL void 2603 tdsaDeregisterDevicesInPort( 2604 tiRoot_t *tiRoot, 2605 tdsaPortContext_t *onePortContext 2606 ) 2607 { 2608 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 2609 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 2610 tdsaDeviceData_t *oneDeviceData = agNULL; 2611 tdList_t *DeviceListList; 2612 agsaRoot_t *agRoot = agNULL; 2613 2614 agRoot = &(tdsaAllShared->agRootNonInt); 2615 2616 TI_DBG1(("tdsaDeregisterDevicesInPort: start\n")); 2617 2618 /* find a device's existence */ 2619 DeviceListList = tdsaAllShared->MainDeviceList.flink; 2620 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 2621 { 2622 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 2623 if (oneDeviceData == agNULL) 2624 { 2625 TI_DBG1(("tdsaDeregisterDevicesInPort: oneDeviceData is NULL!!!\n")); 2626 return; 2627 } 2628 if (oneDeviceData->tdPortContext == onePortContext) 2629 { 2630 TI_DBG3(("tdsaDeregisterDevicesInPort: Found pid %d did %d\n", onePortContext->id, oneDeviceData->id)); 2631 if ( !( DEVICE_IS_SMP_TARGET(oneDeviceData) && oneDeviceData->directlyAttached == agTRUE)) 2632 { 2633 saDeregisterDeviceHandle(agRoot, agNULL, oneDeviceData->agDevHandle, tdsaRotateQnumber(tiRoot, oneDeviceData)); 2634 } 2635 else 2636 { 2637 TI_DBG1(("tdsaDeregisterDevicesInPort: keeping\n")); 2638 oneDeviceData->registered = agTRUE; 2639 } 2640 } 2641 DeviceListList = DeviceListList->flink; 2642 } 2643 2644 TI_DBG3(("tdsaDeregisterDevicesInPort: end\n")); 2645 2646 return; 2647 } 2648 2649 /******************** for debugging only ***************************/ 2650 osGLOBAL void 2651 tdsaPrintSwConfig( 2652 agsaSwConfig_t *SwConfig 2653 ) 2654 { 2655 if (SwConfig == agNULL) 2656 { 2657 TI_DBG6(("tdsaPrintSwConfig: SwConfig is NULL\n")); 2658 return; 2659 } 2660 else 2661 { 2662 TI_DBG6(("SwConfig->maxActiveIOs %d\n", SwConfig->maxActiveIOs)); 2663 TI_DBG6(("SwConfig->smpReqTimeout %d\n", SwConfig->smpReqTimeout)); 2664 } 2665 2666 return; 2667 2668 } 2669 2670 osGLOBAL void 2671 tdsaPrintHwConfig( 2672 agsaHwConfig_t *HwConfig 2673 ) 2674 { 2675 if (HwConfig == agNULL) 2676 { 2677 TI_DBG6(("tdsaPrintHwConfig: HwConfig is NULL\n")); 2678 return; 2679 } 2680 else 2681 { 2682 TI_DBG6(("HwConfig->phyCount %d\n", HwConfig->phyCount)); 2683 } 2684 return; 2685 } 2686 2687 osGLOBAL void 2688 tdssPrintSASIdentify( 2689 agsaSASIdentify_t *id 2690 ) 2691 { 2692 if (id == agNULL) 2693 { 2694 TI_DBG1(("tdsaPrintSASIdentify: ID is NULL\n")); 2695 return; 2696 } 2697 else 2698 { 2699 TI_DBG6(("SASID->sspTargetPort %d\n", SA_IDFRM_IS_SSP_TARGET(id)?1:0)); 2700 TI_DBG6(("SASID->stpTargetPort %d\n", SA_IDFRM_IS_STP_TARGET(id)?1:0)); 2701 TI_DBG6(("SASID->smpTargetPort %d\n", SA_IDFRM_IS_SMP_TARGET(id)?1:0)); 2702 TI_DBG6(("SASID->sspInitiatorPort %d\n", SA_IDFRM_IS_SSP_INITIATOR(id)?1:0)); 2703 TI_DBG6(("SASID->stpInitiatorPort %d\n", SA_IDFRM_IS_STP_INITIATOR(id)?1:0)); 2704 TI_DBG6(("SASID->smpInitiatorPort %d\n", SA_IDFRM_IS_SMP_INITIATOR(id)?1:0)); 2705 TI_DBG6(("SASID->deviceType %d\n", SA_IDFRM_GET_DEVICETTYPE(id))); 2706 TI_DBG6(("SASID->sasAddressHi 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSHI(id))); 2707 TI_DBG6(("SASID->sasAddressLo 0x%x\n", SA_IDFRM_GET_SAS_ADDRESSLO(id))); 2708 TI_DBG6(("SASID->phyIdentifier 0x%x\n", id->phyIdentifier)); 2709 2710 } 2711 2712 return; 2713 } 2714 2715 osGLOBAL void 2716 tdsaInitTimerHandler( 2717 tiRoot_t *tiRoot, 2718 void *timerData 2719 ) 2720 { 2721 2722 TI_DBG6(("tdsaInitTimerHandler: start\n")); 2723 return; 2724 } 2725 2726 /* 2727 type: 1 portcontext 2 devicedata 2728 flag: 1 FreeLink 2 MainLink 2729 */ 2730 2731 osGLOBAL void 2732 print_tdlist_flink(tdList_t *hdr, int type, int flag) 2733 { 2734 tdList_t *hdr_tmp1 = NULL; 2735 #ifdef TD_DEBUG_ENABLE 2736 tdsaPortContext_t *ele1; 2737 #endif 2738 #ifdef REMOVED 2739 tdsaDeviceData_t *ele2; 2740 #endif 2741 hdr_tmp1 = hdr; 2742 2743 if (type == 1 && flag == 1) 2744 { 2745 TI_DBG6(("PortContext and FreeLink\n")); 2746 } 2747 else if (type != 1 && flag == 1) 2748 { 2749 TI_DBG6(("DeviceData and FreeLink\n")); 2750 } 2751 else if (type == 1 && flag != 1) 2752 { 2753 TI_DBG6(("PortContext and MainLink\n")); 2754 } 2755 else 2756 { 2757 TI_DBG6(("DeviceData and MainLink\n")); 2758 } 2759 if (type == 1) 2760 { 2761 do 2762 { 2763 /* data structure type variable = (data structure type, file name, header of the tdList) */ 2764 if (flag == 1) 2765 { 2766 #ifdef TD_DEBUG_ENABLE 2767 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, FreeLink, hdr_tmp1); 2768 #endif 2769 } 2770 else 2771 { 2772 #ifdef TD_DEBUG_ENABLE 2773 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, hdr_tmp1); 2774 #endif 2775 } 2776 TI_DBG6(("flist ele %d\n", ele1->id)); 2777 TI_DBG6(("flist ele %p\n", ele1)); 2778 hdr_tmp1 = hdr_tmp1->flink; 2779 } while (hdr_tmp1 != hdr); 2780 } 2781 else 2782 { 2783 do 2784 { 2785 /* data structure type variable = (data structure type, file name, header of the tdList) */ 2786 #ifdef REMOVED 2787 if (flag == 1) 2788 { 2789 ele2 = TDLIST_OBJECT_BASE(tdsaDeviceData_t, FreeLink, hdr_tmp1); 2790 } 2791 else 2792 { 2793 ele2 = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, hdr_tmp1); 2794 } 2795 TI_DBG6(("flist ele %d\n", ele2->id)); 2796 TI_DBG6(("flist ele %p\n", ele2)); 2797 #endif 2798 hdr_tmp1 = hdr_tmp1->flink; 2799 } while (hdr_tmp1 != hdr); 2800 } 2801 TI_DBG6(("\n")); 2802 } 2803 2804 /* not verified yet. 6/15/2005 */ 2805 osGLOBAL void 2806 print_tdlist_blink(tdList_t *hdr, int flag) 2807 { 2808 tdList_t *hdr_tmp1 = NULL; 2809 #ifdef REMOVED 2810 tdsaPortContext_t *ele1; 2811 #endif 2812 hdr_tmp1 = hdr; 2813 2814 do 2815 { 2816 /* data structure type variable = (data structure type, file name, header of the tdList) */ 2817 #ifdef REMOVED 2818 if (flag == 1) 2819 { 2820 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, FreeLink, hdr_tmp1); 2821 } 2822 else 2823 { 2824 ele1 = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, hdr_tmp1); 2825 } 2826 TI_DBG6(("blist ele %d\n", ele1->id)); 2827 #endif 2828 2829 hdr_tmp1 = hdr_tmp1->blink; 2830 } while (hdr_tmp1 != hdr); 2831 } 2832 2833 2834 /** hexidecimal dump */ 2835 void tdhexdump(const char *ptitle, bit8 *pbuf, int len) 2836 { 2837 int i; 2838 TI_DBG2(("%s - hexdump(len=%d):\n", ptitle, (int)len)); 2839 if (!pbuf) 2840 { 2841 TI_DBG1(("pbuf is NULL\n")); 2842 return; 2843 } 2844 for (i = 0; i < len; ) 2845 { 2846 if (len - i > 4) 2847 { 2848 TI_DBG2((" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", pbuf[i], pbuf[i+1], pbuf[i+2], pbuf[i+3])); 2849 i += 4; 2850 } 2851 else 2852 { 2853 TI_DBG2((" 0x%02x,", pbuf[i])); 2854 i++; 2855 } 2856 } 2857 TI_DBG2(("\n")); 2858 } 2859 2860 void 2861 tdsaSingleThreadedEnter(tiRoot_t *ptiRoot, bit32 queueId) 2862 { 2863 tdsaRoot_t * tiroot = agNULL; 2864 bit32 offset = 0; 2865 TD_ASSERT(ptiRoot,"ptiRoot"); 2866 tiroot = ptiRoot->tdData; 2867 2868 offset = tiroot->tdsaAllShared.MaxNumLLLocks + tiroot->tdsaAllShared.MaxNumOSLocks; 2869 2870 ostiSingleThreadedEnter(ptiRoot, queueId + offset); 2871 } 2872 2873 void 2874 tdsaSingleThreadedLeave(tiRoot_t *ptiRoot, bit32 queueId) 2875 { 2876 tdsaRoot_t * tiroot = agNULL; 2877 bit32 offset = 0; 2878 2879 TD_ASSERT(ptiRoot,"ptiRoot"); 2880 tiroot = ptiRoot->tdData; 2881 2882 offset = tiroot->tdsaAllShared.MaxNumLLLocks + tiroot->tdsaAllShared.MaxNumOSLocks; 2883 2884 ostiSingleThreadedLeave(ptiRoot, queueId + offset); 2885 } 2886 2887 #ifdef PERF_COUNT 2888 void 2889 tdsaEnter(tiRoot_t *ptiRoot, int io) 2890 { 2891 ostiEnter(ptiRoot, 1, io); 2892 } 2893 2894 void 2895 tdsaLeave(tiRoot_t *ptiRoot, int io) 2896 { 2897 ostiLeave(ptiRoot, 1, io); 2898 } 2899 #endif 2900 2901