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