1285242Sachim/******************************************************************************* 2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285242Sachim* 4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285242Sachim*that the following conditions are met: 6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285242Sachim*following disclaimer. 8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice, 9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285242Sachim*with the distribution. 11285242Sachim* 12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285242Sachim 21285242Sachim** 22285242Sachim********************************************************************************/ 23285242Sachim#include <sys/cdefs.h> 24285242Sachim__FBSDID("$FreeBSD: releng/11.0/sys/dev/pms/RefTisa/discovery/dm/dmsmp.c 285242 2015-07-07 13:17:02Z achim $"); 25285242Sachim#include <dev/pms/config.h> 26285242Sachim 27285242Sachim#include <dev/pms/freebsd/driver/common/osenv.h> 28285242Sachim#include <dev/pms/freebsd/driver/common/ostypes.h> 29285242Sachim#include <dev/pms/freebsd/driver/common/osdebug.h> 30285242Sachim 31285242Sachim#include <dev/pms/RefTisa/sallsdk/api/sa.h> 32285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saapi.h> 33285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 34285242Sachim 35285242Sachim#ifdef FDS_DM 36285242Sachim#include <dev/pms/RefTisa/discovery/api/dm.h> 37285242Sachim#include <dev/pms/RefTisa/discovery/api/dmapi.h> 38285242Sachim#include <dev/pms/RefTisa/discovery/api/tddmapi.h> 39285242Sachim 40285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 41285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 42285242Sachim#include <dev/pms/RefTisa/discovery/dm/dmproto.h> 43285242Sachim 44285242SachimosGLOBAL bit32 45285242SachimdmSMPStart( 46285242Sachim dmRoot_t *dmRoot, 47285242Sachim agsaRoot_t *agRoot, 48285242Sachim dmDeviceData_t *oneDeviceData, 49285242Sachim bit32 functionCode, 50285242Sachim bit8 *pSmpBody, 51285242Sachim bit32 smpBodySize, 52285242Sachim bit32 agRequestType 53285242Sachim ) 54285242Sachim{ 55285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 56285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 57285242Sachim dmIntPortContext_t *onePortContext = agNULL; 58285242Sachim dmSMPRequestBody_t *dmSMPRequestBody = agNULL; 59285242Sachim#ifndef DIRECT_SMP 60285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 61285242Sachim#endif 62285242Sachim agsaSASRequestBody_t *agSASRequestBody; 63285242Sachim dmList_t *SMPList; 64285242Sachim agsaDevHandle_t *agDevHandle; 65285242Sachim agsaIORequest_t *agIORequest; 66285242Sachim agsaSMPFrame_t *agSMPFrame; 67285242Sachim bit32 expectedRspLen = 0; 68285242Sachim dmSMPFrameHeader_t dmSMPFrameHeader; 69285242Sachim dmExpander_t *oneExpander = agNULL; 70285242Sachim bit32 status; 71285242Sachim 72285242Sachim DM_DBG5(("dmSMPStart: start\n")); 73285242Sachim DM_DBG5(("dmSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 74285242Sachim DM_DBG5(("dmSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 75285242Sachim 76285242Sachim dm_memset(&dmSMPFrameHeader, 0, sizeof(dmSMPFrameHeader_t)); 77285242Sachim 78285242Sachim onePortContext = oneDeviceData->dmPortContext; 79285242Sachim 80285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 81285242Sachim { 82285242Sachim DM_DBG1(("dmSMPStart: invalid port or aborted discovery!!!\n")); 83285242Sachim return DM_RC_FAILURE; 84285242Sachim } 85285242Sachim 86285242Sachim oneExpander = oneDeviceData->dmExpander; 87285242Sachim if (oneExpander == agNULL) 88285242Sachim { 89285242Sachim DM_DBG1(("dmSMPStart: Wrong!!! oneExpander is NULL!!!\n")); 90285242Sachim return DM_RC_FAILURE; 91285242Sachim } 92285242Sachim 93285242Sachim if (onePortContext != agNULL) 94285242Sachim { 95285242Sachim DM_DBG5(("dmSMPStart: pid %d\n", onePortContext->id)); 96285242Sachim /* increment the number of pending SMP */ 97285242Sachim onePortContext->discovery.pendingSMP++; 98285242Sachim } 99285242Sachim else 100285242Sachim { 101285242Sachim DM_DBG1(("dmSMPStart: Wrong, onePortContext is NULL!!!\n")); 102285242Sachim return DM_RC_FAILURE; 103285242Sachim } 104285242Sachim 105285242Sachim /* get an smp REQUEST from the free list */ 106285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 107285242Sachim if (DMLIST_EMPTY(&(dmAllShared->freeSMPList))) 108285242Sachim { 109285242Sachim DM_DBG1(("dmSMPStart: no free SMP!!!\n")); 110285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 111285242Sachim /* undo increment the number of pending SMP */ 112285242Sachim onePortContext->discovery.pendingSMP--; 113285242Sachim return DM_RC_FAILURE; 114285242Sachim } 115285242Sachim else 116285242Sachim { 117285242Sachim DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList)); 118285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 119285242Sachim dmSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList); 120285242Sachim } 121285242Sachim 122285242Sachim if (dmSMPRequestBody == agNULL) 123285242Sachim { 124285242Sachim DM_DBG1(("dmSMPStart: dmSMPRequestBody is NULL, wrong!!!\n")); 125285242Sachim return DM_RC_FAILURE; 126285242Sachim } 127285242Sachim DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPRequestBody->id)); 128285242Sachim 129285242Sachim dmSMPRequestBody->dmRoot = dmRoot; 130285242Sachim dmSMPRequestBody->dmDevice = oneDeviceData; 131285242Sachim dmSMPRequestBody->dmPortContext = onePortContext; 132285242Sachim 133285242Sachim agDevHandle = oneExpander->agDevHandle; 134285242Sachim 135285242Sachim /* save the callback funtion */ 136285242Sachim dmSMPRequestBody->SMPCompletionFunc = dmSMPCompleted; /* in dmsmp.c */ 137285242Sachim 138285242Sachim dmSMPRequestBody->retries = 0; 139285242Sachim 140285242Sachim agIORequest = &(dmSMPRequestBody->agIORequest); 141285242Sachim agIORequest->osData = (void *) dmSMPRequestBody; 142285242Sachim agIORequest->sdkData = agNULL; /* SALL takes care of this */ 143285242Sachim 144285242Sachim agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 145285242Sachim agSMPFrame = &(agSASRequestBody->smpFrame); 146285242Sachim 147285242Sachim /* sets dmSMPFrameHeader values */ 148285242Sachim if (oneExpander->SAS2 == 0) 149285242Sachim { 150285242Sachim DM_DBG5(("dmSMPStart: SAS 1.1\n")); 151285242Sachim switch (functionCode) 152285242Sachim { 153285242Sachim case SMP_REPORT_GENERAL: 154285242Sachim expectedRspLen = sizeof(smpRespReportGeneral_t) + 4; 155285242Sachim break; 156285242Sachim case SMP_REPORT_MANUFACTURE_INFORMATION: 157285242Sachim expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4; 158285242Sachim break; 159285242Sachim case SMP_DISCOVER: 160285242Sachim expectedRspLen = sizeof(smpRespDiscover_t) + 4; 161285242Sachim break; 162285242Sachim case SMP_REPORT_PHY_ERROR_LOG: 163285242Sachim expectedRspLen = 32 - 4; 164285242Sachim break; 165285242Sachim case SMP_REPORT_PHY_SATA: 166285242Sachim expectedRspLen = sizeof(smpRespReportPhySata_t) + 4; 167285242Sachim break; 168285242Sachim case SMP_REPORT_ROUTING_INFORMATION: 169285242Sachim expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4; 170285242Sachim break; 171285242Sachim case SMP_CONFIGURE_ROUTING_INFORMATION: 172285242Sachim expectedRspLen = 4; 173285242Sachim break; 174285242Sachim case SMP_PHY_CONTROL: 175285242Sachim expectedRspLen = 4; 176285242Sachim break; 177285242Sachim case SMP_PHY_TEST_FUNCTION: 178285242Sachim expectedRspLen = 4; 179285242Sachim break; 180285242Sachim case SMP_PMC_SPECIFIC: 181285242Sachim expectedRspLen = 4; 182285242Sachim break; 183285242Sachim default: 184285242Sachim expectedRspLen = 0; 185285242Sachim DM_DBG1(("dmSMPStart: SAS 1.1 error, undefined or unused smp function code 0x%x !!!\n", functionCode)); 186285242Sachim return DM_RC_FAILURE; 187285242Sachim } 188285242Sachim /* SMP 1.1 header */ 189285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 190285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 191285242Sachim dmSMPFrameHeader.smpFunctionResult = 0; 192285242Sachim dmSMPFrameHeader.smpReserved = 0; 193285242Sachim } 194285242Sachim else /* SAS 2 */ 195285242Sachim { 196285242Sachim DM_DBG2(("dmSMPStart: SAS 2\n")); 197285242Sachim switch (functionCode) 198285242Sachim { 199285242Sachim case SMP_REPORT_GENERAL: 200285242Sachim expectedRspLen = sizeof(smpRespReportGeneral2_t) + 4; 201285242Sachim /* SMP 2.0 header */ 202285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 203285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 204285242Sachim dmSMPFrameHeader.smpFunctionResult = 0x11; 205285242Sachim dmSMPFrameHeader.smpReserved = 0; 206285242Sachim break; 207285242Sachim case SMP_REPORT_MANUFACTURE_INFORMATION: 208285242Sachim expectedRspLen = sizeof(smpRespReportManufactureInfo2_t) + 4; 209285242Sachim break; 210285242Sachim case SMP_DISCOVER: 211285242Sachim expectedRspLen = sizeof(smpRespDiscover2_t) + 4; 212285242Sachim /* SMP 2.0 header */ 213285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 214285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 215285242Sachim// dmSMPFrameHeader.smpFunctionResult = 0x6c; 216285242Sachim dmSMPFrameHeader.smpFunctionResult = 0x1b; 217285242Sachim dmSMPFrameHeader.smpReserved = 0x02; 218285242Sachim break; 219285242Sachim case SMP_REPORT_PHY_ERROR_LOG: 220285242Sachim expectedRspLen = 32 - 4; 221285242Sachim break; 222285242Sachim case SMP_REPORT_PHY_SATA: 223285242Sachim /* SMP 2.0 header */ 224285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 225285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 226285242Sachim dmSMPFrameHeader.smpFunctionResult = 0x10; 227285242Sachim dmSMPFrameHeader.smpReserved = 0x02; 228285242Sachim expectedRspLen = sizeof(smpRespReportPhySata2_t) + 4; 229285242Sachim break; 230285242Sachim case SMP_REPORT_ROUTING_INFORMATION: 231285242Sachim expectedRspLen = sizeof(smpRespReportRouteTable2_t) + 4; 232285242Sachim break; 233285242Sachim case SMP_CONFIGURE_ROUTING_INFORMATION: 234285242Sachim expectedRspLen = 4; 235285242Sachim /* SMP 2.0 header */ 236285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 237285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 238285242Sachim dmSMPFrameHeader.smpFunctionResult = 0; 239285242Sachim dmSMPFrameHeader.smpReserved = 0x09; 240285242Sachim break; 241285242Sachim case SMP_PHY_CONTROL: 242285242Sachim expectedRspLen = 4; 243285242Sachim /* SMP 2.0 header */ 244285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 245285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 246285242Sachim dmSMPFrameHeader.smpFunctionResult = 0; 247285242Sachim dmSMPFrameHeader.smpReserved = 0x09; 248285242Sachim break; 249285242Sachim case SMP_PHY_TEST_FUNCTION: 250285242Sachim expectedRspLen = 4; 251285242Sachim break; 252285242Sachim case SMP_DISCOVER_LIST: 253285242Sachim expectedRspLen = SMP_MAXIMUM_PAYLOAD; /* 1024 without CRC */ 254285242Sachim /* SMP 2.0 header */ 255285242Sachim dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 256285242Sachim dmSMPFrameHeader.smpFunction = (bit8)functionCode; 257285242Sachim dmSMPFrameHeader.smpFunctionResult = 0xFF; 258285242Sachim dmSMPFrameHeader.smpReserved = 0x06; 259285242Sachim break; 260285242Sachim case SMP_PMC_SPECIFIC: 261285242Sachim expectedRspLen = 4; 262285242Sachim break; 263285242Sachim default: 264285242Sachim expectedRspLen = 0; 265285242Sachim DM_DBG1(("dmSMPStart: SAS 2 error!!! undefined or unused smp function code 0x%x!!!\n", functionCode)); 266285242Sachim return DM_RC_FAILURE; 267285242Sachim } 268285242Sachim } 269285242Sachim 270285242Sachim if (DMIsSPC(agRoot)) 271285242Sachim { 272285242Sachim#ifdef DIRECT_SMP /* direct SMP with 48 or less payload */ 273285242Sachim if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */ 274285242Sachim { 275285242Sachim DM_DBG5(("dmSMPStart: DIRECT smp payload\n")); 276285242Sachim dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 277285242Sachim dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4); 278285242Sachim dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 279285242Sachim 280285242Sachim /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 281285242Sachim agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload; 282285242Sachim agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 283285242Sachim /* to specify DIRECT SMP response */ 284285242Sachim agSMPFrame->inFrameLen = 0; 285285242Sachim 286285242Sachim /* temporary solution for T2D Combo*/ 287285242Sachim#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 288285242Sachim /* force smp repsonse to be direct */ 289285242Sachim agSMPFrame->expectedRespLen = 0; 290285242Sachim#else 291285242Sachim agSMPFrame->expectedRespLen = expectedRspLen; 292285242Sachim#endif 293285242Sachim } 294285242Sachim else 295285242Sachim { 296285242Sachim DM_DBG5(("dmSMPStart: INDIRECT smp payload, TBD\n")); 297285242Sachim } 298285242Sachim 299285242Sachim#else 300285242Sachim 301285242Sachim /* 302285242Sachim dmSMPRequestBody is SMP request 303285242Sachim dmSMPResponsebody is SMP response 304285242Sachim */ 305285242Sachim 306285242Sachim /* get an smp RESPONSE from the free list */ 307285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 308285242Sachim if (DMLIST_EMPTY(&(dmAllShared->freeSMPList))) 309285242Sachim { 310285242Sachim DM_DBG1(("dmSMPStart: no free SMP!!!\n")); 311285242Sachim /* puy back dmSMPRequestBody to the freelist ???*/ 312285242Sachim// DMLIST_DEQUEUE_THIS(&(dmSMPRequestBody->Link)); 313285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 314285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 315285242Sachim 316285242Sachim /* undo increment the number of pending SMP */ 317285242Sachim onePortContext->discovery.pendingSMP--; 318285242Sachim return DM_RC_FAILURE; 319285242Sachim } 320285242Sachim else 321285242Sachim { 322285242Sachim DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList)); 323285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 324285242Sachim dmSMPResponseBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList); 325285242Sachim DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPResponseBody->id)); 326285242Sachim } 327285242Sachim 328285242Sachim if (dmSMPResponseBody == agNULL) 329285242Sachim { 330285242Sachim DM_DBG1(("dmSMPStart: dmSMPResponseBody is NULL, wrong!!!\n")); 331285242Sachim return DM_RC_FAILURE; 332285242Sachim } 333285242Sachim 334285242Sachim /* fill in indirect SMP request fields */ 335285242Sachim DM_DBG5(("dmSMPStart: INDIRECT smp payload\n")); 336285242Sachim 337285242Sachim /* save the pointer to SMP response in SMP request */ 338285242Sachim dmSMPRequestBody->IndirectSMPResponse = dmSMPResponseBody; 339285242Sachim /* SMP request and response initialization */ 340285242Sachim dm_memset(dmSMPRequestBody->IndirectSMP, 0, smpBodySize + 4); 341285242Sachim dm_memset(dmSMPResponseBody->IndirectSMP, 0, expectedRspLen); 342285242Sachim 343285242Sachim dm_memcpy(dmSMPRequestBody->IndirectSMP, &dmSMPFrameHeader, 4); 344285242Sachim dm_memcpy(dmSMPRequestBody->IndirectSMP+4, pSmpBody, smpBodySize); 345285242Sachim 346285242Sachim /* Indirect SMP request */ 347285242Sachim agSMPFrame->outFrameBuf = agNULL; 348285242Sachim agSMPFrame->outFrameAddrUpper32 = dmSMPRequestBody->IndirectSMPUpper32; 349285242Sachim agSMPFrame->outFrameAddrLower32 = dmSMPRequestBody->IndirectSMPLower32; 350285242Sachim agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 351285242Sachim 352285242Sachim /* Indirect SMP response */ 353285242Sachim agSMPFrame->expectedRespLen = expectedRspLen; 354285242Sachim agSMPFrame->inFrameAddrUpper32 = dmSMPResponseBody->IndirectSMPUpper32; 355285242Sachim agSMPFrame->inFrameAddrLower32 = dmSMPResponseBody->IndirectSMPLower32; 356285242Sachim agSMPFrame->inFrameLen = expectedRspLen; /* without last 4 byte crc */ 357285242Sachim 358285242Sachim#endif 359285242Sachim } 360285242Sachim else /* SPCv controller */ 361285242Sachim { 362285242Sachim /* only direct mode for both request and response */ 363285242Sachim DM_DBG5(("dmSMPStart: DIRECT smp payload\n")); 364285242Sachim agSMPFrame->flag = 0; 365285242Sachim dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 366285242Sachim dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4); 367285242Sachim dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 368285242Sachim 369285242Sachim /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 370285242Sachim agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload; 371285242Sachim agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 372285242Sachim /* to specify DIRECT SMP response */ 373285242Sachim agSMPFrame->inFrameLen = 0; 374285242Sachim 375285242Sachim /* temporary solution for T2D Combo*/ 376285242Sachim#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 377285242Sachim /* force smp repsonse to be direct */ 378285242Sachim agSMPFrame->expectedRespLen = 0; 379285242Sachim#else 380285242Sachim agSMPFrame->expectedRespLen = expectedRspLen; 381285242Sachim#endif 382285242Sachim // tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 383285242Sachim // tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 384285242Sachim // tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t)); 385285242Sachim } 386285242Sachim 387285242Sachim if (agDevHandle == agNULL) 388285242Sachim { 389285242Sachim DM_DBG1(("dmSMPStart: !!! agDevHandle is NULL !!! \n")); 390285242Sachim } 391285242Sachim else 392285242Sachim { 393285242Sachim status = saSMPStart( 394285242Sachim agRoot, 395285242Sachim agIORequest, 396285242Sachim 0, 397285242Sachim agDevHandle, 398285242Sachim agRequestType, 399285242Sachim agSASRequestBody, 400285242Sachim &dmsaSMPCompleted 401285242Sachim ); 402285242Sachim 403285242Sachim if (status == AGSA_RC_SUCCESS) 404285242Sachim { 405285242Sachim /* start SMP timer */ 406285242Sachim if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 407285242Sachim functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION 408285242Sachim ) 409285242Sachim { 410285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, functionCode, dmSMPRequestBody); 411285242Sachim } 412285242Sachim return DM_RC_SUCCESS; 413285242Sachim } 414285242Sachim else if (status == AGSA_RC_BUSY) 415285242Sachim { 416285242Sachim /* set timer */ 417285242Sachim if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 418285242Sachim functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION) 419285242Sachim { 420285242Sachim /* only for discovery related SMPs*/ 421285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 422285242Sachim return DM_RC_SUCCESS; 423285242Sachim } 424285242Sachim else 425285242Sachim { 426285242Sachim DM_DBG1(("dmSMPStart: return DM_RC_BUSY!!! \n")); 427285242Sachim#ifdef DIRECT_SMP 428285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 429285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 430285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 431285242Sachim#else 432285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 433285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 434285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 435285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 436285242Sachim#endif 437285242Sachim return DM_RC_BUSY; 438285242Sachim } 439285242Sachim } 440285242Sachim else /* AGSA_RC_FAILURE */ 441285242Sachim { 442285242Sachim DM_DBG1(("dmSMPStart: return DM_RC_FAILURE!!! \n")); 443285242Sachim /* discovery failure or task management failure */ 444285242Sachim if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER || 445285242Sachim functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION) 446285242Sachim { 447285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 448285242Sachim } 449285242Sachim#ifdef DIRECT_SMP 450285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 451285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 452285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 453285242Sachim#else 454285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 455285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 456285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 457285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 458285242Sachim#endif 459285242Sachim 460285242Sachim return DM_RC_FAILURE; 461285242Sachim } 462285242Sachim } 463285242Sachim return DM_RC_SUCCESS; 464285242Sachim} 465285242Sachim 466285242SachimosGLOBAL void 467285242SachimdmsaSMPCompleted( 468285242Sachim agsaRoot_t *agRoot, 469285242Sachim agsaIORequest_t *agIORequest, 470285242Sachim bit32 agIOStatus, 471285242Sachim bit32 agIOInfoLen, 472285242Sachim agsaFrameHandle_t agFrameHandle 473285242Sachim ) 474285242Sachim{ 475285242Sachim dmSMPRequestBody_t *pSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData; 476285242Sachim 477285242Sachim /* SPC can't be SMP target */ 478285242Sachim 479285242Sachim DM_DBG5(("dmsaSMPCompleted: start\n")); 480285242Sachim 481285242Sachim if (pSMPRequestBody == agNULL) 482285242Sachim { 483285242Sachim DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody is NULL!!! \n")); 484285242Sachim return; 485285242Sachim } 486285242Sachim 487285242Sachim if (pSMPRequestBody->SMPCompletionFunc == agNULL) 488285242Sachim { 489285242Sachim DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody->SMPCompletionFunc is NULL!!!\n")); 490285242Sachim return; 491285242Sachim } 492285242Sachim 493285242Sachim#ifdef DM_INTERNAL_DEBUG /* debugging */ 494285242Sachim DM_DBG3(("dmsaSMPCompleted: agIOrequest %p\n", agIORequest->osData)); 495285242Sachim DM_DBG3(("dmsaSMPCompleted: sizeof(tdIORequestBody_t) %d 0x%x\n", sizeof(tdIORequestBody_t), 496285242Sachim sizeof(tdIORequestBody_t))); 497285242Sachim DM_DBG3(("dmsaSMPCompleted: SMPRequestbody %p\n", pSMPRequestBody)); 498285242Sachim DM_DBG3(("dmsaSMPCompleted: calling callback fn\n")); 499285242Sachim DM_DBG3(("dmsaSMPCompleted: callback fn %p\n",pSMPRequestBody->SMPCompletionFunc)); 500285242Sachim#endif /* TD_INTERNAL_DEBUG */ 501285242Sachim /* 502285242Sachim if initiator, calling dmSMPCompleted() in dmsmp.c 503285242Sachim */ 504285242Sachim pSMPRequestBody->SMPCompletionFunc( 505285242Sachim agRoot, 506285242Sachim agIORequest, 507285242Sachim agIOStatus, 508285242Sachim agIOInfoLen, 509285242Sachim agFrameHandle 510285242Sachim ); 511285242Sachim 512285242Sachim return; 513285242Sachim 514285242Sachim} 515285242Sachim 516285242SachimosGLOBAL bit32 517285242SachimdmPhyControlSend( 518285242Sachim dmRoot_t *dmRoot, 519285242Sachim// dmDeviceData_t *oneDeviceData, /* taget disk */ 520285242Sachim dmDeviceData_t *oneExpDeviceData, /* taget disk */ 521285242Sachim bit8 phyOp, 522285242Sachimbit8 phyID // added 523285242Sachim ) 524285242Sachim{ 525285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 526285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 527285242Sachim agsaRoot_t *agRoot = dmAllShared->agRoot; 528285242Sachim// thenil 529285242Sachim// dmDeviceData_t *oneExpDeviceData; 530285242Sachim smpReqPhyControl_t smpPhyControlReq; 531285242Sachim// bit8 phyID; 532285242Sachim bit32 status; 533285242Sachim 534285242Sachim DM_DBG3(("dmPhyControlSend: start\n")); 535285242Sachim 536285242Sachim 537285242Sachim 538285242Sachim osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t)); 539285242Sachim 540285242Sachim /* fill in SMP payload */ 541285242Sachim smpPhyControlReq.phyIdentifier = phyID; 542285242Sachim smpPhyControlReq.phyOperation = phyOp; 543285242Sachim 544285242Sachim status = dmSMPStart( 545285242Sachim dmRoot, 546285242Sachim agRoot, 547285242Sachim oneExpDeviceData, 548285242Sachim SMP_PHY_CONTROL, 549285242Sachim (bit8 *)&smpPhyControlReq, 550285242Sachim sizeof(smpReqPhyControl_t), 551285242Sachim AGSA_SMP_INIT_REQ 552285242Sachim ); 553285242Sachim return status; 554285242Sachim} 555285242Sachim 556285242SachimosGLOBAL void 557285242SachimdmReportGeneralSend( 558285242Sachim dmRoot_t *dmRoot, 559285242Sachim dmDeviceData_t *oneDeviceData 560285242Sachim ) 561285242Sachim{ 562285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 563285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 564285242Sachim agsaRoot_t *agRoot = dmAllShared->agRoot; 565285242Sachim 566285242Sachim DM_DBG3(("dmReportGeneralSend: start\n")); 567285242Sachim DM_DBG3(("dmReportGeneralSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 568285242Sachim DM_DBG3(("dmReportGeneralSend: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id)); 569285242Sachim 570285242Sachim if (agRoot == agNULL) 571285242Sachim { 572285242Sachim DM_DBG1(("dmReportGeneralSend: agRoot is NULL!!!\n")); 573285242Sachim return; 574285242Sachim } 575285242Sachim 576285242Sachim dmSMPStart( 577285242Sachim dmRoot, 578285242Sachim agRoot, 579285242Sachim oneDeviceData, 580285242Sachim SMP_REPORT_GENERAL, 581285242Sachim agNULL, 582285242Sachim 0, 583285242Sachim AGSA_SMP_INIT_REQ 584285242Sachim ); 585285242Sachim return; 586285242Sachim} 587285242SachimosGLOBAL void 588285242SachimdmReportGeneralRespRcvd( 589285242Sachim dmRoot_t *dmRoot, 590285242Sachim agsaRoot_t *agRoot, 591285242Sachim agsaIORequest_t *agIORequest, 592285242Sachim dmDeviceData_t *oneDeviceData, 593285242Sachim dmSMPFrameHeader_t *frameHeader, 594285242Sachim agsaFrameHandle_t frameHandle 595285242Sachim ) 596285242Sachim{ 597285242Sachim smpRespReportGeneral_t dmSMPReportGeneralResp; 598285242Sachim smpRespReportGeneral_t *pdmSMPReportGeneralResp; 599285242Sachim dmIntPortContext_t *onePortContext = agNULL; 600285242Sachim dmDiscovery_t *discovery; 601285242Sachim dmExpander_t *oneExpander = agNULL; 602285242Sachim#ifndef DIRECT_SMP 603285242Sachim dmSMPRequestBody_t *dmSMPRequestBody; 604285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 605285242Sachim#endif 606285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 607285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 608285242Sachim 609285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: start\n")); 610285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 611285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 612285242Sachim 613285242Sachim#ifndef DIRECT_SMP 614285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 615285242Sachim#endif 616285242Sachim pdmSMPReportGeneralResp = &dmSMPReportGeneralResp; 617285242Sachim 618285242Sachim dm_memset(&dmSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t)); 619285242Sachim 620285242Sachim#ifdef DIRECT_SMP 621285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t)); 622285242Sachim#else 623285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 624285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t)); 625285242Sachim#endif 626285242Sachim 627285242Sachim onePortContext = oneDeviceData->dmPortContext; 628285242Sachim discovery = &(onePortContext->discovery); 629285242Sachim 630285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 631285242Sachim { 632285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: invalid port or aborted discovery!!!\n")); 633285242Sachim return; 634285242Sachim } 635285242Sachim 636285242Sachim if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 637285242Sachim { 638285242Sachim oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneralResp->numOfPhys; 639285242Sachim oneExpander = oneDeviceData->dmExpander; 640285242Sachim oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneralResp); 641285242Sachim oneExpander->configReserved = 0; 642285242Sachim oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneralResp) ? 1 : 0; 643285242Sachim oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneralResp) ? 1 : 0; 644285242Sachim DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 is %d\n", oneExpander->SAS2)); 645285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 646285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 647285242Sachim 648285242Sachim if ( oneExpander->SAS2 == 0 && REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp) == 1) 649285242Sachim { 650285242Sachim oneExpander->SAS2 = REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp); 651285242Sachim DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 Long Response=%d\n", REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp))); 652285242Sachim dmReportGeneralSend(dmRoot, oneDeviceData); 653285242Sachim return; 654285242Sachim } 655285242Sachim 656285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n", 657285242Sachim oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex)); 658285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n", 659285242Sachim oneExpander->configRouteTable, oneExpander->configuring)); 660285242Sachim 661285242Sachim if (oneExpander->configuring == 1) 662285242Sachim { 663285242Sachim discovery->retries++; 664285242Sachim if (discovery->retries >= dmAllShared->MaxRetryDiscovery) 665285242Sachim { 666285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: retries are over!!!\n")); 667285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 668285242Sachim discovery->retries = 0; 669285242Sachim /* failed the discovery */ 670285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 671285242Sachim } 672285242Sachim else 673285242Sachim { 674285242Sachim DM_DBG3(("dmReportGeneralRespRcvd: keep retrying\n")); 675285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery)); 676285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 677285242Sachim // start timer for sending ReportGeneral 678285242Sachim dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData); 679285242Sachim } 680285242Sachim } 681285242Sachim else 682285242Sachim { 683285242Sachim discovery->retries = 0; 684285242Sachim dmDiscoverSend(dmRoot, oneDeviceData); 685285242Sachim } 686285242Sachim } 687285242Sachim else 688285242Sachim { 689285242Sachim DM_DBG1(("dmReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery !!!\n", frameHeader->smpFunctionResult)); 690285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 691285242Sachim } 692285242Sachim return; 693285242Sachim} 694285242Sachim 695285242SachimosGLOBAL void 696285242SachimdmReportGeneral2RespRcvd( 697285242Sachim dmRoot_t *dmRoot, 698285242Sachim agsaRoot_t *agRoot, 699285242Sachim agsaIORequest_t *agIORequest, 700285242Sachim dmDeviceData_t *oneDeviceData, 701285242Sachim dmSMPFrameHeader_t *frameHeader, 702285242Sachim agsaFrameHandle_t frameHandle 703285242Sachim ) 704285242Sachim{ 705285242Sachim smpRespReportGeneral2_t dmSMPReportGeneral2Resp; 706285242Sachim smpRespReportGeneral2_t *pdmSMPReportGeneral2Resp; 707285242Sachim dmExpander_t *oneExpander = agNULL; 708285242Sachim dmIntPortContext_t *onePortContext = agNULL; 709285242Sachim dmDiscovery_t *discovery; 710285242Sachim#ifndef DIRECT_SMP 711285242Sachim dmSMPRequestBody_t *dmSMPRequestBody; 712285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 713285242Sachim#endif 714285242Sachim bit32 ConfiguresOthers = agFALSE; 715285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 716285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 717285242Sachim 718285242Sachim 719285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: start\n")); 720285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 721285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 722285242Sachim 723285242Sachim#ifndef DIRECT_SMP 724285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 725285242Sachim#endif 726285242Sachim pdmSMPReportGeneral2Resp = &dmSMPReportGeneral2Resp; 727285242Sachim 728285242Sachim dm_memset(&dmSMPReportGeneral2Resp, 0, sizeof(smpRespReportGeneral2_t)); 729285242Sachim 730285242Sachim#ifdef DIRECT_SMP 731285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t)); 732285242Sachim#else 733285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 734285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t)); 735285242Sachim#endif 736285242Sachim 737285242Sachim onePortContext = oneDeviceData->dmPortContext; 738285242Sachim discovery = &(onePortContext->discovery); 739285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 740285242Sachim { 741285242Sachim DM_DBG1(("dmReportGeneral2RespRcvd: invalid port or aborted discovery!!!\n")); 742285242Sachim return; 743285242Sachim } 744285242Sachim 745285242Sachim/* ??? start here */ 746285242Sachim if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 747285242Sachim { 748285242Sachim oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneral2Resp->numOfPhys; 749285242Sachim oneExpander = oneDeviceData->dmExpander; 750285242Sachim oneExpander->routingIndex = (bit16) SAS2_REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneral2Resp); 751285242Sachim oneExpander->configReserved = 0; 752285242Sachim oneExpander->configRouteTable = SAS2_REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneral2Resp) ? 1 : 0; 753285242Sachim oneExpander->configuring = SAS2_REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneral2Resp) ? 1 : 0; 754285242Sachim oneExpander->TTTSupported = SAS2_REPORT_GENERAL_IS_TABLE_TO_TABLE_SUPPORTED(pdmSMPReportGeneral2Resp) ? 1 : 0; 755285242Sachim ConfiguresOthers = SAS2_REPORT_GENERAL_IS_CONFIGURES_OTHERS(pdmSMPReportGeneral2Resp) ? 1 : 0; 756285242Sachim 757285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: SAS 2 is %d\n", oneExpander->SAS2)); 758285242Sachim DM_DBG3(("dmReportGeneral2RespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 759285242Sachim DM_DBG3(("dmReportGeneral2RespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 760285242Sachim 761285242Sachim 762285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n", 763285242Sachim oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex)); 764285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: configRouteTable=%d configuring=%d\n", 765285242Sachim oneExpander->configRouteTable, oneExpander->configuring)); 766285242Sachim if (ConfiguresOthers) 767285242Sachim { 768285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: ConfiguresOthers is true\n")); 769285242Sachim discovery->ConfiguresOthers = agTRUE; 770285242Sachim } 771285242Sachim if (oneExpander->configuring == 1) 772285242Sachim { 773285242Sachim discovery->retries++; 774285242Sachim if (discovery->retries >= dmAllShared->MaxRetryDiscovery) 775285242Sachim { 776285242Sachim DM_DBG1(("dmReportGeneral2RespRcvd: retries are over!!!\n")); 777285242Sachim DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 778285242Sachim 779285242Sachim discovery->retries = 0; 780285242Sachim /* failed the discovery */ 781285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 782285242Sachim } 783285242Sachim else 784285242Sachim { 785285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: keep retrying\n")); 786285242Sachim DM_DBG1(("dmReportGeneral2RespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery)); 787285242Sachim DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo)); 788285242Sachim // start timer for sending ReportGeneral 789285242Sachim dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData); 790285242Sachim } 791285242Sachim } 792285242Sachim else 793285242Sachim { 794285242Sachim discovery->retries = 0; 795285242Sachim dmDiscoverSend(dmRoot, oneDeviceData); 796285242Sachim } 797285242Sachim } 798285242Sachim else 799285242Sachim { 800285242Sachim DM_DBG2(("dmReportGeneral2RespRcvd: SMP failed, stopping discovery\n")); 801285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 802285242Sachim } 803285242Sachim 804285242Sachim return; 805285242Sachim} 806285242Sachim 807285242Sachim 808285242SachimosGLOBAL void 809285242SachimdmDiscoverSend( 810285242Sachim dmRoot_t *dmRoot, 811285242Sachim dmDeviceData_t *oneDeviceData 812285242Sachim ) 813285242Sachim{ 814285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 815285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 816285242Sachim agsaRoot_t *agRoot = dmAllShared->agRoot; 817285242Sachim smpReqDiscover_t smpDiscoverReq; 818285242Sachim dmExpander_t *oneExpander; 819285242Sachim 820285242Sachim DM_DBG3(("dmDiscoverSend: start\n")); 821285242Sachim DM_DBG3(("dmDiscoverSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 822285242Sachim oneExpander = oneDeviceData->dmExpander; 823285242Sachim DM_DBG3(("dmDiscoverSend: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 824285242Sachim DM_DBG3(("dmDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId)); 825285242Sachim 826285242Sachim dm_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t)); 827285242Sachim 828285242Sachim smpDiscoverReq.reserved1 = 0; 829285242Sachim smpDiscoverReq.reserved2 = 0; 830285242Sachim smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId; 831285242Sachim smpDiscoverReq.reserved3 = 0; 832285242Sachim 833285242Sachim dmSMPStart( 834285242Sachim dmRoot, 835285242Sachim agRoot, 836285242Sachim oneDeviceData, 837285242Sachim SMP_DISCOVER, 838285242Sachim (bit8 *)&smpDiscoverReq, 839285242Sachim sizeof(smpReqDiscover_t), 840285242Sachim AGSA_SMP_INIT_REQ 841285242Sachim ); 842285242Sachim return; 843285242Sachim} 844285242Sachim 845285242SachimosGLOBAL void 846285242SachimdmDiscoverRespRcvd( 847285242Sachim dmRoot_t *dmRoot, 848285242Sachim agsaRoot_t *agRoot, 849285242Sachim agsaIORequest_t *agIORequest, 850285242Sachim dmDeviceData_t *oneDeviceData, 851285242Sachim dmSMPFrameHeader_t *frameHeader, 852285242Sachim agsaFrameHandle_t frameHandle 853285242Sachim ) 854285242Sachim{ 855285242Sachim dmIntPortContext_t *onePortContext = agNULL; 856285242Sachim dmDiscovery_t *discovery; 857285242Sachim smpRespDiscover_t *pdmSMPDiscoverResp; 858285242Sachim#ifndef DIRECT_SMP 859285242Sachim dmSMPRequestBody_t *dmSMPRequestBody; 860285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 861285242Sachim#endif 862285242Sachim dmExpander_t *oneExpander = agNULL; 863285242Sachim 864285242Sachim DM_DBG3(("dmDiscoverRespRcvd: start\n")); 865285242Sachim DM_DBG3(("dmDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 866285242Sachim DM_DBG3(("dmDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 867285242Sachim 868285242Sachim onePortContext = oneDeviceData->dmPortContext; 869285242Sachim oneExpander = oneDeviceData->dmExpander; 870285242Sachim discovery = &(onePortContext->discovery); 871285242Sachim#ifndef DIRECT_SMP 872285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 873285242Sachim#endif 874285242Sachim DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 875285242Sachim DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 876285242Sachim 877285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 878285242Sachim { 879285242Sachim DM_DBG1(("dmDiscoverRespRcvd: invalid port or aborted discovery!!!\n")); 880285242Sachim return; 881285242Sachim } 882285242Sachim 883285242Sachim pdmSMPDiscoverResp = &(discovery->SMPDiscoverResp); 884285242Sachim 885285242Sachim#ifdef DIRECT_SMP 886285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 887285242Sachim#else 888285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 889285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 890285242Sachim#endif 891285242Sachim 892285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 893285242Sachim { 894285242Sachim if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 895285242Sachim { 896285242Sachim dmUpStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp); 897285242Sachim } 898285242Sachim else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 899285242Sachim { 900285242Sachim dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp); 901285242Sachim } 902285242Sachim else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 903285242Sachim { 904285242Sachim /* not done with configuring routing 905285242Sachim 1. set the timer 906285242Sachim 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 907285242Sachim */ 908285242Sachim DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n")); 909285242Sachim DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp)); 910285242Sachim dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 911285242Sachim 912285242Sachim dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL); 913285242Sachim } 914285242Sachim else 915285242Sachim { 916285242Sachim /* nothing */ 917285242Sachim } 918285242Sachim } 919285242Sachim else if (frameHeader->smpFunctionResult == PHY_VACANT) 920285242Sachim { 921285242Sachim DM_DBG3(("dmDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId)); 922285242Sachim if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 923285242Sachim { 924285242Sachim dmUpStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander); 925285242Sachim } 926285242Sachim else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 927285242Sachim { 928285242Sachim dmDownStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander); 929285242Sachim } 930285242Sachim else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 931285242Sachim { 932285242Sachim /* not done with configuring routing 933285242Sachim 1. set the timer 934285242Sachim 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 935285242Sachim */ 936285242Sachim DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n")); 937285242Sachim DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp)); 938285242Sachim dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t)); 939285242Sachim 940285242Sachim dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL); 941285242Sachim } 942285242Sachim } 943285242Sachim else 944285242Sachim { 945285242Sachim DM_DBG1(("dmDiscoverRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n", 946285242Sachim frameHeader->smpFunctionResult)); 947285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 948285242Sachim } 949285242Sachim 950285242Sachim 951285242Sachim 952285242Sachim return; 953285242Sachim} 954285242Sachim 955285242SachimosGLOBAL void 956285242SachimdmDiscover2RespRcvd( 957285242Sachim dmRoot_t *dmRoot, 958285242Sachim agsaRoot_t *agRoot, 959285242Sachim agsaIORequest_t *agIORequest, 960285242Sachim dmDeviceData_t *oneDeviceData, 961285242Sachim dmSMPFrameHeader_t *frameHeader, 962285242Sachim agsaFrameHandle_t frameHandle 963285242Sachim ) 964285242Sachim{ 965285242Sachim dmIntPortContext_t *onePortContext = agNULL; 966285242Sachim dmDiscovery_t *discovery; 967285242Sachim smpRespDiscover2_t *pdmSMPDiscover2Resp; 968285242Sachim#ifndef DIRECT_SMP 969285242Sachim dmSMPRequestBody_t *dmSMPRequestBody; 970285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 971285242Sachim#endif 972285242Sachim dmExpander_t *oneExpander = agNULL; 973285242Sachim 974285242Sachim DM_DBG2(("dmDiscover2RespRcvd: start\n")); 975285242Sachim DM_DBG2(("dmDiscover2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 976285242Sachim DM_DBG2(("dmDiscover2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 977285242Sachim 978285242Sachim onePortContext = oneDeviceData->dmPortContext; 979285242Sachim oneExpander = oneDeviceData->dmExpander; 980285242Sachim discovery = &(onePortContext->discovery); 981285242Sachim#ifndef DIRECT_SMP 982285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 983285242Sachim#endif 984285242Sachim DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 985285242Sachim DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id)); 986285242Sachim 987285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 988285242Sachim { 989285242Sachim DM_DBG1(("dmDiscover2RespRcvd: invalid port or aborted discovery!!!\n")); 990285242Sachim return; 991285242Sachim } 992285242Sachim 993285242Sachim pdmSMPDiscover2Resp = &(discovery->SMPDiscover2Resp); 994285242Sachim 995285242Sachim#ifdef DIRECT_SMP 996285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 997285242Sachim#else 998285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 999285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 1000285242Sachim#endif 1001285242Sachim 1002285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ) 1003285242Sachim { 1004285242Sachim DM_DBG2(("dmDiscover2RespRcvd: phyIdentifier %d\n", pdmSMPDiscover2Resp->phyIdentifier)); 1005285242Sachim DM_DBG2(("dmDiscover2RespRcvd: NegotiatedSSCHWMuxingSupported %d\n", pdmSMPDiscover2Resp->NegotiatedSSCHWMuxingSupported)); 1006285242Sachim DM_DBG2(("dmDiscover2RespRcvd: SAS2_MUXING_SUPPORTED %d\n", SAS2_DISCRSP_IS_MUXING_SUPPORTED(pdmSMPDiscover2Resp))); 1007285242Sachim DM_DBG2(("dmDiscover2RespRcvd: NegotiatedLogicalLinkRate %d\n", pdmSMPDiscover2Resp->NegotiatedLogicalLinkRate)); 1008285242Sachim DM_DBG2(("dmDiscover2RespRcvd: ReasonNegotiatedPhysicalLinkRate %d\n", pdmSMPDiscover2Resp->ReasonNegotiatedPhysicalLinkRate)); 1009285242Sachim DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LOGICAL_LINKRATE %d\n", SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pdmSMPDiscover2Resp))); 1010285242Sachim DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LINKRATE %d\n", SAS2_DISCRSP_GET_LINKRATE(pdmSMPDiscover2Resp))); 1011285242Sachim 1012285242Sachim//NegotiatedLogicalLinkRate 13 1013285242Sachim//ReasonNegotiatedPhysicalLinkRate 94 1014285242Sachim if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 1015285242Sachim { 1016285242Sachim dmUpStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp); 1017285242Sachim } 1018285242Sachim else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1019285242Sachim { 1020285242Sachim dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp); 1021285242Sachim } 1022285242Sachim else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 1023285242Sachim { 1024285242Sachim /* not done with configuring routing 1025285242Sachim 1. set the timer 1026285242Sachim 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 1027285242Sachim */ 1028285242Sachim DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n")); 1029285242Sachim DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp)); 1030285242Sachim dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 1031285242Sachim dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp); 1032285242Sachim } 1033285242Sachim else 1034285242Sachim { 1035285242Sachim /* nothing */ 1036285242Sachim } 1037285242Sachim } 1038285242Sachim else if (frameHeader->smpFunctionResult == PHY_VACANT) 1039285242Sachim { 1040285242Sachim DM_DBG2(("dmDiscover2RespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId)); 1041285242Sachim if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM) 1042285242Sachim { 1043285242Sachim dmUpStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander); 1044285242Sachim } 1045285242Sachim else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM) 1046285242Sachim { 1047285242Sachim dmDownStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander); 1048285242Sachim } 1049285242Sachim else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING) 1050285242Sachim { 1051285242Sachim /* not done with configuring routing 1052285242Sachim 1. set the timer 1053285242Sachim 2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy() 1054285242Sachim */ 1055285242Sachim DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n")); 1056285242Sachim DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp)); 1057285242Sachim dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t)); 1058285242Sachim dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp); 1059285242Sachim } 1060285242Sachim else 1061285242Sachim { 1062285242Sachim /* nothing */ 1063285242Sachim } 1064285242Sachim } 1065285242Sachim else 1066285242Sachim { 1067285242Sachim DM_DBG1(("dmDiscover2RespRcvd: Discovery Error SMP function return result error=0x%x\n", 1068285242Sachim frameHeader->smpFunctionResult)); 1069285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1070285242Sachim } 1071285242Sachim return; 1072285242Sachim} 1073285242Sachim 1074285242Sachim#ifdef NOT_YET 1075285242SachimosGLOBAL void 1076285242SachimtdsaDiscoverList2Send( 1077285242Sachim tiRoot_t *tiRoot, 1078285242Sachim tdsaDeviceData_t *oneDeviceData 1079285242Sachim ) 1080285242Sachim{ 1081285242Sachim agsaRoot_t *agRoot; 1082285242Sachim tdsaExpander_t *oneExpander; 1083285242Sachim smpReqDiscoverList2_t smpDiscoverListReq; 1084285242Sachim 1085285242Sachim DM_DBG1(("tdsaDiscoverList2Send: start\n")); 1086285242Sachim DM_DBG1(("tdsaDiscoverList2Send: device %p did %d\n", oneDeviceData, oneDeviceData->id)); 1087285242Sachim agRoot = oneDeviceData->agRoot; 1088285242Sachim oneExpander = oneDeviceData->dmExpander; 1089285242Sachim DM_DBG1(("tdsaDiscoverList2Send: phyID 0x%x\n", oneExpander->discoveringPhyId)); 1090285242Sachim 1091285242Sachim 1092285242Sachim osti_memset(&smpDiscoverListReq, 0, sizeof(smpReqDiscoverList2_t)); 1093285242Sachim 1094285242Sachim smpDiscoverListReq.reserved1 = 0; 1095285242Sachim smpDiscoverListReq.StartingPhyID = 0; 1096285242Sachim smpDiscoverListReq.MaxNumDiscoverDesc = 40; /* 40 for SHORT FORMAT; 8 for Long Format; SAS2 p630 */ 1097285242Sachim smpDiscoverListReq.byte10 = 0x2; /* phy filter; all but "no device attached" */ 1098285242Sachim smpDiscoverListReq.byte11 = 0x1; /* descriptor type; SHORT FORMAT */ 1099285242Sachim 1100285242Sachim 1101285242Sachim dmSMPStart( 1102285242Sachim dmRoot, 1103285242Sachim agRoot, 1104285242Sachim oneDeviceData, 1105285242Sachim SMP_DISCOVER_LIST, 1106285242Sachim (bit8 *)&smpDiscoverListReq, 1107285242Sachim sizeof(smpReqDiscoverList2_t), 1108285242Sachim AGSA_SMP_INIT_REQ, 1109285242Sachim agNULL 1110285242Sachim ); 1111285242Sachim return; 1112285242Sachim} 1113285242Sachim 1114285242SachimosGLOBAL void 1115285242SachimtdsaDiscoverList2RespRcvd( 1116285242Sachim tiRoot_t *tiRoot, 1117285242Sachim agsaRoot_t *agRoot, 1118285242Sachim tdsaDeviceData_t *oneDeviceData, 1119285242Sachim tdssSMPFrameHeader_t *frameHeader, 1120285242Sachim agsaFrameHandle_t frameHandle 1121285242Sachim ) 1122285242Sachim{ 1123285242Sachim return; 1124285242Sachim} 1125285242Sachim#endif /* not yet */ 1126285242Sachim 1127285242Sachim/***************************************************************************** 1128285242Sachim*! \brief dmReportPhySataSend 1129285242Sachim* 1130285242Sachim* Purpose: This function sends Report Phy SATA to a device. 1131285242Sachim* 1132285242Sachim* \param dmRoot: Pointer to the OS Specific module allocated dmRoot_t 1133285242Sachim* instance. 1134285242Sachim* \param oneDeviceData: Pointer to the device data. 1135285242Sachim* \param phyId: Phy Identifier. 1136285242Sachim* 1137285242Sachim* \return: 1138285242Sachim* None 1139285242Sachim* 1140285242Sachim* \note: 1141285242Sachim* 1142285242Sachim*****************************************************************************/ 1143285242SachimosGLOBAL void 1144285242SachimdmReportPhySataSend( 1145285242Sachim dmRoot_t *dmRoot, 1146285242Sachim dmDeviceData_t *oneDeviceData, 1147285242Sachim bit8 phyId 1148285242Sachim ) 1149285242Sachim{ 1150285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1151285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1152285242Sachim agsaRoot_t *agRoot = dmAllShared->agRoot; 1153285242Sachim dmExpander_t *oneExpander; 1154285242Sachim smpReqReportPhySata_t smpReportPhySataReq; 1155285242Sachim 1156285242Sachim DM_DBG3(("dmReportPhySataSend: start\n")); 1157285242Sachim DM_DBG3(("dmReportPhySataSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 1158285242Sachim DM_DBG3(("dmReportPhySataSend: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1159285242Sachim DM_DBG3(("dmReportPhySataSend: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1160285242Sachim 1161285242Sachim oneExpander = oneDeviceData->dmExpander; 1162285242Sachim 1163285242Sachim if (oneExpander == agNULL) 1164285242Sachim { 1165285242Sachim DM_DBG1(("dmReportPhySataSend: Error!!! expander is NULL\n")); 1166285242Sachim return; 1167285242Sachim } 1168285242Sachim DM_DBG3(("dmReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id)); 1169285242Sachim DM_DBG3(("dmReportPhySataSend: phyid %d\n", phyId)); 1170285242Sachim 1171285242Sachim dm_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t)); 1172285242Sachim 1173285242Sachim smpReportPhySataReq.phyIdentifier = phyId; 1174285242Sachim 1175285242Sachim dmSMPStart( 1176285242Sachim dmRoot, 1177285242Sachim agRoot, 1178285242Sachim oneExpander->dmDevice, 1179285242Sachim SMP_REPORT_PHY_SATA, 1180285242Sachim (bit8 *)&smpReportPhySataReq, 1181285242Sachim sizeof(smpReqReportPhySata_t), 1182285242Sachim AGSA_SMP_INIT_REQ 1183285242Sachim ); 1184285242Sachim 1185285242Sachim return; 1186285242Sachim} 1187285242Sachim/***************************************************************************** 1188285242Sachim*! \brief dmReportPhySataRcvd 1189285242Sachim* 1190285242Sachim* Purpose: This function processes Report Phy SATA response. 1191285242Sachim* 1192285242Sachim* \param dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t 1193285242Sachim* instance. 1194285242Sachim* \param agRoot: Pointer to chip/driver Instance. 1195285242Sachim* \param oneDeviceData: Pointer to the device data. 1196285242Sachim* \param frameHeader: Pointer to SMP frame header. 1197285242Sachim* \param frameHandle: A Handle used to refer to the response frame 1198285242Sachim* 1199285242Sachim* \return: 1200285242Sachim* None 1201285242Sachim* 1202285242Sachim* \note: 1203285242Sachim* 1204285242Sachim*****************************************************************************/ 1205285242Sachim 1206285242SachimosGLOBAL void 1207285242SachimdmReportPhySataRcvd( 1208285242Sachim dmRoot_t *dmRoot, 1209285242Sachim agsaRoot_t *agRoot, 1210285242Sachim agsaIORequest_t *agIORequest, 1211285242Sachim dmDeviceData_t *oneDeviceData, 1212285242Sachim dmSMPFrameHeader_t *frameHeader, 1213285242Sachim agsaFrameHandle_t frameHandle 1214285242Sachim ) 1215285242Sachim{ 1216285242Sachim smpRespReportPhySata_t SMPreportPhySataResp; 1217285242Sachim smpRespReportPhySata_t *pSMPReportPhySataResp; 1218285242Sachim dmExpander_t *oneExpander = oneDeviceData->dmExpander; 1219285242Sachim dmIntPortContext_t *onePortContext = agNULL; 1220285242Sachim agsaFisRegDeviceToHost_t *fis; 1221285242Sachim dmDeviceData_t *SataDevice = agNULL; 1222285242Sachim#ifndef DIRECT_SMP 1223285242Sachim dmSMPRequestBody_t *tdSMPRequestBody; 1224285242Sachim#endif 1225285242Sachim bit8 sataDeviceType; 1226285242Sachim bit8 *bit8fis; 1227285242Sachim bit8 i = 0; 1228285242Sachim bit32 a = 0; 1229285242Sachim bit8 bit8fisarray[20]; 1230285242Sachim 1231285242Sachim DM_DBG3(("dmReportPhySataRcvd: start\n")); 1232285242Sachim DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1233285242Sachim DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1234285242Sachim 1235285242Sachim#ifndef DIRECT_SMP 1236285242Sachim tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 1237285242Sachim#endif 1238285242Sachim /* get the current sata device hanlde stored in the expander structure */ 1239285242Sachim if (oneExpander != agNULL) 1240285242Sachim { 1241285242Sachim SataDevice = oneExpander->dmDeviceToProcess; 1242285242Sachim } 1243285242Sachim 1244285242Sachim if (SataDevice != agNULL) 1245285242Sachim { 1246285242Sachim DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi)); 1247285242Sachim DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo)); 1248285242Sachim } 1249285242Sachim else 1250285242Sachim { 1251285242Sachim DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n")); 1252285242Sachim } 1253285242Sachim 1254285242Sachim pSMPReportPhySataResp = &SMPreportPhySataResp; 1255285242Sachim 1256285242Sachim#ifdef DIRECT_SMP 1257285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 1258285242Sachim#else 1259285242Sachim saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 1260285242Sachim#endif 1261285242Sachim 1262285242Sachim /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/ 1263285242Sachim 1264285242Sachim#ifndef DIRECT_SMP 1265285242Sachim ostiFreeMemory( 1266285242Sachim dmRoot, 1267285242Sachim tdSMPRequestBody->IndirectSMPReqosMemHandle, 1268285242Sachim tdSMPRequestBody->IndirectSMPReqLen 1269285242Sachim ); 1270285242Sachim ostiFreeMemory( 1271285242Sachim dmRoot, 1272285242Sachim tdSMPRequestBody->IndirectSMPResposMemHandle, 1273285242Sachim tdSMPRequestBody->IndirectSMPRespLen 1274285242Sachim ); 1275285242Sachim#endif 1276285242Sachim 1277285242Sachim onePortContext = oneDeviceData->dmPortContext; 1278285242Sachim 1279285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1280285242Sachim { 1281285242Sachim DM_DBG1(("dmReportPhySataRcvd: invalid port or aborted discovery!!!\n")); 1282285242Sachim return; 1283285242Sachim } 1284285242Sachim 1285285242Sachim if (SataDevice == agNULL) 1286285242Sachim { 1287285242Sachim DM_DBG1(("dmReportPhySataRcvd: SataDevice is NULL, wrong\n")); 1288285242Sachim dmDiscoverAbort(dmRoot, onePortContext); 1289285242Sachim return; 1290285242Sachim } 1291285242Sachim 1292285242Sachim if (frameHeader->smpFunctionResult == PHY_VACANT ) 1293285242Sachim { 1294285242Sachim DM_DBG1(("dmReportPhySataRcvd: smpFunctionResult == PHY_VACANT, wrong\n")); 1295285242Sachim return; 1296285242Sachim } 1297285242Sachim 1298285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ) 1299285242Sachim { 1300285242Sachim fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis; 1301285242Sachim if (fis->h.fisType == REG_DEV_TO_HOST_FIS) 1302285242Sachim { 1303285242Sachim /* save signature */ 1304285242Sachim DM_DBG3(("dmReportPhySataRcvd: saves the signature\n")); 1305285242Sachim /* saves signature */ 1306285242Sachim SataDevice->satSignature[0] = fis->d.sectorCount; 1307285242Sachim SataDevice->satSignature[1] = fis->d.lbaLow; 1308285242Sachim SataDevice->satSignature[2] = fis->d.lbaMid; 1309285242Sachim SataDevice->satSignature[3] = fis->d.lbaHigh; 1310285242Sachim SataDevice->satSignature[4] = fis->d.device; 1311285242Sachim SataDevice->satSignature[5] = 0; 1312285242Sachim SataDevice->satSignature[6] = 0; 1313285242Sachim SataDevice->satSignature[7] = 0; 1314285242Sachim 1315285242Sachim DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n", 1316285242Sachim SataDevice->satSignature[0], 1317285242Sachim SataDevice->satSignature[1], 1318285242Sachim SataDevice->satSignature[2], 1319285242Sachim SataDevice->satSignature[3], 1320285242Sachim SataDevice->satSignature[4])); 1321285242Sachim 1322285242Sachim sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature); 1323285242Sachim if( sataDeviceType == SATA_ATAPI_DEVICE) 1324285242Sachim { 1325285242Sachim SataDevice->agDeviceInfo.flag |= ATAPI_DEVICE_FLAG; 1326285242Sachim } 1327285242Sachim SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType; 1328285242Sachim } 1329285242Sachim /* Handling DataDomain buggy FIS */ 1330285242Sachim else if (fis->h.error == REG_DEV_TO_HOST_FIS) 1331285242Sachim { 1332285242Sachim /* needs to flip fis to host order */ 1333285242Sachim bit8fis = (bit8*)fis; 1334285242Sachim for (i=0;i<5;i++) 1335285242Sachim { 1336285242Sachim a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis); 1337285242Sachim DM_DBG3(("dmReportPhySataRcvd: a 0x%8x\n", a)); 1338285242Sachim bit8fisarray[4*i] = (a & 0xFF000000) >> 24; 1339285242Sachim bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16; 1340285242Sachim bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8; 1341285242Sachim bit8fisarray[4*i+3] = (a & 0x000000FF); 1342285242Sachim bit8fis = bit8fis + 4; 1343285242Sachim } 1344285242Sachim fis = (agsaFisRegDeviceToHost_t*) bit8fisarray; 1345285242Sachim /* save signature */ 1346285242Sachim DM_DBG3(("dmReportPhySataRcvd: DataDomain ATAPI saves the signature\n")); 1347285242Sachim /* saves signature */ 1348285242Sachim SataDevice->satSignature[0] = fis->d.sectorCount; 1349285242Sachim SataDevice->satSignature[1] = fis->d.lbaLow; 1350285242Sachim SataDevice->satSignature[2] = fis->d.lbaMid; 1351285242Sachim SataDevice->satSignature[3] = fis->d.lbaHigh; 1352285242Sachim SataDevice->satSignature[4] = fis->d.device; 1353285242Sachim SataDevice->satSignature[5] = 0; 1354285242Sachim SataDevice->satSignature[6] = 0; 1355285242Sachim SataDevice->satSignature[7] = 0; 1356285242Sachim 1357285242Sachim DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n", 1358285242Sachim SataDevice->satSignature[0], 1359285242Sachim SataDevice->satSignature[1], 1360285242Sachim SataDevice->satSignature[2], 1361285242Sachim SataDevice->satSignature[3], 1362285242Sachim SataDevice->satSignature[4])); 1363285242Sachim 1364285242Sachim sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature); 1365285242Sachim if( sataDeviceType == SATA_ATAPI_DEVICE) 1366285242Sachim { 1367285242Sachim SataDevice->agDeviceInfo.flag |= ATAPI_DEVICE_FLAG; 1368285242Sachim } 1369285242Sachim SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType; 1370285242Sachim } 1371285242Sachim else 1372285242Sachim { 1373285242Sachim DM_DBG3(("dmReportPhySataRcvd: getting next stp bride\n")); 1374285242Sachim } 1375285242Sachim 1376285242Sachim /* Continure to report this STP device to TD*/ 1377285242Sachim if (SataDevice->ExpDevice != agNULL) 1378285242Sachim { 1379285242Sachim tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival); 1380285242Sachim } 1381285242Sachim else 1382285242Sachim { 1383285242Sachim tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival); 1384285242Sachim } 1385285242Sachim } 1386285242Sachim else 1387285242Sachim { 1388285242Sachim DM_DBG3(("dmReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n", 1389285242Sachim frameHeader->smpFunctionResult)); 1390285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1391285242Sachim } 1392285242Sachim 1393285242Sachim return; 1394285242Sachim} 1395285242Sachim 1396285242Sachim/***************************************************************************** 1397285242Sachim*! \brief dmReportPhySata2Rcvd 1398285242Sachim* 1399285242Sachim* Purpose: This function processes SAS2.0 Report Phy SATA response. 1400285242Sachim* 1401285242Sachim* \param dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t 1402285242Sachim* instance. 1403285242Sachim* \param agRoot: Pointer to chip/driver Instance. 1404285242Sachim* \param oneDeviceData: Pointer to the device data. 1405285242Sachim* \param frameHeader: Pointer to SMP frame header. 1406285242Sachim* \param frameHandle: A Handle used to refer to the response frame 1407285242Sachim* 1408285242Sachim* \return: 1409285242Sachim* None 1410285242Sachim* 1411285242Sachim* \note: 1412285242Sachim* 1413285242Sachim*****************************************************************************/ 1414285242SachimosGLOBAL void 1415285242SachimdmReportPhySata2Rcvd( 1416285242Sachim dmRoot_t *dmRoot, 1417285242Sachim agsaRoot_t *agRoot, 1418285242Sachim agsaIORequest_t *agIORequest, 1419285242Sachim dmDeviceData_t *oneDeviceData, 1420285242Sachim dmSMPFrameHeader_t *frameHeader, 1421285242Sachim agsaFrameHandle_t frameHandle 1422285242Sachim ) 1423285242Sachim{ 1424285242Sachim smpRespReportPhySata2_t SMPreportPhySataResp; 1425285242Sachim smpRespReportPhySata2_t *pSMPReportPhySataResp; 1426285242Sachim dmExpander_t *oneExpander = oneDeviceData->dmExpander; 1427285242Sachim dmIntPortContext_t *onePortContext = agNULL; 1428285242Sachim agsaFisRegDeviceToHost_t *fis; 1429285242Sachim dmDeviceData_t *SataDevice = agNULL; 1430285242Sachim#ifndef DIRECT_SMP 1431285242Sachim dmSMPRequestBody_t *tdSMPRequestBody; 1432285242Sachim#endif 1433285242Sachim bit8 sataDeviceType = 0; 1434285242Sachim bit8 *bit8fis; 1435285242Sachim bit8 i = 0; 1436285242Sachim bit32 a = 0; 1437285242Sachim bit8 bit8fisarray[20]; 1438285242Sachim 1439285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: start\n")); 1440285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 1441285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 1442285242Sachim 1443285242Sachim#ifndef DIRECT_SMP 1444285242Sachim tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 1445285242Sachim#endif 1446285242Sachim /* get the current sata device hanlde stored in the expander structure */ 1447285242Sachim if (oneExpander != agNULL) 1448285242Sachim { 1449285242Sachim SataDevice = oneExpander->dmDeviceToProcess; 1450285242Sachim } 1451285242Sachim 1452285242Sachim if (SataDevice != agNULL) 1453285242Sachim { 1454285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi)); 1455285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo)); 1456285242Sachim } 1457285242Sachim else 1458285242Sachim { 1459285242Sachim DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n")); 1460285242Sachim } 1461285242Sachim 1462285242Sachim pSMPReportPhySataResp = &SMPreportPhySataResp; 1463285242Sachim 1464285242Sachim#ifdef DIRECT_SMP 1465285242Sachim saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 1466285242Sachim#else 1467285242Sachim saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t)); 1468285242Sachim#endif 1469285242Sachim 1470285242Sachim /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/ 1471285242Sachim 1472285242Sachim#ifndef DIRECT_SMP 1473285242Sachim ostiFreeMemory( 1474285242Sachim dmRoot, 1475285242Sachim tdSMPRequestBody->IndirectSMPReqosMemHandle, 1476285242Sachim tdSMPRequestBody->IndirectSMPReqLen 1477285242Sachim ); 1478285242Sachim ostiFreeMemory( 1479285242Sachim dmRoot, 1480285242Sachim tdSMPRequestBody->IndirectSMPResposMemHandle, 1481285242Sachim tdSMPRequestBody->IndirectSMPRespLen 1482285242Sachim ); 1483285242Sachim#endif 1484285242Sachim 1485285242Sachim onePortContext = oneDeviceData->dmPortContext; 1486285242Sachim 1487285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1488285242Sachim { 1489285242Sachim DM_DBG1(("dmReportPhySata2Rcvd: invalid port or aborted discovery!!!\n")); 1490285242Sachim return; 1491285242Sachim } 1492285242Sachim 1493285242Sachim if (SataDevice == agNULL) 1494285242Sachim { 1495285242Sachim DM_DBG1(("dmReportPhySata2Rcvd: SataDevice is NULL, wrong\n")); 1496285242Sachim dmDiscoverAbort(dmRoot, onePortContext); 1497285242Sachim return; 1498285242Sachim } 1499285242Sachim 1500285242Sachim if ( frameHeader->smpFunctionResult == PHY_VACANT ) 1501285242Sachim { 1502285242Sachim DM_DBG1(("dmReportPhySata2Rcvd: smpFunctionResult == PHY_VACANT, wrong\n")); 1503285242Sachim return; 1504285242Sachim } 1505285242Sachim 1506285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ) 1507285242Sachim { 1508285242Sachim fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis; 1509285242Sachim if (fis->h.fisType == REG_DEV_TO_HOST_FIS) 1510285242Sachim { 1511285242Sachim /* save signature */ 1512285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: saves the signature\n")); 1513285242Sachim /* saves signature */ 1514285242Sachim SataDevice->satSignature[0] = fis->d.sectorCount; 1515285242Sachim SataDevice->satSignature[1] = fis->d.lbaLow; 1516285242Sachim SataDevice->satSignature[2] = fis->d.lbaMid; 1517285242Sachim SataDevice->satSignature[3] = fis->d.lbaHigh; 1518285242Sachim SataDevice->satSignature[4] = fis->d.device; 1519285242Sachim SataDevice->satSignature[5] = 0; 1520285242Sachim SataDevice->satSignature[6] = 0; 1521285242Sachim SataDevice->satSignature[7] = 0; 1522285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n", 1523285242Sachim SataDevice->satSignature[0], 1524285242Sachim SataDevice->satSignature[1], 1525285242Sachim SataDevice->satSignature[2], 1526285242Sachim SataDevice->satSignature[3], 1527285242Sachim SataDevice->satSignature[4])); 1528285242Sachim sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature); 1529285242Sachim if( sataDeviceType == SATA_ATAPI_DEVICE) 1530285242Sachim { 1531285242Sachim SataDevice->agDeviceInfo.flag |= ATAPI_DEVICE_FLAG; 1532285242Sachim } 1533285242Sachim SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType; 1534285242Sachim } 1535285242Sachim /* Handling DataDomain buggy FIS */ 1536285242Sachim else if (fis->h.error == REG_DEV_TO_HOST_FIS) 1537285242Sachim { 1538285242Sachim /* needs to flip fis to host order */ 1539285242Sachim bit8fis = (bit8*)fis; 1540285242Sachim for (i=0;i<5;i++) 1541285242Sachim { 1542285242Sachim a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis); 1543285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: a 0x%8x\n", a)); 1544285242Sachim bit8fisarray[4*i] = (a & 0xFF000000) >> 24; 1545285242Sachim bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16; 1546285242Sachim bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8; 1547285242Sachim bit8fisarray[4*i+3] = (a & 0x000000FF); 1548285242Sachim bit8fis = bit8fis + 4; 1549285242Sachim } 1550285242Sachim fis = (agsaFisRegDeviceToHost_t*) bit8fisarray; 1551285242Sachim /* save signature */ 1552285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: DataDomain ATAPI saves the signature\n")); 1553285242Sachim /* saves signature */ 1554285242Sachim SataDevice->satSignature[0] = fis->d.sectorCount; 1555285242Sachim SataDevice->satSignature[1] = fis->d.lbaLow; 1556285242Sachim SataDevice->satSignature[2] = fis->d.lbaMid; 1557285242Sachim SataDevice->satSignature[3] = fis->d.lbaHigh; 1558285242Sachim SataDevice->satSignature[4] = fis->d.device; 1559285242Sachim SataDevice->satSignature[5] = 0; 1560285242Sachim SataDevice->satSignature[6] = 0; 1561285242Sachim SataDevice->satSignature[7] = 0; 1562285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n", 1563285242Sachim SataDevice->satSignature[0], 1564285242Sachim SataDevice->satSignature[1], 1565285242Sachim SataDevice->satSignature[2], 1566285242Sachim SataDevice->satSignature[3], 1567285242Sachim SataDevice->satSignature[4])); 1568285242Sachim 1569285242Sachim sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature); 1570285242Sachim if( sataDeviceType == SATA_ATAPI_DEVICE) 1571285242Sachim { 1572285242Sachim SataDevice->agDeviceInfo.flag |= ATAPI_DEVICE_FLAG; 1573285242Sachim } 1574285242Sachim SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType; 1575285242Sachim } 1576285242Sachim else 1577285242Sachim { 1578285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: getting next stp bride\n")); 1579285242Sachim } 1580285242Sachim 1581285242Sachim /* Continue to report this STP device to TD*/ 1582285242Sachim if (SataDevice->ExpDevice != agNULL) 1583285242Sachim { 1584285242Sachim tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival); 1585285242Sachim } 1586285242Sachim else 1587285242Sachim { 1588285242Sachim tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival); 1589285242Sachim } 1590285242Sachim 1591285242Sachim } 1592285242Sachim else 1593285242Sachim { 1594285242Sachim DM_DBG3(("dmReportPhySata2Rcvd: siReportPhySataRcvd SMP function return result %x\n", 1595285242Sachim frameHeader->smpFunctionResult)); 1596285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1597285242Sachim } 1598285242Sachim 1599285242Sachim return; 1600285242Sachim} 1601285242Sachim 1602285242Sachim 1603285242Sachim 1604285242SachimosGLOBAL bit32 1605285242SachimdmRoutingEntryAdd( 1606285242Sachim dmRoot_t *dmRoot, 1607285242Sachim dmExpander_t *oneExpander, 1608285242Sachim bit32 phyId, 1609285242Sachim bit32 configSASAddressHi, 1610285242Sachim bit32 configSASAddressLo 1611285242Sachim ) 1612285242Sachim{ 1613285242Sachim dmIntRoot_t *dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 1614285242Sachim dmIntContext_t *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 1615285242Sachim agsaRoot_t *agRoot = dmAllShared->agRoot; 1616285242Sachim bit32 ret = agTRUE; 1617285242Sachim dmIntPortContext_t *onePortContext; 1618285242Sachim smpReqConfigureRouteInformation_t confRoutingInfo; 1619285242Sachim bit32 i; 1620285242Sachim 1621285242Sachim DM_DBG3(("dmRoutingEntryAdd: start\n")); 1622285242Sachim DM_DBG3(("dmRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1623285242Sachim DM_DBG3(("dmRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1624285242Sachim DM_DBG3(("dmRoutingEntryAdd: phyid %d\n", phyId)); 1625285242Sachim 1626285242Sachim if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi && 1627285242Sachim oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo 1628285242Sachim ) 1629285242Sachim { 1630285242Sachim DM_DBG3(("dmRoutingEntryAdd: unnecessary\n")); 1631285242Sachim return ret; 1632285242Sachim } 1633285242Sachim if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE) 1634285242Sachim { 1635285242Sachim DM_DBG3(("dmRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId])); 1636285242Sachim return ret; 1637285242Sachim } 1638285242Sachim 1639285242Sachim onePortContext = oneExpander->dmDevice->dmPortContext; 1640285242Sachim 1641285242Sachim onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING; 1642285242Sachim 1643285242Sachim /* reset smpReqConfigureRouteInformation_t */ 1644285242Sachim dm_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t)); 1645285242Sachim if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex ) 1646285242Sachim { 1647285242Sachim DM_DBG3(("dmRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi)); 1648285242Sachim DM_DBG3(("dmRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo)); 1649285242Sachim DM_DBG3(("dmRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId])); 1650285242Sachim 1651285242Sachim oneExpander->configSASAddressHi = configSASAddressHi; 1652285242Sachim oneExpander->configSASAddressLo = configSASAddressLo; 1653285242Sachim confRoutingInfo.reserved1[0] = 0; 1654285242Sachim confRoutingInfo.reserved1[1] = 0; 1655285242Sachim OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId])); 1656285242Sachim confRoutingInfo.reserved2 = 0; 1657285242Sachim confRoutingInfo.phyIdentifier = (bit8)phyId; 1658285242Sachim confRoutingInfo.reserved3[0] = 0; 1659285242Sachim confRoutingInfo.reserved3[1] = 0; 1660285242Sachim confRoutingInfo.disabledBit_reserved4 = 0; 1661285242Sachim confRoutingInfo.reserved5[0] = 0; 1662285242Sachim confRoutingInfo.reserved5[1] = 0; 1663285242Sachim confRoutingInfo.reserved5[2] = 0; 1664285242Sachim OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi); 1665285242Sachim OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo); 1666285242Sachim for ( i = 0; i < 16; i ++ ) 1667285242Sachim { 1668285242Sachim confRoutingInfo.reserved6[i] = 0; 1669285242Sachim } 1670285242Sachim dmSMPStart(dmRoot, agRoot, oneExpander->dmDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ); 1671285242Sachim 1672285242Sachim oneExpander->currentIndex[phyId] ++; 1673285242Sachim } 1674285242Sachim else 1675285242Sachim { 1676285242Sachim DM_DBG3(("dmRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex)); 1677285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1678285242Sachim 1679285242Sachim ret = agFALSE; 1680285242Sachim } 1681285242Sachim return ret; 1682285242Sachim} 1683285242Sachim 1684285242Sachim 1685285242SachimosGLOBAL void 1686285242SachimdmConfigRoutingInfoRespRcvd( 1687285242Sachim dmRoot_t *dmRoot, 1688285242Sachim agsaRoot_t *agRoot, 1689285242Sachim agsaIORequest_t *agIORequest, 1690285242Sachim dmDeviceData_t *oneDeviceData, 1691285242Sachim dmSMPFrameHeader_t *frameHeader, 1692285242Sachim agsaFrameHandle_t frameHandle 1693285242Sachim ) 1694285242Sachim{ 1695285242Sachim dmIntPortContext_t *onePortContext; 1696285242Sachim dmExpander_t *oneExpander = oneDeviceData->dmExpander; 1697285242Sachim dmExpander_t *UpStreamExpander; 1698285242Sachim dmExpander_t *DownStreamExpander; 1699285242Sachim dmExpander_t *ReturningExpander; 1700285242Sachim dmExpander_t *ConfigurableExpander; 1701285242Sachim dmDeviceData_t *ReturningExpanderDeviceData = agNULL; 1702285242Sachim bit32 dupConfigSASAddr = agFALSE; 1703285242Sachim 1704285242Sachim 1705285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: start\n")); 1706285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1707285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1708285242Sachim 1709285242Sachim onePortContext = oneDeviceData->dmPortContext; 1710285242Sachim 1711285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1712285242Sachim { 1713285242Sachim DM_DBG1(("dmConfigRoutingInfoRespRcvd: invalid port or aborted discovery!!!\n")); 1714285242Sachim return; 1715285242Sachim } 1716285242Sachim 1717285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED || 1718285242Sachim frameHeader->smpFunctionResult == PHY_VACANT 1719285242Sachim ) 1720285242Sachim { 1721285242Sachim DownStreamExpander = oneExpander->dmCurrentDownStreamExpander; 1722285242Sachim if (DownStreamExpander != agNULL) 1723285242Sachim { 1724285242Sachim DownStreamExpander->currentUpStreamPhyIndex ++; 1725285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 1726285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys)); 1727285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 1728285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 1729285242Sachim 1730285242Sachim } 1731285242Sachim 1732285242Sachim oneExpander->currentDownStreamPhyIndex++; 1733285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys)); 1734285242Sachim 1735285242Sachim if ( (DownStreamExpander != agNULL) && 1736285242Sachim (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys) 1737285242Sachim ) 1738285242Sachim { 1739285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: first if\n")); 1740285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 1741285242Sachim 1742285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex])); 1743285242Sachim 1744285242Sachim dmRoutingEntryAdd(dmRoot, 1745285242Sachim oneExpander, 1746285242Sachim DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex], 1747285242Sachim oneExpander->configSASAddressHi, 1748285242Sachim oneExpander->configSASAddressLo 1749285242Sachim ); 1750285242Sachim } 1751285242Sachim else 1752285242Sachim { 1753285242Sachim /* traversing up till discovery Root onePortContext->discovery.RootExp */ 1754285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: else\n")); 1755285242Sachim 1756285242Sachim UpStreamExpander = oneExpander->dmUpStreamExpander; 1757285242Sachim ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1758285242Sachim if (UpStreamExpander != agNULL) 1759285242Sachim { 1760285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 1761285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 1762285242Sachim } 1763285242Sachim else 1764285242Sachim { 1765285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n")); 1766285242Sachim } 1767285242Sachim dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 1768285242Sachim ConfigurableExpander, 1769285242Sachim oneExpander->configSASAddressHi, 1770285242Sachim oneExpander->configSASAddressLo 1771285242Sachim ); 1772285242Sachim 1773285242Sachim if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE) 1774285242Sachim { 1775285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: else if\n")); 1776285242Sachim 1777285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi)); 1778285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo)); 1779285242Sachim 1780285242Sachim if ( UpStreamExpander != agNULL) 1781285242Sachim { 1782285242Sachim UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 1783285242Sachim } 1784285242Sachim ConfigurableExpander->currentDownStreamPhyIndex = 1785285242Sachim dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 1786285242Sachim ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander; 1787285242Sachim if ( DownStreamExpander != agNULL) 1788285242Sachim { 1789285242Sachim DownStreamExpander->currentUpStreamPhyIndex = 0; 1790285242Sachim } 1791285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex)); 1792285242Sachim 1793285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex])); 1794285242Sachim dmRoutingEntryAdd(dmRoot, 1795285242Sachim ConfigurableExpander, 1796285242Sachim ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 1797285242Sachim oneExpander->configSASAddressHi, 1798285242Sachim oneExpander->configSASAddressLo 1799285242Sachim ); 1800285242Sachim } 1801285242Sachim else 1802285242Sachim { 1803285242Sachim /* going back to where it was */ 1804285242Sachim /* ConfigRoutingInfo is done for a target */ 1805285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n")); 1806285242Sachim ReturningExpander = oneExpander->dmReturnginExpander; 1807285242Sachim if ( DownStreamExpander != agNULL) 1808285242Sachim { 1809285242Sachim DownStreamExpander->currentUpStreamPhyIndex = 0; 1810285242Sachim } 1811285242Sachim /* debugging */ 1812285242Sachim if (ReturningExpander != agNULL) 1813285242Sachim { 1814285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi)); 1815285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo)); 1816285242Sachim ReturningExpanderDeviceData = ReturningExpander->dmDevice; 1817285242Sachim } 1818285242Sachim 1819285242Sachim /* No longer in DISCOVERY_CONFIG_ROUTING */ 1820285242Sachim onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 1821285242Sachim 1822285242Sachim if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL) 1823285242Sachim { 1824285242Sachim /* If not the last phy */ 1825285242Sachim if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys ) 1826285242Sachim { 1827285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: More Phys to discover\n")); 1828285242Sachim /* continue discovery for the next phy */ 1829285242Sachim /* needs to send only one Discovery not multiple times */ 1830285242Sachim if (ReturningExpander->discoverSMPAllowed == agTRUE) 1831285242Sachim { 1832285242Sachim dmDiscoverSend(dmRoot, ReturningExpanderDeviceData); 1833285242Sachim } 1834285242Sachim if (ReturningExpander != agNULL) 1835285242Sachim { 1836285242Sachim ReturningExpander->discoverSMPAllowed = agFALSE; 1837285242Sachim } 1838285242Sachim } 1839285242Sachim /* If the last phy */ 1840285242Sachim else 1841285242Sachim { 1842285242Sachim DM_DBG3(("dmConfigRoutingInfoRespRcvd: No More Phys\n")); 1843285242Sachim ReturningExpander->discoverSMPAllowed = agTRUE; 1844285242Sachim 1845285242Sachim /* remove the expander from the discovering list */ 1846285242Sachim dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander); 1847285242Sachim /* continue downstream discovering */ 1848285242Sachim dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData); 1849285242Sachim 1850285242Sachim //DownStreamExpander 1851285242Sachim } 1852285242Sachim } 1853285242Sachim } 1854285242Sachim } 1855285242Sachim } 1856285242Sachim else 1857285242Sachim { 1858285242Sachim DM_DBG1(("dmConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n", frameHeader->smpFunctionResult)); 1859285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 1860285242Sachim } 1861285242Sachim return; 1862285242Sachim} 1863285242Sachim 1864285242SachimosGLOBAL void 1865285242SachimdmConfigRoutingInfo2RespRcvd( 1866285242Sachim dmRoot_t *dmRoot, 1867285242Sachim agsaRoot_t *agRoot, 1868285242Sachim agsaIORequest_t *agIORequest, 1869285242Sachim dmDeviceData_t *oneDeviceData, 1870285242Sachim dmSMPFrameHeader_t *frameHeader, 1871285242Sachim agsaFrameHandle_t frameHandle 1872285242Sachim ) 1873285242Sachim{ 1874285242Sachim dmExpander_t *oneExpander = oneDeviceData->dmExpander; 1875285242Sachim dmExpander_t *UpStreamExpander; 1876285242Sachim dmExpander_t *DownStreamExpander; 1877285242Sachim dmExpander_t *ReturningExpander; 1878285242Sachim dmExpander_t *ConfigurableExpander; 1879285242Sachim 1880285242Sachim dmIntPortContext_t *onePortContext; 1881285242Sachim dmDeviceData_t *ReturningExpanderDeviceData = agNULL; 1882285242Sachim bit32 dupConfigSASAddr = agFALSE; 1883285242Sachim 1884285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: start\n")); 1885285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi)); 1886285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo)); 1887285242Sachim 1888285242Sachim onePortContext = oneDeviceData->dmPortContext; 1889285242Sachim 1890285242Sachim if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE) 1891285242Sachim { 1892285242Sachim DM_DBG1(("dmConfigRoutingInfo2RespRcvd: invalid port or aborted discovery!!!\n")); 1893285242Sachim return; 1894285242Sachim } 1895285242Sachim 1896285242Sachim if (frameHeader->smpFunctionResult == PHY_VACANT) 1897285242Sachim { 1898285242Sachim DM_DBG1(("dmConfigRoutingInfo2RespRcvd: smpFunctionResult is PHY_VACANT\n")); 1899285242Sachim } 1900285242Sachim 1901285242Sachim if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED || 1902285242Sachim frameHeader->smpFunctionResult == PHY_VACANT 1903285242Sachim ) 1904285242Sachim { 1905285242Sachim DownStreamExpander = oneExpander->dmCurrentDownStreamExpander; 1906285242Sachim if (DownStreamExpander != agNULL) 1907285242Sachim { 1908285242Sachim DownStreamExpander->currentUpStreamPhyIndex ++; 1909285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 1910285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys)); 1911285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 1912285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 1913285242Sachim 1914285242Sachim } 1915285242Sachim 1916285242Sachim oneExpander->currentDownStreamPhyIndex++; 1917285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys)); 1918285242Sachim 1919285242Sachim if ( (DownStreamExpander != agNULL) && 1920285242Sachim (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys) 1921285242Sachim ) 1922285242Sachim { 1923285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: first if\n")); 1924285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex)); 1925285242Sachim 1926285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex])); 1927285242Sachim 1928285242Sachim dmRoutingEntryAdd(dmRoot, 1929285242Sachim oneExpander, 1930285242Sachim DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex], 1931285242Sachim oneExpander->configSASAddressHi, 1932285242Sachim oneExpander->configSASAddressLo 1933285242Sachim ); 1934285242Sachim } 1935285242Sachim else 1936285242Sachim { 1937285242Sachim /* traversing up till discovery Root onePortContext->discovery.RootExp */ 1938285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else\n")); 1939285242Sachim 1940285242Sachim UpStreamExpander = oneExpander->dmUpStreamExpander; 1941285242Sachim ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander); 1942285242Sachim if (UpStreamExpander != agNULL) 1943285242Sachim { 1944285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi)); 1945285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo)); 1946285242Sachim } 1947285242Sachim else 1948285242Sachim { 1949285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander is NULL\n")); 1950285242Sachim } 1951285242Sachim dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot, 1952285242Sachim ConfigurableExpander, 1953285242Sachim oneExpander->configSASAddressHi, 1954285242Sachim oneExpander->configSASAddressLo 1955285242Sachim ); 1956285242Sachim 1957285242Sachim if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE) 1958285242Sachim { 1959285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else if\n")); 1960285242Sachim 1961285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi)); 1962285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo)); 1963285242Sachim 1964285242Sachim if ( UpStreamExpander != agNULL) 1965285242Sachim { 1966285242Sachim UpStreamExpander->dmCurrentDownStreamExpander = oneExpander; 1967285242Sachim } 1968285242Sachim ConfigurableExpander->currentDownStreamPhyIndex = 1969285242Sachim dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander); 1970285242Sachim ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander; 1971285242Sachim if ( DownStreamExpander != agNULL) 1972285242Sachim { 1973285242Sachim DownStreamExpander->currentUpStreamPhyIndex = 0; 1974285242Sachim } 1975285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex)); 1976285242Sachim 1977285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex])); 1978285242Sachim dmRoutingEntryAdd(dmRoot, 1979285242Sachim ConfigurableExpander, 1980285242Sachim ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex], 1981285242Sachim oneExpander->configSASAddressHi, 1982285242Sachim oneExpander->configSASAddressLo 1983285242Sachim ); 1984285242Sachim } 1985285242Sachim else 1986285242Sachim { 1987285242Sachim /* going back to where it was */ 1988285242Sachim /* ConfigRoutingInfo is done for a target */ 1989285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: $$$$$$ my change $$$$$ \n")); 1990285242Sachim ReturningExpander = oneExpander->dmReturnginExpander; 1991285242Sachim if ( DownStreamExpander != agNULL) 1992285242Sachim { 1993285242Sachim DownStreamExpander->currentUpStreamPhyIndex = 0; 1994285242Sachim } 1995285242Sachim /* debugging */ 1996285242Sachim if (ReturningExpander != agNULL) 1997285242Sachim { 1998285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi)); 1999285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo)); 2000285242Sachim ReturningExpanderDeviceData = ReturningExpander->dmDevice; 2001285242Sachim } 2002285242Sachim 2003285242Sachim /* No longer in DISCOVERY_CONFIG_ROUTING */ 2004285242Sachim onePortContext->discovery.status = DISCOVERY_DOWN_STREAM; 2005285242Sachim 2006285242Sachim if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL) 2007285242Sachim { 2008285242Sachim /* If not the last phy */ 2009285242Sachim if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys ) 2010285242Sachim { 2011285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: More Phys to discover\n")); 2012285242Sachim /* continue discovery for the next phy */ 2013285242Sachim /* needs to send only one Discovery not multiple times */ 2014285242Sachim if (ReturningExpander->discoverSMPAllowed == agTRUE) 2015285242Sachim { 2016285242Sachim dmDiscoverSend(dmRoot, ReturningExpanderDeviceData); 2017285242Sachim } 2018285242Sachim if (ReturningExpander != agNULL) 2019285242Sachim { 2020285242Sachim ReturningExpander->discoverSMPAllowed = agFALSE; 2021285242Sachim } 2022285242Sachim } 2023285242Sachim /* If the last phy */ 2024285242Sachim else 2025285242Sachim { 2026285242Sachim DM_DBG2(("dmConfigRoutingInfo2RespRcvd: No More Phys\n")); 2027285242Sachim ReturningExpander->discoverSMPAllowed = agTRUE; 2028285242Sachim 2029285242Sachim /* remove the expander from the discovering list */ 2030285242Sachim dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander); 2031285242Sachim /* continue downstream discovering */ 2032285242Sachim dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData); 2033285242Sachim 2034285242Sachim //DownStreamExpander 2035285242Sachim } 2036285242Sachim } 2037285242Sachim } 2038285242Sachim } 2039285242Sachim } 2040285242Sachim else 2041285242Sachim { 2042285242Sachim DM_DBG1(("dmConfigRoutingInfo2RespRcvd: Discovery Error SMP function return result error=0x%x!!!\n", frameHeader->smpFunctionResult)); 2043285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2044285242Sachim } 2045285242Sachim return; 2046285242Sachim} 2047285242Sachim 2048285242Sachim 2049285242Sachim/* no task management case here for phyControl*/ 2050285242Sachim 2051285242Sachim/* no task management case here for phyControl*/ 2052285242SachimosGLOBAL void 2053285242SachimdmPhyControlRespRcvd( 2054285242Sachim dmRoot_t *dmRoot, 2055285242Sachim agsaRoot_t *agRoot, 2056285242Sachim agsaIORequest_t *agIORequest, 2057285242Sachim dmDeviceData_t *oneDeviceData, 2058285242Sachim dmSMPFrameHeader_t *frameHeader, 2059285242Sachim agsaFrameHandle_t frameHandle 2060285242Sachim ) 2061285242Sachim{ 2062285242Sachim DM_DBG3(("dmPhyControlRespRcvd: start\n")); 2063285242Sachim DM_DBG3(("dmPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 2064285242Sachim DM_DBG3(("dmPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 2065285242Sachim 2066285242Sachim if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2067285242Sachim { 2068285242Sachim DM_DBG3(("dmPhyControlRespRcvd: SMP success\n")); 2069285242Sachim } 2070285242Sachim else 2071285242Sachim { 2072285242Sachim DM_DBG1(("dmPhyControlRespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult)); 2073285242Sachim } 2074285242Sachim 2075285242Sachim return; 2076285242Sachim} 2077285242Sachim 2078285242Sachim/* no task management case here for phyControl*/ 2079285242SachimosGLOBAL void 2080285242SachimdmPhyControl2RespRcvd( 2081285242Sachim dmRoot_t *dmRoot, 2082285242Sachim agsaRoot_t *agRoot, 2083285242Sachim agsaIORequest_t *agIORequest, 2084285242Sachim dmDeviceData_t *oneDeviceData, 2085285242Sachim dmSMPFrameHeader_t *frameHeader, 2086285242Sachim agsaFrameHandle_t frameHandle 2087285242Sachim ) 2088285242Sachim{ 2089285242Sachim DM_DBG2(("dmPhyControl2RespRcvd: start\n")); 2090285242Sachim DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi)); 2091285242Sachim DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo)); 2092285242Sachim 2093285242Sachim if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2094285242Sachim { 2095285242Sachim DM_DBG2(("dmPhyControl2RespRcvd: SMP success\n")); 2096285242Sachim } 2097285242Sachim else 2098285242Sachim { 2099285242Sachim DM_DBG1(("dmPhyControl2RespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult)); 2100285242Sachim } 2101285242Sachim 2102285242Sachim return; 2103285242Sachim} 2104285242Sachim 2105285242SachimosGLOBAL void 2106285242SachimdmPhyControlFailureRespRcvd( 2107285242Sachim dmRoot_t *dmRoot, 2108285242Sachim agsaRoot_t *agRoot, 2109285242Sachim dmDeviceData_t *oneDeviceData, 2110285242Sachim dmSMPFrameHeader_t *frameHeader, 2111285242Sachim agsaFrameHandle_t frameHandle 2112285242Sachim ) 2113285242Sachim{ 2114285242Sachim DM_DBG1(("dmPhyControlFailureRespRcvd: start\n")); 2115285242Sachim return; 2116285242Sachim} 2117285242Sachim 2118285242SachimGLOBAL void dmSetDeviceInfoCB( 2119285242Sachim agsaRoot_t *agRoot, 2120285242Sachim agsaContext_t *agContext, 2121285242Sachim agsaDevHandle_t *agDevHandle, 2122285242Sachim bit32 status, 2123285242Sachim bit32 option, 2124285242Sachim bit32 param 2125285242Sachim ) 2126285242Sachim{ 2127285242Sachim dmRoot_t *dmRoot = agNULL; 2128285242Sachim agsaIORequest_t *agIORequest; 2129285242Sachim bit32 smstatus; 2130285242Sachim agsaSASRequestBody_t *agSASRequestBody; 2131285242Sachim dmSMPRequestBody_t *dmSMPRequestBody = agNULL; 2132285242Sachim dmIntPortContext_t *onePortContext = agNULL; 2133285242Sachim dmDeviceData_t *oneDeviceData; 2134285242Sachim bit8 SMPRequestFunction; 2135285242Sachim bit8 devType_S_Rate; 2136285242Sachim DM_DBG1(("dmSetDeviceInfoCB: start\n")); 2137285242Sachim DM_DBG4(("dmSetDeviceInfoCB: status 0x%x\n", status)); 2138285242Sachim DM_DBG4(("dmSetDeviceInfoCB: option 0x%x\n", option)); 2139285242Sachim DM_DBG4(("dmSetDeviceInfoCB: param 0x%x\n", param)); 2140285242Sachim if (status != OSSA_SUCCESS) 2141285242Sachim { 2142285242Sachim DM_DBG1(("dmSetDeviceInfoCB: status %d\n", status)); 2143285242Sachim DM_DBG1(("dmSetDeviceInfoCB: option 0x%x\n", option)); 2144285242Sachim DM_DBG1(("dmSetDeviceInfoCB: param 0x%x\n", param)); 2145285242Sachim if (option == 32) /* set connection rate */ 2146285242Sachim { 2147285242Sachim DM_DBG1(("dmSetDeviceInfoCB: IO failure\n")); 2148285242Sachim agIORequest = (agsaIORequest_t *)agContext->osData; 2149285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 2150285242Sachim dmRoot = dmSMPRequestBody->dmRoot; 2151285242Sachim oneDeviceData = dmSMPRequestBody->dmDevice; 2152285242Sachim onePortContext = oneDeviceData->dmPortContext; 2153285242Sachim SMPRequestFunction = dmSMPRequestBody->smpPayload[1]; 2154285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || 2155285242Sachim SMPRequestFunction == SMP_DISCOVER || 2156285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2157285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2158285242Sachim ) 2159285242Sachim { 2160285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2161285242Sachim } 2162285242Sachim else if (SMPRequestFunction == SMP_PHY_CONTROL) 2163285242Sachim { 2164285242Sachim /* task management failure */ 2165285242Sachim dmPhyControlFailureRespRcvd( 2166285242Sachim dmRoot, 2167285242Sachim agRoot, 2168285242Sachim oneDeviceData, 2169285242Sachim agNULL, 2170285242Sachim agNULL 2171285242Sachim ); 2172285242Sachim } 2173285242Sachim } 2174285242Sachim } 2175285242Sachim if (agDevHandle == agNULL) 2176285242Sachim { 2177285242Sachim DM_DBG1(("dmSetDeviceInfoCB: agDevHandle is NULL\n")); 2178285242Sachim return; 2179285242Sachim } 2180285242Sachim 2181285242Sachim /* retry SMP */ 2182285242Sachim if (option == 32) /* set connection rate */ 2183285242Sachim { 2184285242Sachim DM_DBG1(("dmSetDeviceInfoCB: set connection rate option\n")); 2185285242Sachim agIORequest = (agsaIORequest_t *)agContext->osData; 2186285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 2187285242Sachim dmRoot = dmSMPRequestBody->dmRoot; 2188285242Sachim agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 2189285242Sachim oneDeviceData = dmSMPRequestBody->dmDevice; 2190285242Sachim onePortContext = oneDeviceData->dmPortContext; 2191285242Sachim devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate; 2192285242Sachim devType_S_Rate = (devType_S_Rate & 0xF0) | (param >> 28); 2193285242Sachim oneDeviceData->agDeviceInfo.devType_S_Rate = devType_S_Rate; 2194285242Sachim SMPRequestFunction = dmSMPRequestBody->smpPayload[1]; 2195285242Sachim DM_DBG1(("dmSetDeviceInfoCB: SMPRequestFunction 0x%x\n", SMPRequestFunction)); 2196285242Sachim DM_DBG1(("dmSetDeviceInfoCB: new rate is 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo))); 2197285242Sachim smstatus = saSMPStart( 2198285242Sachim agRoot, 2199285242Sachim agIORequest, 2200285242Sachim 0, 2201285242Sachim agDevHandle, 2202285242Sachim AGSA_SMP_INIT_REQ, 2203285242Sachim agSASRequestBody, 2204285242Sachim &dmsaSMPCompleted 2205285242Sachim ); 2206285242Sachim if (status == AGSA_RC_SUCCESS) 2207285242Sachim { 2208285242Sachim /* increment the number of pending SMP */ 2209285242Sachim onePortContext->discovery.pendingSMP++; 2210285242Sachim// dmSMPRequestBody->retries++; 2211285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 2212285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2213285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2214285242Sachim ) 2215285242Sachim { 2216285242Sachim /* start discovery-related SMP timer */ 2217285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)SMPRequestFunction, dmSMPRequestBody); 2218285242Sachim } 2219285242Sachim return; 2220285242Sachim } 2221285242Sachim else if (status == AGSA_RC_BUSY) 2222285242Sachim { 2223285242Sachim onePortContext->discovery.pendingSMP++; 2224285242Sachim// dmSMPRequestBody->retries++; 2225285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || 2226285242Sachim SMPRequestFunction == SMP_DISCOVER || 2227285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2228285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2229285242Sachim ) 2230285242Sachim { 2231285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 2232285242Sachim } 2233285242Sachim else if (SMPRequestFunction == SMP_PHY_CONTROL) 2234285242Sachim { 2235285242Sachim /* For taskmanagement SMP, let's fail task management failure */ 2236285242Sachim dmPhyControlFailureRespRcvd( 2237285242Sachim dmRoot, 2238285242Sachim agRoot, 2239285242Sachim oneDeviceData, 2240285242Sachim agNULL, 2241285242Sachim agNULL 2242285242Sachim ); 2243285242Sachim } 2244285242Sachim else 2245285242Sachim { 2246285242Sachim } 2247285242Sachim } 2248285242Sachim else /* AGSA_RC_FAILURE */ 2249285242Sachim { 2250285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || 2251285242Sachim SMPRequestFunction == SMP_DISCOVER || 2252285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2253285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2254285242Sachim ) 2255285242Sachim { 2256285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2257285242Sachim } 2258285242Sachim else if (SMPRequestFunction == SMP_PHY_CONTROL) 2259285242Sachim { 2260285242Sachim /* task management failure */ 2261285242Sachim dmPhyControlFailureRespRcvd( 2262285242Sachim dmRoot, 2263285242Sachim agRoot, 2264285242Sachim oneDeviceData, 2265285242Sachim agNULL, 2266285242Sachim agNULL 2267285242Sachim ); 2268285242Sachim } 2269285242Sachim else 2270285242Sachim { 2271285242Sachim } 2272285242Sachim } 2273285242Sachim } 2274285242Sachim return; 2275285242Sachim} 2276285242Sachim/* smp completion */ 2277285242SachimosGLOBAL void 2278285242SachimdmSMPCompleted( 2279285242Sachim agsaRoot_t *agRoot, 2280285242Sachim agsaIORequest_t *agIORequest, 2281285242Sachim bit32 agIOStatus, 2282285242Sachim bit32 agIOInfoLen, 2283285242Sachim agsaFrameHandle_t agFrameHandle 2284285242Sachim ) 2285285242Sachim{ 2286285242Sachim dmIntRoot_t *dmIntRoot = agNULL; 2287285242Sachim dmIntContext_t *dmAllShared = agNULL; 2288285242Sachim dmSMPRequestBody_t *dmSMPRequestBody = agNULL; 2289285242Sachim agsaSMPFrame_t *agSMPFrame; 2290285242Sachim dmRoot_t *dmRoot = agNULL; 2291285242Sachim dmIntPortContext_t *onePortContext = agNULL; 2292285242Sachim dmIntPortContext_t *oldonePortContext; 2293285242Sachim dmExpander_t *oneExpander = agNULL; 2294285242Sachim dmDeviceData_t *oneDeviceData; 2295285242Sachim agsaDevHandle_t *agDevHandle = agNULL; 2296285242Sachim agsaSASRequestBody_t *agSASRequestBody; 2297285242Sachim bit8 smpHeader[4]; 2298285242Sachim bit8 SMPRequestFunction; 2299285242Sachim dmSMPFrameHeader_t *dmResponseSMPFrameHeader; 2300285242Sachim dmSMPFrameHeader_t *dmSMPFrameHeader; 2301285242Sachim bit8 *dmSMPPayload; 2302285242Sachim smpReqPhyControl_t *smpPhyControlReq; 2303285242Sachim smpReqPhyControl2_t *smpPhyControl2Req; 2304285242Sachim#ifndef DIRECT_SMP 2305285242Sachim dmSMPRequestBody_t *dmSMPResponseBody = agNULL; 2306285242Sachim dmSMPFrameHeader_t *dmRequestSMPFrameHeader; 2307285242Sachim bit8 smpRequestHeader[4]; 2308285242Sachim#endif 2309285242Sachim bit32 status; 2310285242Sachim bit32 ConnRate = SAS_CONNECTION_RATE_12_0G; 2311285242Sachim agsaContext_t *agContext = agNULL; 2312285242Sachim 2313285242Sachim DM_DBG3(("dmSMPCompleted: start\n")); 2314285242Sachim 2315285242Sachim dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData; 2316285242Sachim 2317285242Sachim dmRoot = dmSMPRequestBody->dmRoot; 2318285242Sachim dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 2319285242Sachim dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 2320285242Sachim 2321285242Sachim oneDeviceData = dmSMPRequestBody->dmDevice; 2322285242Sachim agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody); 2323285242Sachim agSMPFrame = &(agSASRequestBody->smpFrame); 2324285242Sachim 2325285242Sachim if (oneDeviceData->valid == agFALSE && 2326285242Sachim oneDeviceData->valid2 == agFALSE && 2327285242Sachim oneDeviceData->dmPortContext == agNULL && 2328285242Sachim dmSMPRequestBody->dmPortContext->valid == agFALSE 2329285242Sachim ) 2330285242Sachim { 2331285242Sachim DM_DBG3(("dmSMPCompleted: port has been destroyed\n")); 2332285242Sachim /* all device, port information have been reset 2333285242Sachim just put smp to freeList 2334285242Sachim */ 2335285242Sachim /* SMP request */ 2336285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2337285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2338285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2339285242Sachim 2340285242Sachim#ifndef DIRECT_SMP 2341285242Sachim /* SMP response */ 2342285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2343285242Sachim if (dmSMPResponseBody == agNULL) 2344285242Sachim { 2345285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2346285242Sachim return; 2347285242Sachim } 2348285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2349285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2350285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2351285242Sachim#endif 2352285242Sachim return; 2353285242Sachim } 2354285242Sachim 2355285242Sachim onePortContext = oneDeviceData->dmPortContext; 2356285242Sachim oneExpander = oneDeviceData->dmExpander; 2357285242Sachim agDevHandle = oneExpander->agDevHandle; 2358285242Sachim 2359285242Sachim 2360285242Sachim#ifdef DIRECT_SMP 2361285242Sachim SMPRequestFunction = dmSMPRequestBody->smpPayload[1]; 2362285242Sachim#else 2363285242Sachim saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpRequestHeader, 4); 2364285242Sachim dmRequestSMPFrameHeader = (dmSMPFrameHeader_t *)smpRequestHeader; 2365285242Sachim SMPRequestFunction = dmRequestSMPFrameHeader->smpFunction; 2366285242Sachim#endif 2367285242Sachim 2368285242Sachim#ifdef NOT_IN_USE 2369285242Sachim /* for debugging; dump SMP request payload */ 2370285242Sachim dmhexdump("smp payload", 2371285242Sachim (bit8 *)agSASRequestBody->smpFrame.outFrameBuf, 2372285242Sachim agSASRequestBody->smpFrame.outFrameLen 2373285242Sachim ); 2374285242Sachim dmhexdump("smp payload new", 2375285242Sachim (bit8 *)dmSMPRequestBody->smpPayload, 2376285242Sachim agSASRequestBody->smpFrame.outFrameLen 2377285242Sachim ); 2378285242Sachim#endif 2379285242Sachim 2380285242Sachim /* sanity check */ 2381285242Sachim if (onePortContext != agNULL) 2382285242Sachim { 2383285242Sachim DM_DBG5(("dmSMPCompleted: pid %d\n", onePortContext->id)); 2384285242Sachim } 2385285242Sachim else 2386285242Sachim { 2387285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, onePortContext is NULL!!!\n")); 2388285242Sachim /* SMP request */ 2389285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2390285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2391285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2392285242Sachim 2393285242Sachim#ifndef DIRECT_SMP 2394285242Sachim /* SMP response */ 2395285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2396285242Sachim if (dmSMPResponseBody == agNULL) 2397285242Sachim { 2398285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2399285242Sachim return; 2400285242Sachim } 2401285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2402285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2403285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2404285242Sachim#endif 2405285242Sachim return; 2406285242Sachim } 2407285242Sachim 2408285242Sachim oldonePortContext = dmSMPRequestBody->dmPortContext; 2409285242Sachim if (oldonePortContext != agNULL) 2410285242Sachim { 2411285242Sachim DM_DBG5(("dmSMPCompleted: old pid %d\n", oldonePortContext->id)); 2412285242Sachim } 2413285242Sachim else 2414285242Sachim { 2415285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, oldonePortContext is NULL!!!\n")); 2416285242Sachim /* SMP request */ 2417285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2418285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2419285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2420285242Sachim 2421285242Sachim#ifndef DIRECT_SMP 2422285242Sachim /* SMP response */ 2423285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2424285242Sachim if (dmSMPResponseBody == agNULL) 2425285242Sachim { 2426285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2427285242Sachim return; 2428285242Sachim } 2429285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2430285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2431285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2432285242Sachim#endif 2433285242Sachim return; 2434285242Sachim } 2435285242Sachim 2436285242Sachim /* decrement the number of pending SMP */ 2437285242Sachim onePortContext->discovery.pendingSMP--; 2438285242Sachim 2439285242Sachim 2440285242Sachim /* for port invalid case; 2441285242Sachim full discovery -> full discovery; incremental discovery -> full discovery 2442285242Sachim */ 2443285242Sachim if (onePortContext != oldonePortContext) 2444285242Sachim { 2445285242Sachim DM_DBG1(("dmSMPCompleted: portcontext has changed!!!\n")); 2446285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 2447285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2448285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2449285242Sachim ) 2450285242Sachim { 2451285242Sachim /* stop SMP timer */ 2452285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2453285242Sachim if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2454285242Sachim { 2455285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2456285242Sachim dmKillTimer( 2457285242Sachim dmRoot, 2458285242Sachim &(onePortContext->discovery.DiscoverySMPTimer) 2459285242Sachim ); 2460285242Sachim } 2461285242Sachim else 2462285242Sachim { 2463285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2464285242Sachim } 2465285242Sachim 2466285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2467285242Sachim if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2468285242Sachim { 2469285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2470285242Sachim dmKillTimer( 2471285242Sachim dmRoot, 2472285242Sachim &(oldonePortContext->discovery.DiscoverySMPTimer) 2473285242Sachim ); 2474285242Sachim } 2475285242Sachim else 2476285242Sachim { 2477285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2478285242Sachim } 2479285242Sachim } 2480285242Sachim /* clean up expanders data strucures; move to free exp when device is cleaned */ 2481285242Sachim dmCleanAllExp(dmRoot, oldonePortContext); 2482285242Sachim /* remove devices */ 2483285242Sachim dmInternalRemovals(dmRoot, oldonePortContext); 2484285242Sachim 2485285242Sachim /* SMP request */ 2486285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2487285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2488285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2489285242Sachim 2490285242Sachim#ifndef DIRECT_SMP 2491285242Sachim /* SMP response */ 2492285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2493285242Sachim if (dmSMPResponseBody == agNULL) 2494285242Sachim { 2495285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2496285242Sachim return; 2497285242Sachim } 2498285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2499285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2500285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2501285242Sachim#endif 2502285242Sachim 2503285242Sachim 2504285242Sachim return; 2505285242Sachim } 2506285242Sachim 2507285242Sachim if (onePortContext->valid == agFALSE || 2508285242Sachim onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 2509285242Sachim onePortContext->discovery.status == DISCOVERY_SAS_DONE || 2510285242Sachim onePortContext->DiscoveryAbortInProgress == agTRUE 2511285242Sachim ) 2512285242Sachim { 2513285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 2514285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2515285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2516285242Sachim ) 2517285242Sachim { 2518285242Sachim /* stop SMP timer */ 2519285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2520285242Sachim if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2521285242Sachim { 2522285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2523285242Sachim dmKillTimer( 2524285242Sachim dmRoot, 2525285242Sachim &(onePortContext->discovery.DiscoverySMPTimer) 2526285242Sachim ); 2527285242Sachim } 2528285242Sachim else 2529285242Sachim { 2530285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2531285242Sachim } 2532285242Sachim 2533285242Sachim 2534285242Sachim 2535285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2536285242Sachim if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2537285242Sachim { 2538285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2539285242Sachim dmKillTimer( 2540285242Sachim dmRoot, 2541285242Sachim &(oldonePortContext->discovery.DiscoverySMPTimer) 2542285242Sachim ); 2543285242Sachim } 2544285242Sachim else 2545285242Sachim { 2546285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2547285242Sachim } 2548285242Sachim } 2549285242Sachim 2550285242Sachim /* SMP request */ 2551285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2552285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2553285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2554285242Sachim 2555285242Sachim#ifndef DIRECT_SMP 2556285242Sachim /* SMP response */ 2557285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2558285242Sachim if (dmSMPResponseBody == agNULL) 2559285242Sachim { 2560285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2561285242Sachim return; 2562285242Sachim } 2563285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2564285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2565285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2566285242Sachim#endif 2567285242Sachim 2568285242Sachim if (onePortContext->discovery.pendingSMP == 0) 2569285242Sachim { 2570285242Sachim DM_DBG1(("dmSMPCompleted: aborting discovery\n")); 2571285242Sachim if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED || 2572285242Sachim onePortContext->discovery.status == DISCOVERY_SAS_DONE || 2573285242Sachim onePortContext->DiscoveryAbortInProgress == agTRUE 2574285242Sachim ) 2575285242Sachim { 2576285242Sachim onePortContext->DiscoveryAbortInProgress = agFALSE; 2577285242Sachim onePortContext->DiscoveryState = DM_DSTATE_COMPLETED; 2578285242Sachim onePortContext->discovery.status = DISCOVERY_SAS_DONE; 2579285242Sachim dmCleanAllExp(dmRoot, onePortContext); 2580285242Sachim if ( onePortContext->DiscoveryAbortInProgress == agTRUE) 2581285242Sachim { 2582285242Sachim tddmDiscoverCB( 2583285242Sachim dmRoot, 2584285242Sachim onePortContext->dmPortContext, 2585285242Sachim dmDiscAborted 2586285242Sachim ); 2587285242Sachim } 2588285242Sachim } 2589285242Sachim } 2590285242Sachim else 2591285242Sachim { 2592285242Sachim DM_DBG3(("dmSMPCompleted: not yet abort; non zero pendingSMP %d\n", onePortContext->discovery.pendingSMP)); 2593285242Sachim } 2594285242Sachim return; 2595285242Sachim } 2596285242Sachim 2597285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 2598285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2599285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2600285242Sachim ) 2601285242Sachim { 2602285242Sachim /* stop SMP timer */ 2603285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2604285242Sachim if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2605285242Sachim { 2606285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2607285242Sachim dmKillTimer( 2608285242Sachim dmRoot, 2609285242Sachim &(onePortContext->discovery.DiscoverySMPTimer) 2610285242Sachim ); 2611285242Sachim } 2612285242Sachim else 2613285242Sachim { 2614285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2615285242Sachim } 2616285242Sachim 2617285242Sachim 2618285242Sachim tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK); 2619285242Sachim if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) 2620285242Sachim { 2621285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2622285242Sachim dmKillTimer( 2623285242Sachim dmRoot, 2624285242Sachim &(oldonePortContext->discovery.DiscoverySMPTimer) 2625285242Sachim ); 2626285242Sachim } 2627285242Sachim else 2628285242Sachim { 2629285242Sachim tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK); 2630285242Sachim } 2631285242Sachim } 2632285242Sachim 2633285242Sachim if (oneExpander->SAS2 == 0) 2634285242Sachim { 2635285242Sachim DM_DBG3(("dmSMPCompleted: SAS 1.1\n")); 2636285242Sachim if (agIOStatus == OSSA_IO_SUCCESS) 2637285242Sachim { 2638285242Sachim //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen); 2639285242Sachim /* parsing SMP payload */ 2640285242Sachim#ifdef DIRECT_SMP 2641285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 2642285242Sachim#else 2643285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2644285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4); 2645285242Sachim#endif 2646285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 2647285242Sachim 2648285242Sachim /* SMP function dependent payload */ 2649285242Sachim switch (dmResponseSMPFrameHeader->smpFunction) 2650285242Sachim { 2651285242Sachim case SMP_REPORT_GENERAL: 2652285242Sachim DM_DBG3(("dmSMPCompleted: report general\n")); 2653285242Sachim if (agIOInfoLen != sizeof(smpRespReportGeneral_t) + 4 && 2654285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2655285242Sachim { 2656285242Sachim DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportGeneral_t) + 4)); 2657285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2658285242Sachim 2659285242Sachim /* SMP request */ 2660285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2661285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2662285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2663285242Sachim 2664285242Sachim#ifndef DIRECT_SMP 2665285242Sachim /* SMP response */ 2666285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2667285242Sachim if (dmSMPResponseBody == agNULL) 2668285242Sachim { 2669285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2670285242Sachim return; 2671285242Sachim } 2672285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2673285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2674285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2675285242Sachim#endif 2676285242Sachim return; 2677285242Sachim } 2678285242Sachim /* start here */ 2679285242Sachim dmReportGeneralRespRcvd( 2680285242Sachim dmRoot, 2681285242Sachim agRoot, 2682285242Sachim agIORequest, 2683285242Sachim oneDeviceData, 2684285242Sachim dmResponseSMPFrameHeader, 2685285242Sachim agFrameHandle 2686285242Sachim ); 2687285242Sachim break; 2688285242Sachim case SMP_DISCOVER: 2689285242Sachim DM_DBG3(("dmSMPCompleted: discover\n")); 2690285242Sachim if (agIOInfoLen != sizeof(smpRespDiscover_t) + 4 && 2691285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2692285242Sachim { 2693285242Sachim DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespDiscover_t) + 4)); 2694285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2695285242Sachim /* SMP request */ 2696285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2697285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2698285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2699285242Sachim 2700285242Sachim#ifndef DIRECT_SMP 2701285242Sachim /* SMP response */ 2702285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2703285242Sachim if (dmSMPResponseBody == agNULL) 2704285242Sachim { 2705285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2706285242Sachim return; 2707285242Sachim } 2708285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2709285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2710285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2711285242Sachim#endif 2712285242Sachim return; 2713285242Sachim } 2714285242Sachim dmDiscoverRespRcvd( 2715285242Sachim dmRoot, 2716285242Sachim agRoot, 2717285242Sachim agIORequest, 2718285242Sachim oneDeviceData, 2719285242Sachim dmResponseSMPFrameHeader, 2720285242Sachim agFrameHandle 2721285242Sachim ); 2722285242Sachim break; 2723285242Sachim case SMP_REPORT_PHY_SATA: 2724285242Sachim DM_DBG3(("dmSMPCompleted: report phy sata\n")); 2725285242Sachim if (agIOInfoLen != sizeof(smpRespReportPhySata_t) + 4 && 2726285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2727285242Sachim { 2728285242Sachim DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportPhySata_t) + 4)); 2729285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2730285242Sachim /* SMP request */ 2731285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2732285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2733285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2734285242Sachim 2735285242Sachim#ifndef DIRECT_SMP 2736285242Sachim /* SMP response */ 2737285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2738285242Sachim if (dmSMPResponseBody == agNULL) 2739285242Sachim { 2740285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2741285242Sachim return; 2742285242Sachim } 2743285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2744285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2745285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2746285242Sachim#endif 2747285242Sachim return; 2748285242Sachim } 2749285242Sachim dmReportPhySataRcvd( 2750285242Sachim dmRoot, 2751285242Sachim agRoot, 2752285242Sachim agIORequest, 2753285242Sachim oneDeviceData, 2754285242Sachim dmResponseSMPFrameHeader, 2755285242Sachim agFrameHandle 2756285242Sachim ); 2757285242Sachim break; 2758285242Sachim case SMP_CONFIGURE_ROUTING_INFORMATION: 2759285242Sachim DM_DBG3(("dmSMPCompleted: configure routing information\n")); 2760285242Sachim if (agIOInfoLen != 4 && 2761285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) 2762285242Sachim { 2763285242Sachim DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); 2764285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2765285242Sachim /* SMP request */ 2766285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2767285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2768285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2769285242Sachim 2770285242Sachim#ifndef DIRECT_SMP 2771285242Sachim /* SMP response */ 2772285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2773285242Sachim if (dmSMPResponseBody == agNULL) 2774285242Sachim { 2775285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2776285242Sachim return; 2777285242Sachim } 2778285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2779285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2780285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2781285242Sachim#endif 2782285242Sachim return; 2783285242Sachim } 2784285242Sachim dmConfigRoutingInfoRespRcvd( 2785285242Sachim dmRoot, 2786285242Sachim agRoot, 2787285242Sachim agIORequest, 2788285242Sachim oneDeviceData, 2789285242Sachim dmResponseSMPFrameHeader, 2790285242Sachim agFrameHandle 2791285242Sachim ); 2792285242Sachim 2793285242Sachim break; 2794285242Sachim case SMP_PHY_CONTROL: 2795285242Sachim DM_DBG3(("dmSMPCompleted: phy control\n")); 2796285242Sachim if (agIOInfoLen != 4 && 2797285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */ 2798285242Sachim { 2799285242Sachim DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); 2800285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2801285242Sachim 2802285242Sachim /* SMP request */ 2803285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2804285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 2805285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2806285242Sachim 2807285242Sachim#ifndef DIRECT_SMP 2808285242Sachim /* SMP response */ 2809285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 2810285242Sachim if (dmSMPResponseBody == agNULL) 2811285242Sachim { 2812285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 2813285242Sachim return; 2814285242Sachim } 2815285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 2816285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 2817285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 2818285242Sachim#endif 2819285242Sachim return; 2820285242Sachim } 2821285242Sachim dmPhyControlRespRcvd( 2822285242Sachim dmRoot, 2823285242Sachim agRoot, 2824285242Sachim agIORequest, 2825285242Sachim oneDeviceData, 2826285242Sachim dmResponseSMPFrameHeader, 2827285242Sachim agFrameHandle 2828285242Sachim ); 2829285242Sachim break; 2830285242Sachim case SMP_REPORT_ROUTING_INFORMATION: /* fall through */ 2831285242Sachim case SMP_REPORT_PHY_ERROR_LOG: /* fall through */ 2832285242Sachim case SMP_PHY_TEST_FUNCTION: /* fall through */ 2833285242Sachim case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */ 2834285242Sachim case SMP_READ_GPIO_REGISTER: /* fall through */ 2835285242Sachim case SMP_WRITE_GPIO_REGISTER: /* fall through */ 2836285242Sachim default: 2837285242Sachim DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunction)); 2838285242Sachim DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x !!!\n", dmResponseSMPFrameHeader->smpFrameType)); 2839285242Sachim DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunctionResult)); 2840285242Sachim DM_DBG1(("dmSMPCompleted: smpReserved 0x%x !!!\n", dmResponseSMPFrameHeader->smpReserved)); 2841285242Sachim dmhexdump("dmSMPCompleted: SMP payload !!!", (bit8 *)agFrameHandle, agIOInfoLen); 2842285242Sachim break; 2843285242Sachim } /* switch */ 2844285242Sachim } /* OSSA_IO_SUCCESS */ 2845285242Sachim else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH) 2846285242Sachim { 2847285242Sachim /* no retry this case */ 2848285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus)); 2849285242Sachim } 2850285242Sachim else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE) 2851285242Sachim { 2852285242Sachim DM_DBG3(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n")); 2853285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 2854285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 2855285242Sachim 2856285242Sachim status = saSMPStart( 2857285242Sachim agRoot, 2858285242Sachim agIORequest, 2859285242Sachim 0, 2860285242Sachim agDevHandle, 2861285242Sachim AGSA_SMP_INIT_REQ, 2862285242Sachim agSASRequestBody, 2863285242Sachim &dmsaSMPCompleted 2864285242Sachim ); 2865285242Sachim 2866285242Sachim if (status == AGSA_RC_SUCCESS) 2867285242Sachim { 2868285242Sachim /* increment the number of pending SMP */ 2869285242Sachim onePortContext->discovery.pendingSMP++; 2870285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 2871285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2872285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2873285242Sachim ) 2874285242Sachim { 2875285242Sachim /* start discovery-related SMP timer */ 2876285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody); 2877285242Sachim } 2878285242Sachim return; 2879285242Sachim } 2880285242Sachim else if (status == AGSA_RC_BUSY) 2881285242Sachim { 2882285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 2883285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 2884285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 2885285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2886285242Sachim ) 2887285242Sachim { 2888285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 2889285242Sachim } 2890285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 2891285242Sachim { 2892285242Sachim /* For taskmanagement SMP, let's fail task management failure */ 2893285242Sachim dmPhyControlFailureRespRcvd( 2894285242Sachim dmRoot, 2895285242Sachim agRoot, 2896285242Sachim oneDeviceData, 2897285242Sachim dmResponseSMPFrameHeader, 2898285242Sachim agFrameHandle 2899285242Sachim ); 2900285242Sachim } 2901285242Sachim else 2902285242Sachim { 2903285242Sachim } 2904285242Sachim } 2905285242Sachim else /* AGSA_RC_FAILURE */ 2906285242Sachim { 2907285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 2908285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 2909285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 2910285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2911285242Sachim ) 2912285242Sachim { 2913285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2914285242Sachim } 2915285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 2916285242Sachim { 2917285242Sachim /* task management failure */ 2918285242Sachim dmPhyControlFailureRespRcvd( 2919285242Sachim dmRoot, 2920285242Sachim agRoot, 2921285242Sachim oneDeviceData, 2922285242Sachim dmResponseSMPFrameHeader, 2923285242Sachim agFrameHandle 2924285242Sachim ); 2925285242Sachim } 2926285242Sachim else 2927285242Sachim { 2928285242Sachim } 2929285242Sachim } 2930285242Sachim } /* OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE*/ 2931285242Sachim else 2932285242Sachim { 2933285242Sachim if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 2934285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED || 2935285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO || 2936285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST || 2937285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE || 2938285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED || 2939285242Sachim agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ) 2940285242Sachim { 2941285242Sachim DM_DBG1(("dmSMPCompleted: setting back to operational\n")); 2942285242Sachim saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL); 2943285242Sachim } 2944285242Sachim if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust) 2945285242Sachim { 2946285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); 2947285242Sachim DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction)); 2948285242Sachim ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); 2949285242Sachim if (ConnRate == SAS_CONNECTION_RATE_1_5G) 2950285242Sachim { 2951285242Sachim /* no retry; failure ??? */ 2952285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || 2953285242Sachim SMPRequestFunction == SMP_DISCOVER || 2954285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 2955285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 2956285242Sachim ) 2957285242Sachim { 2958285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 2959285242Sachim } 2960285242Sachim else if (SMPRequestFunction == SMP_PHY_CONTROL) 2961285242Sachim { 2962285242Sachim /* task management failure */ 2963285242Sachim dmPhyControlFailureRespRcvd( 2964285242Sachim dmRoot, 2965285242Sachim agRoot, 2966285242Sachim oneDeviceData, 2967285242Sachim agNULL, 2968285242Sachim agNULL 2969285242Sachim ); 2970285242Sachim } 2971285242Sachim else 2972285242Sachim { 2973285242Sachim } 2974285242Sachim } 2975285242Sachim else 2976285242Sachim { 2977285242Sachim ConnRate = ConnRate - 1; 2978285242Sachim } 2979285242Sachim agContext = &(dmSMPRequestBody->agContext); 2980285242Sachim agContext->osData = agIORequest; 2981285242Sachim saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB); 2982285242Sachim } 2983285242Sachim else 2984285242Sachim { 2985285242Sachim if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */ 2986285242Sachim { 2987285242Sachim /* retry the SMP again */ 2988285242Sachim DM_DBG1(("dmSMPCompleted: failed, but retries %d agIOStatus 0x%x %d agIOInfoLen %d !!!\n", 2989285242Sachim dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen)); 2990285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 2991285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 2992285242Sachim status = saSMPStart( 2993285242Sachim agRoot, 2994285242Sachim agIORequest, 2995285242Sachim 0, 2996285242Sachim agDevHandle, 2997285242Sachim AGSA_SMP_INIT_REQ, 2998285242Sachim agSASRequestBody, 2999285242Sachim &dmsaSMPCompleted 3000285242Sachim ); 3001285242Sachim if (status == AGSA_RC_SUCCESS) 3002285242Sachim { 3003285242Sachim /* increment the number of pending SMP */ 3004285242Sachim onePortContext->discovery.pendingSMP++; 3005285242Sachim dmSMPRequestBody->retries++; 3006285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 3007285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 3008285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3009285242Sachim ) 3010285242Sachim { 3011285242Sachim /* start discovery-related SMP timer */ 3012285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody); 3013285242Sachim } 3014285242Sachim return; 3015285242Sachim } 3016285242Sachim else if (status == AGSA_RC_BUSY) 3017285242Sachim { 3018285242Sachim onePortContext->discovery.pendingSMP++; 3019285242Sachim dmSMPRequestBody->retries++; 3020285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3021285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3022285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3023285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3024285242Sachim ) 3025285242Sachim { 3026285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 3027285242Sachim return; 3028285242Sachim } 3029285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3030285242Sachim { 3031285242Sachim /* For taskmanagement SMP, let's fail task management failure */ 3032285242Sachim dmPhyControlFailureRespRcvd( 3033285242Sachim dmRoot, 3034285242Sachim agRoot, 3035285242Sachim oneDeviceData, 3036285242Sachim dmResponseSMPFrameHeader, 3037285242Sachim agFrameHandle 3038285242Sachim ); 3039285242Sachim } 3040285242Sachim else 3041285242Sachim { 3042285242Sachim } 3043285242Sachim } 3044285242Sachim else /* AGSA_RC_FAILURE */ 3045285242Sachim { 3046285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3047285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3048285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3049285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3050285242Sachim ) 3051285242Sachim { 3052285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3053285242Sachim } 3054285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3055285242Sachim { 3056285242Sachim /* task management failure */ 3057285242Sachim dmPhyControlFailureRespRcvd( 3058285242Sachim dmRoot, 3059285242Sachim agRoot, 3060285242Sachim oneDeviceData, 3061285242Sachim dmResponseSMPFrameHeader, 3062285242Sachim agFrameHandle 3063285242Sachim ); 3064285242Sachim } 3065285242Sachim else 3066285242Sachim { 3067285242Sachim } 3068285242Sachim } 3069285242Sachim } 3070285242Sachim else 3071285242Sachim { 3072285242Sachim dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf; 3073285242Sachim dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4; 3074285242Sachim DM_DBG1(("dmSMPCompleted: failed. no more retry. agIOStatus 0x%x %d !!!\n", agIOStatus, agIOStatus)); 3075285242Sachim if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL) 3076285242Sachim { 3077285242Sachim DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_NON_OPERATIONAL!!!\n")); 3078285242Sachim } 3079285242Sachim if (agIOStatus == OSSA_IO_DS_IN_RECOVERY) 3080285242Sachim { 3081285242Sachim DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_IN_RECOVERY!!!\n")); 3082285242Sachim } 3083285242Sachim if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3084285242Sachim dmSMPFrameHeader->smpFunction == SMP_DISCOVER || 3085285242Sachim dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3086285242Sachim dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3087285242Sachim ) 3088285242Sachim { 3089285242Sachim /* discovery failure */ 3090285242Sachim DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction)); 3091285242Sachim DM_DBG1(("dmSMPCompleted: discover done with error\n")); 3092285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3093285242Sachim } 3094285242Sachim else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3095285242Sachim { 3096285242Sachim DM_DBG3(("dmSMPCompleted: SMP_PHY_CONTROL\n")); 3097285242Sachim smpPhyControlReq = (smpReqPhyControl_t *)dmSMPPayload; 3098285242Sachim if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION) 3099285242Sachim { 3100285242Sachim DM_DBG3(("dmSMPCompleted: discover done with error\n")); 3101285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3102285242Sachim } 3103285242Sachim else 3104285242Sachim { 3105285242Sachim DM_DBG3(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControlReq->phyOperation)); 3106285242Sachim } 3107285242Sachim } /* SMP_PHY_CONTROL */ 3108285242Sachim else 3109285242Sachim { 3110285242Sachim DM_DBG3(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction)); 3111285242Sachim } 3112285242Sachim } /* else */ 3113285242Sachim } /* for RateAdjust */ 3114285242Sachim } /* outer else */ 3115285242Sachim } /* SAS 1.1 */ 3116285242Sachim /************************************ SAS 2 ***********************************************/ 3117285242Sachim else 3118285242Sachim { 3119285242Sachim DM_DBG2(("dmSMPCompleted: SAS 2\n")); 3120285242Sachim if (agIOStatus == OSSA_IO_SUCCESS) 3121285242Sachim { 3122285242Sachim //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen); 3123285242Sachim /* parsing SMP payload */ 3124285242Sachim#ifdef DIRECT_SMP 3125285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 3126285242Sachim#else 3127285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3128285242Sachim saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4); 3129285242Sachim#endif 3130285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 3131285242Sachim 3132285242Sachim /* SMP function dependent payload */ 3133285242Sachim switch (dmResponseSMPFrameHeader->smpFunction) 3134285242Sachim { 3135285242Sachim case SMP_REPORT_GENERAL: 3136285242Sachim DM_DBG2(("dmSMPCompleted: report general\n")); 3137285242Sachim if ((agIOInfoLen != sizeof(smpRespReportGeneral2_t) + 4) && 3138285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED 3139285242Sachim ) 3140285242Sachim { 3141285242Sachim DM_DBG1(("dmSMPCompleted: report general mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportGeneral2_t) + 4)); 3142285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3143285242Sachim 3144285242Sachim /* SMP request */ 3145285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3146285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3147285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3148285242Sachim 3149285242Sachim#ifndef DIRECT_SMP 3150285242Sachim /* SMP response */ 3151285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3152285242Sachim if (dmSMPResponseBody == agNULL) 3153285242Sachim { 3154285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3155285242Sachim return; 3156285242Sachim } 3157285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3158285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3159285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3160285242Sachim#endif 3161285242Sachim 3162285242Sachim return; 3163285242Sachim } 3164285242Sachim 3165285242Sachim dmReportGeneral2RespRcvd( 3166285242Sachim dmRoot, 3167285242Sachim agRoot, 3168285242Sachim agIORequest, 3169285242Sachim oneDeviceData, 3170285242Sachim dmResponseSMPFrameHeader, 3171285242Sachim agFrameHandle 3172285242Sachim ); 3173285242Sachim break; 3174285242Sachim case SMP_DISCOVER: 3175285242Sachim DM_DBG2(("dmSMPCompleted: discover\n")); 3176285242Sachim if ((agIOInfoLen != sizeof(smpRespDiscover2_t) + 4) && 3177285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED 3178285242Sachim ) 3179285242Sachim { 3180285242Sachim DM_DBG1(("dmSMPCompleted: discover mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespDiscover2_t) + 4)); 3181285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3182285242Sachim 3183285242Sachim /* SMP request */ 3184285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3185285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3186285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3187285242Sachim 3188285242Sachim#ifndef DIRECT_SMP 3189285242Sachim /* SMP response */ 3190285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3191285242Sachim if (dmSMPResponseBody == agNULL) 3192285242Sachim { 3193285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3194285242Sachim return; 3195285242Sachim } 3196285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3197285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3198285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3199285242Sachim#endif 3200285242Sachim 3201285242Sachim return; 3202285242Sachim } 3203285242Sachim dmDiscover2RespRcvd( 3204285242Sachim dmRoot, 3205285242Sachim agRoot, 3206285242Sachim agIORequest, 3207285242Sachim oneDeviceData, 3208285242Sachim dmResponseSMPFrameHeader, 3209285242Sachim agFrameHandle 3210285242Sachim ); 3211285242Sachim break; 3212285242Sachim case SMP_REPORT_PHY_SATA: 3213285242Sachim DM_DBG2(("dmSMPCompleted: report phy sata\n")); 3214285242Sachim if ((agIOInfoLen != sizeof(smpRespReportPhySata2_t) + 4) && 3215285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED 3216285242Sachim ) 3217285242Sachim { 3218285242Sachim DM_DBG1(("dmSMPCompleted: report phy sata mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportPhySata2_t) + 4)); 3219285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3220285242Sachim 3221285242Sachim /* SMP request */ 3222285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3223285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3224285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3225285242Sachim 3226285242Sachim#ifndef DIRECT_SMP 3227285242Sachim /* SMP response */ 3228285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3229285242Sachim if (dmSMPResponseBody == agNULL) 3230285242Sachim { 3231285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3232285242Sachim return; 3233285242Sachim } 3234285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3235285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3236285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3237285242Sachim#endif 3238285242Sachim 3239285242Sachim return; 3240285242Sachim } 3241285242Sachim dmReportPhySata2Rcvd( 3242285242Sachim dmRoot, 3243285242Sachim agRoot, 3244285242Sachim agIORequest, 3245285242Sachim oneDeviceData, 3246285242Sachim dmResponseSMPFrameHeader, 3247285242Sachim agFrameHandle 3248285242Sachim ); 3249285242Sachim break; 3250285242Sachim case SMP_CONFIGURE_ROUTING_INFORMATION: 3251285242Sachim DM_DBG2(("dmSMPCompleted: configure routing information\n")); 3252285242Sachim if (agIOInfoLen != 4 && 3253285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED 3254285242Sachim ) 3255285242Sachim { 3256285242Sachim DM_DBG1(("dmSMPCompleted: configure routing information mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); 3257285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3258285242Sachim 3259285242Sachim /* SMP request */ 3260285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3261285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3262285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3263285242Sachim 3264285242Sachim#ifndef DIRECT_SMP 3265285242Sachim /* SMP response */ 3266285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3267285242Sachim if (dmSMPResponseBody == agNULL) 3268285242Sachim { 3269285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3270285242Sachim return; 3271285242Sachim } 3272285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3273285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3274285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3275285242Sachim#endif 3276285242Sachim 3277285242Sachim return; 3278285242Sachim } 3279285242Sachim dmConfigRoutingInfo2RespRcvd( 3280285242Sachim dmRoot, 3281285242Sachim agRoot, 3282285242Sachim agIORequest, 3283285242Sachim oneDeviceData, 3284285242Sachim dmResponseSMPFrameHeader, 3285285242Sachim agFrameHandle 3286285242Sachim ); 3287285242Sachim 3288285242Sachim break; 3289285242Sachim case SMP_PHY_CONTROL: 3290285242Sachim DM_DBG2(("dmSMPCompleted: phy control\n")); 3291285242Sachim if (agIOInfoLen != 4 && 3292285242Sachim dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED 3293285242Sachim ) /*zero length is expected */ 3294285242Sachim { 3295285242Sachim DM_DBG1(("dmSMPCompleted: phy control mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); 3296285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3297285242Sachim 3298285242Sachim /* SMP request */ 3299285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3300285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3301285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3302285242Sachim 3303285242Sachim#ifndef DIRECT_SMP 3304285242Sachim /* SMP response */ 3305285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3306285242Sachim if (dmSMPResponseBody == agNULL) 3307285242Sachim { 3308285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3309285242Sachim return; 3310285242Sachim } 3311285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3312285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3313285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3314285242Sachim#endif 3315285242Sachim 3316285242Sachim return; 3317285242Sachim } 3318285242Sachim dmPhyControl2RespRcvd( 3319285242Sachim dmRoot, 3320285242Sachim agRoot, 3321285242Sachim agIORequest, 3322285242Sachim oneDeviceData, 3323285242Sachim dmResponseSMPFrameHeader, 3324285242Sachim agFrameHandle 3325285242Sachim ); 3326285242Sachim 3327285242Sachim 3328285242Sachim break; 3329285242Sachim#ifdef NOT_YET 3330285242Sachim case SMP_DISCOVER_LIST: 3331285242Sachim DM_DBG1(("dmSMPCompleted: SMP_DISCOVER_LIST\n")); 3332285242Sachim DM_DBG1(("dmSMPCompleted: agIOInfoLen 0x%x \n", agIOInfoLen)); 3333285242Sachim tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen); 3334285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3335285242Sachim 3336285242Sachim /* SMP request */ 3337285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3338285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3339285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3340285242Sachim 3341285242Sachim#ifndef DIRECT_SMP 3342285242Sachim /* SMP response */ 3343285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3344285242Sachim if (dmSMPResponseBody == agNULL) 3345285242Sachim { 3346285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3347285242Sachim return; 3348285242Sachim } 3349285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3350285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3351285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3352285242Sachim#endif 3353285242Sachim 3354285242Sachim return; 3355285242Sachim break; 3356285242Sachim#endif 3357285242Sachim case SMP_REPORT_ROUTING_INFORMATION: /* fall through */ 3358285242Sachim case SMP_REPORT_PHY_ERROR_LOG: /* fall through */ 3359285242Sachim case SMP_PHY_TEST_FUNCTION: /* fall through */ 3360285242Sachim case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */ 3361285242Sachim case SMP_READ_GPIO_REGISTER: /* fall through */ 3362285242Sachim case SMP_WRITE_GPIO_REGISTER: /* fall through */ 3363285242Sachim default: 3364285242Sachim DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x\n", dmResponseSMPFrameHeader->smpFunction)); 3365285242Sachim DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x\n", dmResponseSMPFrameHeader->smpFrameType)); 3366285242Sachim DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x\n", dmResponseSMPFrameHeader->smpFunctionResult)); 3367285242Sachim DM_DBG1(("dmSMPCompleted: smpReserved 0x%x\n", dmResponseSMPFrameHeader->smpReserved)); 3368285242Sachim dmhexdump("dmSMPCompleted: SMP payload", (bit8 *)agFrameHandle, agIOInfoLen); 3369285242Sachim break; 3370285242Sachim } 3371285242Sachim } /* agIOStatus == OSSA_IO_SUCCESS */ 3372285242Sachim else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH) 3373285242Sachim { 3374285242Sachim /* no retry this case */ 3375285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus)); 3376285242Sachim } 3377285242Sachim else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE) 3378285242Sachim { 3379285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n")); 3380285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 3381285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 3382285242Sachim 3383285242Sachim status = saSMPStart( 3384285242Sachim agRoot, 3385285242Sachim agIORequest, 3386285242Sachim 0, 3387285242Sachim agDevHandle, 3388285242Sachim AGSA_SMP_INIT_REQ, 3389285242Sachim agSASRequestBody, 3390285242Sachim &dmsaSMPCompleted 3391285242Sachim ); 3392285242Sachim 3393285242Sachim 3394285242Sachim if (status == AGSA_RC_SUCCESS) 3395285242Sachim { 3396285242Sachim /* increment the number of pending SMP */ 3397285242Sachim onePortContext->discovery.pendingSMP++; 3398285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 3399285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 3400285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3401285242Sachim ) 3402285242Sachim { 3403285242Sachim /* start discovery-related SMP timer */ 3404285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody); 3405285242Sachim } 3406285242Sachim return; 3407285242Sachim } 3408285242Sachim else if (status == AGSA_RC_BUSY) 3409285242Sachim { 3410285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3411285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3412285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3413285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3414285242Sachim ) 3415285242Sachim { 3416285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 3417285242Sachim } 3418285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3419285242Sachim { 3420285242Sachim /* For taskmanagement SMP, let's fail task management failure */ 3421285242Sachim dmPhyControlFailureRespRcvd( 3422285242Sachim dmRoot, 3423285242Sachim agRoot, 3424285242Sachim oneDeviceData, 3425285242Sachim dmResponseSMPFrameHeader, 3426285242Sachim agFrameHandle 3427285242Sachim ); 3428285242Sachim } 3429285242Sachim else 3430285242Sachim { 3431285242Sachim } 3432285242Sachim } 3433285242Sachim else /* AGSA_RC_FAILURE */ 3434285242Sachim { 3435285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3436285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3437285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3438285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3439285242Sachim ) 3440285242Sachim { 3441285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3442285242Sachim } 3443285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3444285242Sachim { 3445285242Sachim /* task management failure */ 3446285242Sachim dmPhyControlFailureRespRcvd( 3447285242Sachim dmRoot, 3448285242Sachim agRoot, 3449285242Sachim oneDeviceData, 3450285242Sachim dmResponseSMPFrameHeader, 3451285242Sachim agFrameHandle 3452285242Sachim ); 3453285242Sachim } 3454285242Sachim else 3455285242Sachim { 3456285242Sachim } 3457285242Sachim } 3458285242Sachim } 3459285242Sachim else if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION) 3460285242Sachim { 3461285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); 3462285242Sachim /* 3463285242Sachim skip to the next expander 3464285242Sachim */ 3465285242Sachim dmHandleZoneViolation( 3466285242Sachim dmRoot, 3467285242Sachim agRoot, 3468285242Sachim agIORequest, 3469285242Sachim oneDeviceData, 3470285242Sachim agNULL, 3471285242Sachim agFrameHandle 3472285242Sachim ); 3473285242Sachim } 3474285242Sachim else 3475285242Sachim { 3476285242Sachim if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 3477285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED || 3478285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO || 3479285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST || 3480285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE || 3481285242Sachim agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED || 3482285242Sachim agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ) 3483285242Sachim { 3484285242Sachim DM_DBG1(("dmSMPCompleted: setting back to operational\n")); 3485285242Sachim saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL); 3486285242Sachim } 3487285242Sachim if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust) 3488285242Sachim { 3489285242Sachim DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); 3490285242Sachim DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction)); 3491285242Sachim ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); 3492285242Sachim if (ConnRate == SAS_CONNECTION_RATE_1_5G) 3493285242Sachim { 3494285242Sachim /* no retry; failure ??? */ 3495285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || 3496285242Sachim SMPRequestFunction == SMP_DISCOVER || 3497285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 3498285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3499285242Sachim ) 3500285242Sachim { 3501285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3502285242Sachim } 3503285242Sachim else if (SMPRequestFunction == SMP_PHY_CONTROL) 3504285242Sachim { 3505285242Sachim /* task management failure */ 3506285242Sachim dmPhyControlFailureRespRcvd( 3507285242Sachim dmRoot, 3508285242Sachim agRoot, 3509285242Sachim oneDeviceData, 3510285242Sachim agNULL, 3511285242Sachim agNULL 3512285242Sachim ); 3513285242Sachim } 3514285242Sachim else 3515285242Sachim { 3516285242Sachim } 3517285242Sachim } 3518285242Sachim else 3519285242Sachim { 3520285242Sachim ConnRate = ConnRate - 1; 3521285242Sachim } 3522285242Sachim agContext = &(dmSMPRequestBody->agContext); 3523285242Sachim agContext->osData = agIORequest; 3524285242Sachim saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB); 3525285242Sachim } 3526285242Sachim else 3527285242Sachim { 3528285242Sachim if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */ 3529285242Sachim { 3530285242Sachim /* retry the SMP again */ 3531285242Sachim DM_DBG1(("dmSMPCompleted: failed! but retries %d agIOStatus 0x%x %d agIOInfoLen %d\n", 3532285242Sachim dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen)); 3533285242Sachim saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); 3534285242Sachim dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader; 3535285242Sachim status = saSMPStart( 3536285242Sachim agRoot, 3537285242Sachim agIORequest, 3538285242Sachim 0, 3539285242Sachim agDevHandle, 3540285242Sachim AGSA_SMP_INIT_REQ, 3541285242Sachim agSASRequestBody, 3542285242Sachim &dmsaSMPCompleted 3543285242Sachim ); 3544285242Sachim 3545285242Sachim if (status == AGSA_RC_SUCCESS) 3546285242Sachim { 3547285242Sachim /* increment the number of pending SMP */ 3548285242Sachim onePortContext->discovery.pendingSMP++; 3549285242Sachim dmSMPRequestBody->retries++; 3550285242Sachim if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || 3551285242Sachim SMPRequestFunction == SMP_REPORT_PHY_SATA || 3552285242Sachim SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3553285242Sachim ) 3554285242Sachim { 3555285242Sachim /* start discovery-related SMP timer */ 3556285242Sachim dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody); 3557285242Sachim } 3558285242Sachim return; 3559285242Sachim } 3560285242Sachim else if (status == AGSA_RC_BUSY) 3561285242Sachim { 3562285242Sachim onePortContext->discovery.pendingSMP++; 3563285242Sachim dmSMPRequestBody->retries++; 3564285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3565285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3566285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3567285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3568285242Sachim ) 3569285242Sachim { 3570285242Sachim dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody); 3571285242Sachim return; 3572285242Sachim } 3573285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3574285242Sachim { 3575285242Sachim /* For taskmanagement SMP, let's fail task management failure */ 3576285242Sachim dmPhyControlFailureRespRcvd( 3577285242Sachim dmRoot, 3578285242Sachim agRoot, 3579285242Sachim oneDeviceData, 3580285242Sachim dmResponseSMPFrameHeader, 3581285242Sachim agFrameHandle 3582285242Sachim ); 3583285242Sachim } 3584285242Sachim else 3585285242Sachim { 3586285242Sachim } 3587285242Sachim } 3588285242Sachim else /* AGSA_RC_FAILURE */ 3589285242Sachim { 3590285242Sachim if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3591285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER || 3592285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3593285242Sachim dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3594285242Sachim ) 3595285242Sachim { 3596285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3597285242Sachim } 3598285242Sachim else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3599285242Sachim { 3600285242Sachim /* task management failure */ 3601285242Sachim dmPhyControlFailureRespRcvd( 3602285242Sachim dmRoot, 3603285242Sachim agRoot, 3604285242Sachim oneDeviceData, 3605285242Sachim dmResponseSMPFrameHeader, 3606285242Sachim agFrameHandle 3607285242Sachim ); 3608285242Sachim } 3609285242Sachim else 3610285242Sachim { 3611285242Sachim } 3612285242Sachim } 3613285242Sachim } 3614285242Sachim else 3615285242Sachim { 3616285242Sachim dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf; 3617285242Sachim dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4; 3618285242Sachim DM_DBG1(("dmSMPCompleted: failed! no more retry! agIOStatus 0x%x %d\n", agIOStatus, agIOStatus)); 3619285242Sachim if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL) 3620285242Sachim { 3621285242Sachim DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_NON_OPERATIONAL\n")); 3622285242Sachim } 3623285242Sachim if (agIOStatus == OSSA_IO_DS_IN_RECOVERY) 3624285242Sachim { 3625285242Sachim DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_IN_RECOVERY\n")); 3626285242Sachim } 3627285242Sachim if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || 3628285242Sachim dmSMPFrameHeader->smpFunction == SMP_DISCOVER || 3629285242Sachim dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || 3630285242Sachim dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION 3631285242Sachim ) 3632285242Sachim { 3633285242Sachim /* discovery failure */ 3634285242Sachim DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction)); 3635285242Sachim DM_DBG1(("dmSMPCompleted: discover done with error\n")); 3636285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3637285242Sachim } 3638285242Sachim else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) 3639285242Sachim { 3640285242Sachim DM_DBG1(("dmSMPCompleted: SMP_PHY_CONTROL\n")); 3641285242Sachim smpPhyControl2Req = (smpReqPhyControl2_t *)dmSMPPayload; 3642285242Sachim if (smpPhyControl2Req->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION) 3643285242Sachim { 3644285242Sachim DM_DBG1(("dmSMPCompleted: discover done with error\n")); 3645285242Sachim dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE); 3646285242Sachim } 3647285242Sachim else 3648285242Sachim { 3649285242Sachim DM_DBG1(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControl2Req->phyOperation)); 3650285242Sachim } 3651285242Sachim } /* SMP_PHY_CONTROL */ 3652285242Sachim else 3653285242Sachim { 3654285242Sachim DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction)); 3655285242Sachim } 3656285242Sachim } /* else */ 3657285242Sachim } /* for RateAdjust */ 3658285242Sachim } /* outer else */ 3659285242Sachim } /* SAS 2 else */ 3660285242Sachim 3661285242Sachim /* SMP request */ 3662285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3663285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3664285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3665285242Sachim 3666285242Sachim#ifndef DIRECT_SMP 3667285242Sachim /* SMP response */ 3668285242Sachim dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse; 3669285242Sachim if (dmSMPResponseBody == agNULL) 3670285242Sachim { 3671285242Sachim DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n")); 3672285242Sachim return; 3673285242Sachim } 3674285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3675285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList)); 3676285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3677285242Sachim#endif 3678285242Sachim 3679285242Sachim return; 3680285242Sachim} 3681285242Sachim 3682285242SachimosGLOBAL void 3683285242SachimdmSMPAbortCB( 3684285242Sachim agsaRoot_t *agRoot, 3685285242Sachim agsaIORequest_t *agIORequest, 3686285242Sachim bit32 flag, 3687285242Sachim bit32 status) 3688285242Sachim{ 3689285242Sachim dmRoot_t *dmRoot = agNULL; 3690285242Sachim dmIntRoot_t *dmIntRoot = agNULL; 3691285242Sachim dmIntContext_t *dmAllShared = agNULL; 3692285242Sachim dmSMPRequestBody_t *dmSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData; 3693285242Sachim 3694285242Sachim DM_DBG5(("dmSMPAbortCB: start\n")); 3695285242Sachim 3696285242Sachim if (dmSMPRequestBody == agNULL) 3697285242Sachim { 3698285242Sachim DM_DBG1(("dmSMPAbortCB: pSMPRequestBody is NULL!!! \n")); 3699285242Sachim return; 3700285242Sachim } 3701285242Sachim 3702285242Sachim dmRoot = dmSMPRequestBody->dmRoot; 3703285242Sachim dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 3704285242Sachim dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 3705285242Sachim 3706285242Sachim 3707285242Sachim /* put back into free smplist */ 3708285242Sachim tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK); 3709285242Sachim DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList)); 3710285242Sachim tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK); 3711285242Sachim 3712285242Sachim /* start here */ 3713285242Sachim if (flag == 2) 3714285242Sachim { 3715285242Sachim /* abort all per port */ 3716285242Sachim DM_DBG1(("dmSMPAbortCB: abort per port; not used!!!\n")); 3717285242Sachim } 3718285242Sachim else if (flag == 1) 3719285242Sachim { 3720285242Sachim /* abort all */ 3721285242Sachim DM_DBG1(("dmSMPAbortCB: abort all; not used!!!\n")); 3722285242Sachim } 3723285242Sachim else if (flag == 0) 3724285242Sachim { 3725285242Sachim /* abort one */ 3726285242Sachim DM_DBG1(("ossaSMPAbortCB: abort one\n")); 3727285242Sachim if (status != OSSA_IO_SUCCESS) 3728285242Sachim { 3729285242Sachim DM_DBG1(("dmSMPAbortCB: abort one, status 0x%x\n", status)); 3730285242Sachim } 3731285242Sachim } 3732285242Sachim else 3733285242Sachim { 3734285242Sachim DM_DBG1(("dmSMPAbortCB: not allowed case, flag 0x%x!!!\n", flag)); 3735285242Sachim } 3736285242Sachim 3737285242Sachim return; 3738285242Sachim} 3739285242Sachim 3740285242Sachim 3741285242Sachim#endif /* FDS_DM */ 3742285242Sachim 3743285242Sachim 3744