The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/RefTisa/discovery/dm/dmsmp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
    3 *
    4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 
    5 *that the following conditions are met: 
    6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
    7 *following disclaimer. 
    8 *2. Redistributions in binary form must reproduce the above copyright notice, 
    9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
   10 *with the distribution. 
   11 *
   12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
   13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
   16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
   17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
   18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
   19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
   20 
   21 **
   22 ********************************************************************************/
   23 #include <sys/cdefs.h>
   24 __FBSDID("$FreeBSD$");
   25 #include <dev/pms/config.h>
   26 
   27 #include <dev/pms/freebsd/driver/common/osenv.h>
   28 #include <dev/pms/freebsd/driver/common/ostypes.h>
   29 #include <dev/pms/freebsd/driver/common/osdebug.h>
   30 
   31 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
   32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
   33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
   34 
   35 #ifdef FDS_DM
   36 #include <dev/pms/RefTisa/discovery/api/dm.h>
   37 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
   38 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
   39 
   40 #include <dev/pms/RefTisa/discovery/dm/dmdefs.h>
   41 #include <dev/pms/RefTisa/discovery/dm/dmtypes.h>
   42 #include <dev/pms/RefTisa/discovery/dm/dmproto.h>
   43 
   44 osGLOBAL bit32
   45 dmSMPStart(
   46            dmRoot_t              *dmRoot,
   47            agsaRoot_t            *agRoot,
   48            dmDeviceData_t        *oneDeviceData,
   49            bit32                 functionCode,
   50            bit8                  *pSmpBody,
   51            bit32                 smpBodySize,
   52            bit32                 agRequestType
   53            )
   54 {
   55   dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
   56   dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
   57   dmIntPortContext_t        *onePortContext = agNULL;
   58   dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
   59 #ifndef DIRECT_SMP
   60   dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
   61 #endif
   62   agsaSASRequestBody_t      *agSASRequestBody;
   63   dmList_t                  *SMPList;
   64   agsaDevHandle_t           *agDevHandle;
   65   agsaIORequest_t           *agIORequest;
   66   agsaSMPFrame_t            *agSMPFrame;
   67   bit32                     expectedRspLen = 0;
   68   dmSMPFrameHeader_t        dmSMPFrameHeader;
   69   dmExpander_t              *oneExpander = agNULL;
   70   bit32                     status;
   71 
   72   DM_DBG5(("dmSMPStart: start\n"));
   73   DM_DBG5(("dmSMPStart: 2nd sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
   74   DM_DBG5(("dmSMPStart: 2nd sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
   75 
   76   dm_memset(&dmSMPFrameHeader, 0, sizeof(dmSMPFrameHeader_t));
   77 
   78   onePortContext = oneDeviceData->dmPortContext;
   79 
   80   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
   81   {
   82     DM_DBG1(("dmSMPStart: invalid port or aborted discovery!!!\n"));
   83     return DM_RC_FAILURE;
   84   }
   85 
   86   oneExpander = oneDeviceData->dmExpander;
   87   if (oneExpander == agNULL)
   88   {
   89     DM_DBG1(("dmSMPStart: Wrong!!! oneExpander is NULL!!!\n"));
   90     return DM_RC_FAILURE;
   91   }
   92 
   93   if (onePortContext != agNULL)
   94   {
   95     DM_DBG5(("dmSMPStart: pid %d\n", onePortContext->id));
   96     /* increment the number of pending SMP */
   97     onePortContext->discovery.pendingSMP++;
   98   }
   99   else
  100   {
  101     DM_DBG1(("dmSMPStart: Wrong, onePortContext is NULL!!!\n"));
  102     return DM_RC_FAILURE;
  103   }
  104 
  105   /* get an smp REQUEST from the free list */
  106   tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  107   if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
  108   {
  109     DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
  110     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  111     /* undo increment the number of pending SMP */
  112     onePortContext->discovery.pendingSMP--;
  113     return DM_RC_FAILURE;
  114   }
  115   else
  116   {
  117     DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
  118     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  119     dmSMPRequestBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
  120   }
  121 
  122   if (dmSMPRequestBody == agNULL)
  123   {
  124     DM_DBG1(("dmSMPStart: dmSMPRequestBody is NULL, wrong!!!\n"));
  125     return DM_RC_FAILURE;
  126   }
  127   DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPRequestBody->id));
  128 
  129   dmSMPRequestBody->dmRoot = dmRoot;
  130   dmSMPRequestBody->dmDevice = oneDeviceData;
  131   dmSMPRequestBody->dmPortContext = onePortContext;
  132 
  133   agDevHandle = oneExpander->agDevHandle;
  134 
  135   /* save the callback funtion */
  136   dmSMPRequestBody->SMPCompletionFunc = dmSMPCompleted; /* in dmsmp.c */
  137 
  138   dmSMPRequestBody->retries = 0;
  139 
  140   agIORequest = &(dmSMPRequestBody->agIORequest);
  141   agIORequest->osData = (void *) dmSMPRequestBody;
  142   agIORequest->sdkData = agNULL; /* SALL takes care of this */
  143 
  144   agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
  145   agSMPFrame = &(agSASRequestBody->smpFrame);
  146 
  147   /* sets dmSMPFrameHeader values */
  148   if (oneExpander->SAS2 == 0)
  149   {
  150     DM_DBG5(("dmSMPStart: SAS 1.1\n"));
  151     switch (functionCode)
  152     {
  153     case SMP_REPORT_GENERAL:
  154       expectedRspLen = sizeof(smpRespReportGeneral_t) + 4;
  155       break;
  156     case SMP_REPORT_MANUFACTURE_INFORMATION:
  157       expectedRspLen = sizeof(smpRespReportManufactureInfo_t) + 4;
  158       break;
  159     case SMP_DISCOVER:
  160       expectedRspLen = sizeof(smpRespDiscover_t) + 4;
  161       break;
  162     case SMP_REPORT_PHY_ERROR_LOG:
  163       expectedRspLen = 32 - 4;
  164       break;
  165     case SMP_REPORT_PHY_SATA:
  166       expectedRspLen = sizeof(smpRespReportPhySata_t) + 4;
  167       break;
  168     case SMP_REPORT_ROUTING_INFORMATION:
  169       expectedRspLen = sizeof(smpRespReportRouteTable_t) + 4;
  170       break;
  171     case SMP_CONFIGURE_ROUTING_INFORMATION:
  172       expectedRspLen = 4;
  173       break;
  174     case SMP_PHY_CONTROL:
  175       expectedRspLen = 4;
  176       break;
  177     case SMP_PHY_TEST_FUNCTION:
  178       expectedRspLen = 4;
  179       break;
  180     case SMP_PMC_SPECIFIC:
  181       expectedRspLen = 4;
  182       break;
  183     default:
  184       expectedRspLen = 0;
  185       DM_DBG1(("dmSMPStart: SAS 1.1 error, undefined or unused smp function code 0x%x !!!\n", functionCode));
  186       return DM_RC_FAILURE;
  187     }
  188     /* SMP 1.1 header */
  189     dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  190     dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  191     dmSMPFrameHeader.smpFunctionResult = 0;
  192     dmSMPFrameHeader.smpReserved = 0;
  193   }
  194   else /* SAS 2 */
  195   {
  196     DM_DBG2(("dmSMPStart: SAS 2\n"));
  197     switch (functionCode)
  198     {
  199     case SMP_REPORT_GENERAL:
  200       expectedRspLen = sizeof(smpRespReportGeneral2_t) + 4;
  201       /* SMP 2.0 header */
  202       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  203       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  204       dmSMPFrameHeader.smpFunctionResult = 0x11;
  205       dmSMPFrameHeader.smpReserved = 0;
  206       break;
  207     case SMP_REPORT_MANUFACTURE_INFORMATION:
  208       expectedRspLen = sizeof(smpRespReportManufactureInfo2_t) + 4;
  209       break;
  210     case SMP_DISCOVER:
  211       expectedRspLen = sizeof(smpRespDiscover2_t) + 4;
  212       /* SMP 2.0 header */
  213       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  214       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  215 //      dmSMPFrameHeader.smpFunctionResult = 0x6c;
  216       dmSMPFrameHeader.smpFunctionResult = 0x1b;
  217       dmSMPFrameHeader.smpReserved = 0x02;
  218       break;
  219     case SMP_REPORT_PHY_ERROR_LOG:
  220       expectedRspLen = 32 - 4;
  221       break;
  222     case SMP_REPORT_PHY_SATA:
  223       /* SMP 2.0 header */
  224       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  225       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  226       dmSMPFrameHeader.smpFunctionResult = 0x10;
  227       dmSMPFrameHeader.smpReserved = 0x02;
  228       expectedRspLen = sizeof(smpRespReportPhySata2_t) + 4;
  229       break;
  230     case SMP_REPORT_ROUTING_INFORMATION:
  231       expectedRspLen = sizeof(smpRespReportRouteTable2_t) + 4;
  232       break;
  233     case SMP_CONFIGURE_ROUTING_INFORMATION:
  234       expectedRspLen = 4;
  235       /* SMP 2.0 header */
  236       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  237       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  238       dmSMPFrameHeader.smpFunctionResult = 0;
  239       dmSMPFrameHeader.smpReserved = 0x09;
  240       break;
  241     case SMP_PHY_CONTROL:
  242       expectedRspLen = 4;
  243       /* SMP 2.0 header */
  244       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  245       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  246       dmSMPFrameHeader.smpFunctionResult = 0;
  247       dmSMPFrameHeader.smpReserved = 0x09;
  248      break;
  249     case SMP_PHY_TEST_FUNCTION:
  250       expectedRspLen = 4;
  251       break;
  252     case SMP_DISCOVER_LIST:
  253       expectedRspLen = SMP_MAXIMUM_PAYLOAD; /* 1024 without CRC */
  254       /* SMP 2.0 header */
  255       dmSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
  256       dmSMPFrameHeader.smpFunction = (bit8)functionCode;
  257       dmSMPFrameHeader.smpFunctionResult = 0xFF;
  258       dmSMPFrameHeader.smpReserved = 0x06;
  259       break;
  260     case SMP_PMC_SPECIFIC:
  261       expectedRspLen = 4;
  262       break;
  263     default:
  264       expectedRspLen = 0;
  265       DM_DBG1(("dmSMPStart: SAS 2 error!!! undefined or unused smp function code 0x%x!!!\n", functionCode));
  266       return DM_RC_FAILURE;
  267     }
  268   }
  269 
  270   if (DMIsSPC(agRoot))
  271   {
  272 #ifdef DIRECT_SMP  /* direct SMP with 48 or less payload */
  273   if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
  274   {
  275     DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
  276     dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
  277     dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
  278     dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
  279 
  280     /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
  281     agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
  282     agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
  283     /* to specify DIRECT SMP response */
  284     agSMPFrame->inFrameLen = 0;
  285 
  286     /* temporary solution for T2D Combo*/
  287 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
  288     /* force smp repsonse to be direct */
  289     agSMPFrame->expectedRespLen = 0;
  290 #else
  291     agSMPFrame->expectedRespLen = expectedRspLen;
  292 #endif
  293   }
  294   else
  295   {
  296     DM_DBG5(("dmSMPStart: INDIRECT smp payload, TBD\n"));
  297   }
  298 
  299 #else
  300 
  301   /*
  302      dmSMPRequestBody is SMP request
  303      dmSMPResponsebody is SMP response
  304   */
  305 
  306   /* get an smp RESPONSE from the free list */
  307   tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  308   if (DMLIST_EMPTY(&(dmAllShared->freeSMPList)))
  309   {
  310     DM_DBG1(("dmSMPStart: no free SMP!!!\n"));
  311     /* puy back dmSMPRequestBody to the freelist ???*/
  312 //    DMLIST_DEQUEUE_THIS(&(dmSMPRequestBody->Link));
  313     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  314     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  315 
  316     /* undo increment the number of pending SMP */
  317     onePortContext->discovery.pendingSMP--;
  318     return DM_RC_FAILURE;
  319   }
  320   else
  321   {
  322     DMLIST_DEQUEUE_FROM_HEAD(&SMPList, &(dmAllShared->freeSMPList));
  323     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  324     dmSMPResponseBody = DMLIST_OBJECT_BASE(dmSMPRequestBody_t, Link, SMPList);
  325     DM_DBG5(("dmSMPStart: SMP id %d\n", dmSMPResponseBody->id));
  326   }
  327 
  328   if (dmSMPResponseBody == agNULL)
  329   {
  330     DM_DBG1(("dmSMPStart: dmSMPResponseBody is NULL, wrong!!!\n"));
  331     return DM_RC_FAILURE;
  332   }
  333 
  334   /* fill in indirect SMP request fields */
  335   DM_DBG5(("dmSMPStart: INDIRECT smp payload\n"));
  336 
  337   /* save the pointer to SMP response in SMP request */
  338   dmSMPRequestBody->IndirectSMPResponse = dmSMPResponseBody;
  339   /* SMP request and response initialization */
  340   dm_memset(dmSMPRequestBody->IndirectSMP, 0, smpBodySize + 4);
  341   dm_memset(dmSMPResponseBody->IndirectSMP, 0, expectedRspLen);
  342 
  343   dm_memcpy(dmSMPRequestBody->IndirectSMP, &dmSMPFrameHeader, 4);
  344   dm_memcpy(dmSMPRequestBody->IndirectSMP+4, pSmpBody, smpBodySize);
  345 
  346   /* Indirect SMP request */
  347   agSMPFrame->outFrameBuf = agNULL;
  348   agSMPFrame->outFrameAddrUpper32 = dmSMPRequestBody->IndirectSMPUpper32;
  349   agSMPFrame->outFrameAddrLower32 = dmSMPRequestBody->IndirectSMPLower32;
  350   agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
  351 
  352   /* Indirect SMP response */
  353   agSMPFrame->expectedRespLen = expectedRspLen;
  354   agSMPFrame->inFrameAddrUpper32 = dmSMPResponseBody->IndirectSMPUpper32;
  355   agSMPFrame->inFrameAddrLower32 = dmSMPResponseBody->IndirectSMPLower32;
  356   agSMPFrame->inFrameLen = expectedRspLen; /* without last 4 byte crc */
  357 
  358 #endif
  359   }
  360   else /* SPCv controller */
  361   {
  362     /* only direct mode for both request and response */
  363     DM_DBG5(("dmSMPStart: DIRECT smp payload\n"));
  364     agSMPFrame->flag = 0;
  365     dm_memset(dmSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
  366     dm_memcpy(dmSMPRequestBody->smpPayload, &dmSMPFrameHeader, 4);
  367     dm_memcpy((dmSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
  368 
  369     /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
  370     agSMPFrame->outFrameBuf = dmSMPRequestBody->smpPayload;
  371     agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
  372     /* to specify DIRECT SMP response */
  373     agSMPFrame->inFrameLen = 0;
  374 
  375       /* temporary solution for T2D Combo*/
  376 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
  377     /* force smp repsonse to be direct */
  378     agSMPFrame->expectedRespLen = 0;
  379 #else
  380     agSMPFrame->expectedRespLen = expectedRspLen;
  381 #endif
  382   //    tdhexdump("tdSMPStart", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
  383   //    tdhexdump("tdSMPStart new", (bit8*)tdSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
  384   //    tdhexdump("tdSMPStart - tdSMPRequestBody", (bit8*)tdSMPRequestBody, sizeof(tdssSMPRequestBody_t));
  385   }
  386 
  387   if (agDevHandle == agNULL)
  388   {
  389     DM_DBG1(("dmSMPStart: !!! agDevHandle is NULL !!! \n"));
  390   }
  391   else
  392   {
  393     status = saSMPStart(
  394                       agRoot,
  395                       agIORequest,
  396                       0,
  397                       agDevHandle,
  398                       agRequestType,
  399                       agSASRequestBody,
  400                       &dmsaSMPCompleted
  401                       );
  402 
  403     if (status == AGSA_RC_SUCCESS)
  404     {
  405       /* start SMP timer */
  406       if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
  407           functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION
  408         )
  409       {
  410         dmDiscoverySMPTimer(dmRoot, onePortContext, functionCode, dmSMPRequestBody);
  411       }
  412       return DM_RC_SUCCESS;
  413     }
  414     else if (status == AGSA_RC_BUSY)
  415     {
  416       /* set timer */
  417       if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
  418           functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
  419       {
  420         /* only for discovery related SMPs*/
  421         dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
  422         return DM_RC_SUCCESS;
  423       }
  424       else
  425       {
  426         DM_DBG1(("dmSMPStart: return DM_RC_BUSY!!! \n"));
  427 #ifdef DIRECT_SMP
  428         tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  429         DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  430         tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  431 #else
  432         tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  433         DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  434         DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  435         tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  436 #endif
  437         return DM_RC_BUSY;
  438       }
  439     }
  440     else /* AGSA_RC_FAILURE */
  441     {
  442       DM_DBG1(("dmSMPStart: return DM_RC_FAILURE!!! \n"));
  443       /* discovery failure or task management failure */
  444       if (functionCode == SMP_REPORT_GENERAL || functionCode == SMP_DISCOVER ||
  445           functionCode == SMP_REPORT_PHY_SATA || functionCode == SMP_CONFIGURE_ROUTING_INFORMATION)
  446       {
  447         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  448       }
  449 #ifdef DIRECT_SMP
  450       tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  451       DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  452       tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  453 #else
  454       tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
  455       DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  456       DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
  457       tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
  458 #endif
  459 
  460       return DM_RC_FAILURE;
  461     }
  462   }
  463   return DM_RC_SUCCESS;
  464 }
  465 
  466 osGLOBAL void
  467 dmsaSMPCompleted(
  468                  agsaRoot_t            *agRoot,
  469                  agsaIORequest_t       *agIORequest,
  470                  bit32                 agIOStatus,
  471                  bit32                 agIOInfoLen,
  472                  agsaFrameHandle_t     agFrameHandle
  473                  )
  474 {
  475   dmSMPRequestBody_t   *pSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
  476 
  477   /* SPC can't be SMP target */
  478 
  479   DM_DBG5(("dmsaSMPCompleted: start\n"));
  480 
  481   if (pSMPRequestBody == agNULL)
  482   {
  483     DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody is NULL!!! \n"));
  484     return;
  485   }
  486 
  487   if (pSMPRequestBody->SMPCompletionFunc == agNULL)
  488   {
  489     DM_DBG1(("dmsaSMPCompleted: pSMPRequestBody->SMPCompletionFunc is NULL!!!\n"));
  490     return;
  491   }
  492 
  493 #ifdef DM_INTERNAL_DEBUG /* debugging */
  494   DM_DBG3(("dmsaSMPCompleted: agIOrequest %p\n", agIORequest->osData));
  495   DM_DBG3(("dmsaSMPCompleted: sizeof(tdIORequestBody_t) %d 0x%x\n", sizeof(tdIORequestBody_t),
  496            sizeof(tdIORequestBody_t)));
  497   DM_DBG3(("dmsaSMPCompleted: SMPRequestbody %p\n", pSMPRequestBody));
  498   DM_DBG3(("dmsaSMPCompleted: calling callback fn\n"));
  499   DM_DBG3(("dmsaSMPCompleted: callback fn %p\n",pSMPRequestBody->SMPCompletionFunc));
  500 #endif /* TD_INTERNAL_DEBUG */
  501   /*
  502     if initiator, calling dmSMPCompleted() in dmsmp.c
  503   */
  504   pSMPRequestBody->SMPCompletionFunc(
  505                                      agRoot,
  506                                      agIORequest,
  507                                      agIOStatus,
  508                                      agIOInfoLen,
  509                                      agFrameHandle
  510                                      );
  511 
  512   return;
  513 
  514 }
  515 
  516 osGLOBAL bit32
  517 dmPhyControlSend(
  518                    dmRoot_t             *dmRoot,
  519 //                   dmDeviceData_t     *oneDeviceData, /* taget disk */
  520                    dmDeviceData_t     *oneExpDeviceData, /* taget disk */                   
  521                    bit8                 phyOp,
  522 bit8 phyID // added
  523                    )
  524 {
  525   dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
  526   dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
  527   agsaRoot_t                *agRoot = dmAllShared->agRoot;
  528 //  thenil
  529 //  dmDeviceData_t      *oneExpDeviceData; 
  530   smpReqPhyControl_t    smpPhyControlReq;
  531 //  bit8                  phyID;
  532   bit32                 status;
  533   
  534   DM_DBG3(("dmPhyControlSend: start\n"));
  535   
  536   
  537   
  538   osti_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
  539 
  540   /* fill in SMP payload */
  541   smpPhyControlReq.phyIdentifier = phyID;
  542   smpPhyControlReq.phyOperation = phyOp;
  543   
  544   status = dmSMPStart(
  545                       dmRoot,
  546                       agRoot,
  547                       oneExpDeviceData,
  548                       SMP_PHY_CONTROL,
  549                       (bit8 *)&smpPhyControlReq,
  550                       sizeof(smpReqPhyControl_t),
  551                       AGSA_SMP_INIT_REQ
  552                      );
  553   return status;
  554 }
  555 
  556 osGLOBAL void
  557 dmReportGeneralSend(
  558                     dmRoot_t             *dmRoot,
  559                     dmDeviceData_t       *oneDeviceData
  560                     )
  561 {
  562   dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
  563   dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
  564   agsaRoot_t                *agRoot = dmAllShared->agRoot;
  565 
  566   DM_DBG3(("dmReportGeneralSend: start\n"));
  567   DM_DBG3(("dmReportGeneralSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  568   DM_DBG3(("dmReportGeneralSend: oneExpander %p did %d\n", oneDeviceData->dmExpander, oneDeviceData->dmExpander->id));
  569 
  570   if (agRoot == agNULL)
  571   {
  572     DM_DBG1(("dmReportGeneralSend: agRoot is NULL!!!\n"));
  573     return;
  574   }
  575 
  576   dmSMPStart(
  577              dmRoot,
  578              agRoot,
  579              oneDeviceData,
  580              SMP_REPORT_GENERAL,
  581              agNULL,
  582              0,
  583              AGSA_SMP_INIT_REQ
  584              );
  585   return;
  586 }
  587 osGLOBAL void
  588 dmReportGeneralRespRcvd(
  589                         dmRoot_t              *dmRoot,
  590                         agsaRoot_t            *agRoot,
  591                         agsaIORequest_t       *agIORequest,
  592                         dmDeviceData_t        *oneDeviceData,
  593                         dmSMPFrameHeader_t    *frameHeader,
  594                         agsaFrameHandle_t     frameHandle
  595                         )
  596 {
  597   smpRespReportGeneral_t       dmSMPReportGeneralResp;
  598   smpRespReportGeneral_t       *pdmSMPReportGeneralResp;
  599   dmIntPortContext_t           *onePortContext = agNULL;
  600   dmDiscovery_t                *discovery;
  601   dmExpander_t                 *oneExpander = agNULL;
  602 #ifndef DIRECT_SMP
  603   dmSMPRequestBody_t           *dmSMPRequestBody;
  604   dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
  605 #endif
  606   dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
  607   dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
  608 
  609   DM_DBG3(("dmReportGeneralRespRcvd: start\n"));
  610   DM_DBG3(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
  611   DM_DBG3(("dmReportGeneralRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
  612 
  613 #ifndef DIRECT_SMP
  614   dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
  615 #endif
  616   pdmSMPReportGeneralResp = &dmSMPReportGeneralResp;
  617 
  618   dm_memset(&dmSMPReportGeneralResp, 0, sizeof(smpRespReportGeneral_t));
  619 
  620 #ifdef DIRECT_SMP
  621   saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
  622 #else
  623   dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
  624   saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneralResp, sizeof(smpRespReportGeneral_t));
  625 #endif
  626 
  627   onePortContext = oneDeviceData->dmPortContext;
  628   discovery = &(onePortContext->discovery);
  629 
  630   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
  631   {
  632     DM_DBG1(("dmReportGeneralRespRcvd: invalid port or aborted discovery!!!\n"));
  633     return;
  634   }
  635 
  636   if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
  637   {
  638     oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneralResp->numOfPhys;
  639     oneExpander = oneDeviceData->dmExpander;
  640     oneExpander->routingIndex = (bit16) REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneralResp);
  641     oneExpander->configReserved = 0;
  642     oneExpander->configRouteTable = REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneralResp) ? 1 : 0;
  643     oneExpander->configuring = REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneralResp) ? 1 : 0;
  644     DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
  645     DM_DBG3(("dmReportGeneralRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  646     DM_DBG3(("dmReportGeneralRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
  647 
  648     if ( oneExpander->SAS2 == 0 && REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp) == 1)
  649     {
  650       oneExpander->SAS2 = REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp);
  651       DM_DBG2(("dmReportGeneralRespRcvd: SAS 2 Long Response=%d\n", REPORT_GENERAL_IS_LONG_RESPONSE(pdmSMPReportGeneralResp)));
  652       dmReportGeneralSend(dmRoot, oneDeviceData);
  653       return;
  654     }
  655 
  656     DM_DBG3(("dmReportGeneralRespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
  657       oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
  658     DM_DBG3(("dmReportGeneralRespRcvd: configRouteTable=%d configuring=%d\n",
  659       oneExpander->configRouteTable, oneExpander->configuring));
  660 
  661     if (oneExpander->configuring == 1)
  662     {
  663       discovery->retries++;
  664       if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
  665       {
  666         DM_DBG1(("dmReportGeneralRespRcvd: retries are over!!!\n"));
  667         DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
  668         discovery->retries = 0;
  669         /* failed the discovery */
  670         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  671       }
  672       else
  673       {
  674         DM_DBG3(("dmReportGeneralRespRcvd: keep retrying\n"));
  675         DM_DBG1(("dmReportGeneralRespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
  676         DM_DBG1(("dmReportGeneralRespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
  677         // start timer for sending ReportGeneral
  678         dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
  679       }
  680     }
  681     else
  682     {
  683       discovery->retries = 0;
  684       dmDiscoverSend(dmRoot, oneDeviceData);
  685     }
  686   }
  687   else
  688   {
  689      DM_DBG1(("dmReportGeneralRespRcvd: SMP failed; fn result 0x%x; stopping discovery !!!\n", frameHeader->smpFunctionResult));
  690      dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  691   }
  692   return;
  693 }
  694 
  695 osGLOBAL void
  696 dmReportGeneral2RespRcvd(
  697                         dmRoot_t              *dmRoot,
  698                         agsaRoot_t            *agRoot,
  699                         agsaIORequest_t       *agIORequest,
  700                         dmDeviceData_t        *oneDeviceData,
  701                         dmSMPFrameHeader_t    *frameHeader,
  702                         agsaFrameHandle_t     frameHandle
  703                         )
  704 {
  705   smpRespReportGeneral2_t      dmSMPReportGeneral2Resp;
  706   smpRespReportGeneral2_t      *pdmSMPReportGeneral2Resp;
  707   dmExpander_t                 *oneExpander = agNULL;
  708   dmIntPortContext_t           *onePortContext = agNULL;
  709   dmDiscovery_t                *discovery;
  710 #ifndef DIRECT_SMP
  711   dmSMPRequestBody_t           *dmSMPRequestBody;
  712   dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
  713 #endif
  714   bit32                        ConfiguresOthers = agFALSE;
  715   dmIntRoot_t         *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
  716   dmIntContext_t      *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
  717 
  718 
  719   DM_DBG2(("dmReportGeneral2RespRcvd: start\n"));
  720   DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
  721   DM_DBG2(("dmReportGeneral2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
  722 
  723 #ifndef DIRECT_SMP
  724   dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
  725 #endif
  726   pdmSMPReportGeneral2Resp = &dmSMPReportGeneral2Resp;
  727 
  728   dm_memset(&dmSMPReportGeneral2Resp, 0, sizeof(smpRespReportGeneral2_t));
  729 
  730 #ifdef DIRECT_SMP
  731   saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
  732 #else
  733   dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
  734   saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPReportGeneral2Resp, sizeof(smpRespReportGeneral2_t));
  735 #endif
  736 
  737   onePortContext = oneDeviceData->dmPortContext;
  738   discovery = &(onePortContext->discovery);
  739   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
  740   {
  741     DM_DBG1(("dmReportGeneral2RespRcvd: invalid port or aborted discovery!!!\n"));
  742     return;
  743   }
  744 
  745 /* ??? start here */
  746   if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
  747   {
  748     oneDeviceData->numOfPhys = (bit8) pdmSMPReportGeneral2Resp->numOfPhys;
  749     oneExpander = oneDeviceData->dmExpander;
  750     oneExpander->routingIndex = (bit16) SAS2_REPORT_GENERAL_GET_ROUTEINDEXES(pdmSMPReportGeneral2Resp);
  751     oneExpander->configReserved = 0;
  752     oneExpander->configRouteTable = SAS2_REPORT_GENERAL_IS_CONFIGURABLE(pdmSMPReportGeneral2Resp) ? 1 : 0;
  753     oneExpander->configuring = SAS2_REPORT_GENERAL_IS_CONFIGURING(pdmSMPReportGeneral2Resp) ? 1 : 0;
  754     oneExpander->TTTSupported = SAS2_REPORT_GENERAL_IS_TABLE_TO_TABLE_SUPPORTED(pdmSMPReportGeneral2Resp) ? 1 : 0;
  755     ConfiguresOthers = SAS2_REPORT_GENERAL_IS_CONFIGURES_OTHERS(pdmSMPReportGeneral2Resp) ? 1 : 0;
  756 
  757     DM_DBG2(("dmReportGeneral2RespRcvd: SAS 2 is %d\n", oneExpander->SAS2));
  758     DM_DBG3(("dmReportGeneral2RespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  759     DM_DBG3(("dmReportGeneral2RespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
  760 
  761 
  762     DM_DBG2(("dmReportGeneral2RespRcvd: oneExpander=%p numberofPhys=0x%x RoutingIndex=0x%x\n",
  763       oneExpander, oneDeviceData->numOfPhys, oneExpander->routingIndex));
  764     DM_DBG2(("dmReportGeneral2RespRcvd: configRouteTable=%d configuring=%d\n",
  765       oneExpander->configRouteTable, oneExpander->configuring));
  766     if (ConfiguresOthers)
  767     {
  768       DM_DBG2(("dmReportGeneral2RespRcvd: ConfiguresOthers is true\n"));
  769       discovery->ConfiguresOthers = agTRUE;
  770     }
  771     if (oneExpander->configuring == 1)
  772     {
  773       discovery->retries++;
  774       if (discovery->retries >= dmAllShared->MaxRetryDiscovery)
  775       {
  776         DM_DBG1(("dmReportGeneral2RespRcvd: retries are over!!!\n"));
  777         DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
  778 
  779         discovery->retries = 0;
  780         /* failed the discovery */
  781         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  782       }
  783       else
  784       {
  785         DM_DBG2(("dmReportGeneral2RespRcvd: keep retrying\n"));
  786         DM_DBG1(("dmReportGeneral2RespRcvd: Prep222389 RETRY at %d Maximum Retry is %d\n", discovery->retries, dmAllShared->MaxRetryDiscovery));
  787         DM_DBG1(("dmReportGeneral2RespRcvd: sasAddressHi 0x%08x sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
  788         // start timer for sending ReportGeneral
  789         dmDiscoveryConfiguringTimer(dmRoot, onePortContext, oneDeviceData);
  790       }
  791     }
  792     else
  793     {
  794       discovery->retries = 0;
  795       dmDiscoverSend(dmRoot, oneDeviceData);
  796     }
  797   }
  798   else
  799   {
  800      DM_DBG2(("dmReportGeneral2RespRcvd: SMP failed, stopping discovery\n"));
  801      dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  802   }
  803 
  804   return;
  805 }
  806 
  807 
  808 osGLOBAL void
  809 dmDiscoverSend(
  810                dmRoot_t             *dmRoot,
  811                dmDeviceData_t       *oneDeviceData
  812               )
  813 {
  814   dmIntRoot_t               *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
  815   dmIntContext_t            *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
  816   agsaRoot_t                *agRoot = dmAllShared->agRoot;
  817   smpReqDiscover_t          smpDiscoverReq;
  818   dmExpander_t              *oneExpander;
  819 
  820   DM_DBG3(("dmDiscoverSend: start\n"));
  821   DM_DBG3(("dmDiscoverSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  822   oneExpander = oneDeviceData->dmExpander;
  823   DM_DBG3(("dmDiscoverSend: oneExpander %p did %d\n", oneExpander, oneExpander->id));
  824   DM_DBG3(("dmDiscoverSend: phyID 0x%x\n", oneExpander->discoveringPhyId));
  825 
  826   dm_memset(&smpDiscoverReq, 0, sizeof(smpReqDiscover_t));
  827 
  828   smpDiscoverReq.reserved1 = 0;
  829   smpDiscoverReq.reserved2 = 0;
  830   smpDiscoverReq.phyIdentifier = oneExpander->discoveringPhyId;
  831   smpDiscoverReq.reserved3 = 0;
  832 
  833   dmSMPStart(
  834              dmRoot,
  835              agRoot,
  836              oneDeviceData,
  837              SMP_DISCOVER,
  838              (bit8 *)&smpDiscoverReq,
  839              sizeof(smpReqDiscover_t),
  840              AGSA_SMP_INIT_REQ
  841              );
  842   return;
  843 }
  844 
  845 osGLOBAL void
  846 dmDiscoverRespRcvd(
  847                    dmRoot_t              *dmRoot,
  848                    agsaRoot_t            *agRoot,
  849                    agsaIORequest_t       *agIORequest,
  850                    dmDeviceData_t        *oneDeviceData,
  851                    dmSMPFrameHeader_t    *frameHeader,
  852                    agsaFrameHandle_t     frameHandle
  853                   )
  854 {
  855   dmIntPortContext_t           *onePortContext = agNULL;
  856   dmDiscovery_t                *discovery;
  857   smpRespDiscover_t            *pdmSMPDiscoverResp;
  858 #ifndef DIRECT_SMP
  859   dmSMPRequestBody_t           *dmSMPRequestBody;
  860   dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
  861 #endif
  862   dmExpander_t                 *oneExpander = agNULL;
  863 
  864   DM_DBG3(("dmDiscoverRespRcvd: start\n"));
  865   DM_DBG3(("dmDiscoverRespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
  866   DM_DBG3(("dmDiscoverRespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
  867 
  868   onePortContext = oneDeviceData->dmPortContext;
  869   oneExpander = oneDeviceData->dmExpander;
  870   discovery = &(onePortContext->discovery);
  871 #ifndef DIRECT_SMP
  872   dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
  873 #endif
  874   DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  875   DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
  876 
  877   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
  878   {
  879     DM_DBG1(("dmDiscoverRespRcvd: invalid port or aborted discovery!!!\n"));
  880     return;
  881   }
  882 
  883   pdmSMPDiscoverResp = &(discovery->SMPDiscoverResp);
  884 
  885 #ifdef DIRECT_SMP
  886   saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
  887 #else
  888   dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
  889   saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
  890 #endif
  891 
  892   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
  893   {
  894     if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
  895     {
  896       dmUpStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
  897     }
  898     else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
  899     {
  900       dmDownStreamDiscoverExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp);
  901     }
  902     else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
  903     {
  904       /* not done with configuring routing
  905          1. set the timer
  906          2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
  907       */
  908       DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
  909       DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
  910       dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
  911 
  912       dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
  913     }
  914     else
  915     {
  916       /* nothing */
  917     }
  918   }
  919   else if (frameHeader->smpFunctionResult == PHY_VACANT)
  920   {
  921     DM_DBG3(("dmDiscoverRespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
  922     if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
  923     {
  924       dmUpStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
  925     }
  926     else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
  927     {
  928       dmDownStreamDiscoverExpanderPhySkip(dmRoot, onePortContext, oneExpander);
  929     }
  930     else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
  931     {
  932       /* not done with configuring routing
  933          1. set the timer
  934          2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
  935       */
  936       DM_DBG3(("dmDiscoverRespRcvd: still configuring routing; setting timer\n"));
  937       DM_DBG3(("dmDiscoverRespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscoverResp %p\n", onePortContext, oneDeviceData, pdmSMPDiscoverResp));
  938       dmhexdump("dmDiscoverRespRcvd", (bit8*)pdmSMPDiscoverResp, sizeof(smpRespDiscover_t));
  939 
  940       dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, pdmSMPDiscoverResp, agNULL);
  941     }
  942   }
  943   else
  944   {
  945      DM_DBG1(("dmDiscoverRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n",
  946                frameHeader->smpFunctionResult));
  947      dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
  948   }
  949 
  950 
  951 
  952   return;
  953 }
  954 
  955 osGLOBAL void
  956 dmDiscover2RespRcvd(
  957                    dmRoot_t              *dmRoot,
  958                    agsaRoot_t            *agRoot,
  959                    agsaIORequest_t       *agIORequest,
  960                    dmDeviceData_t        *oneDeviceData,
  961                    dmSMPFrameHeader_t    *frameHeader,
  962                    agsaFrameHandle_t     frameHandle
  963                   )
  964 {
  965   dmIntPortContext_t           *onePortContext = agNULL;
  966   dmDiscovery_t                *discovery;
  967   smpRespDiscover2_t           *pdmSMPDiscover2Resp;
  968 #ifndef DIRECT_SMP
  969   dmSMPRequestBody_t           *dmSMPRequestBody;
  970   dmSMPRequestBody_t           *dmSMPResponseBody = agNULL;
  971 #endif
  972   dmExpander_t                 *oneExpander = agNULL;
  973 
  974   DM_DBG2(("dmDiscover2RespRcvd: start\n"));
  975   DM_DBG2(("dmDiscover2RespRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
  976   DM_DBG2(("dmDiscover2RespRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
  977 
  978   onePortContext = oneDeviceData->dmPortContext;
  979   oneExpander = oneDeviceData->dmExpander;
  980   discovery = &(onePortContext->discovery);
  981 #ifndef DIRECT_SMP
  982   dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
  983 #endif
  984   DM_DBG3(("dmDiscoverRespRcvd: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
  985   DM_DBG3(("dmDiscoverRespRcvd: oneExpander %p did %d\n", oneExpander, oneExpander->id));
  986 
  987   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
  988   {
  989     DM_DBG1(("dmDiscover2RespRcvd: invalid port or aborted discovery!!!\n"));
  990     return;
  991   }
  992 
  993   pdmSMPDiscover2Resp = &(discovery->SMPDiscover2Resp);
  994 
  995 #ifdef DIRECT_SMP
  996   saFrameReadBlock(agRoot, frameHandle, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
  997 #else
  998   dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
  999   saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 4, pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
 1000 #endif
 1001 
 1002   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
 1003   {
 1004     DM_DBG2(("dmDiscover2RespRcvd: phyIdentifier %d\n", pdmSMPDiscover2Resp->phyIdentifier));
 1005     DM_DBG2(("dmDiscover2RespRcvd: NegotiatedSSCHWMuxingSupported %d\n", pdmSMPDiscover2Resp->NegotiatedSSCHWMuxingSupported));
 1006     DM_DBG2(("dmDiscover2RespRcvd: SAS2_MUXING_SUPPORTED %d\n", SAS2_DISCRSP_IS_MUXING_SUPPORTED(pdmSMPDiscover2Resp)));
 1007     DM_DBG2(("dmDiscover2RespRcvd: NegotiatedLogicalLinkRate %d\n", pdmSMPDiscover2Resp->NegotiatedLogicalLinkRate));
 1008     DM_DBG2(("dmDiscover2RespRcvd: ReasonNegotiatedPhysicalLinkRate %d\n", pdmSMPDiscover2Resp->ReasonNegotiatedPhysicalLinkRate));
 1009     DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LOGICAL_LINKRATE %d\n", SAS2_DISCRSP_GET_LOGICAL_LINKRATE(pdmSMPDiscover2Resp)));
 1010     DM_DBG2(("dmDiscover2RespRcvd: SAS2_DISCRSP_GET_LINKRATE %d\n", SAS2_DISCRSP_GET_LINKRATE(pdmSMPDiscover2Resp)));
 1011 
 1012 //NegotiatedLogicalLinkRate 13
 1013 //ReasonNegotiatedPhysicalLinkRate 94
 1014     if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
 1015     {
 1016       dmUpStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
 1017     }
 1018     else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
 1019     {
 1020       dmDownStreamDiscover2ExpanderPhy(dmRoot, onePortContext, oneExpander, pdmSMPDiscover2Resp);
 1021     }
 1022     else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
 1023     {
 1024       /* not done with configuring routing
 1025          1. set the timer
 1026          2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
 1027       */
 1028       DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
 1029       DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
 1030       dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
 1031       dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
 1032     }
 1033     else
 1034     {
 1035       /* nothing */
 1036     }
 1037   }
 1038   else if (frameHeader->smpFunctionResult == PHY_VACANT)
 1039   {
 1040     DM_DBG2(("dmDiscover2RespRcvd: smpFunctionResult is PHY_VACANT, phyid %d\n", oneExpander->discoveringPhyId));
 1041     if ( onePortContext->discovery.status == DISCOVERY_UP_STREAM)
 1042     {
 1043       dmUpStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
 1044     }
 1045     else if ( onePortContext->discovery.status == DISCOVERY_DOWN_STREAM)
 1046     {
 1047       dmDownStreamDiscover2ExpanderPhySkip(dmRoot, onePortContext, oneExpander);
 1048     }
 1049     else if (onePortContext->discovery.status == DISCOVERY_CONFIG_ROUTING)
 1050     {
 1051       /* not done with configuring routing
 1052          1. set the timer
 1053          2. on timer expiration, call tdsaSASDownStreamDiscoverExpanderPhy()
 1054       */
 1055       DM_DBG2(("dmDiscover2RespRcvd: still configuring routing; setting timer\n"));
 1056       DM_DBG2(("dmDiscover2RespRcvd: onePortContext %p oneDeviceData %p pdmSMPDiscover2Resp %p\n", onePortContext, oneDeviceData, pdmSMPDiscover2Resp));
 1057       dmhexdump("dmDiscover2RespRcvd", (bit8*)pdmSMPDiscover2Resp, sizeof(smpRespDiscover2_t));
 1058       dmConfigureRouteTimer(dmRoot, onePortContext, oneExpander, agNULL, pdmSMPDiscover2Resp);
 1059     }
 1060     else
 1061     {
 1062       /* nothing */
 1063     }
 1064   }
 1065   else
 1066   {
 1067      DM_DBG1(("dmDiscover2RespRcvd: Discovery Error SMP function return result error=0x%x\n",
 1068                frameHeader->smpFunctionResult));
 1069      dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 1070   }
 1071   return;
 1072 }
 1073 
 1074 #ifdef NOT_YET
 1075 osGLOBAL void
 1076 tdsaDiscoverList2Send(
 1077                  tiRoot_t             *tiRoot,
 1078                  tdsaDeviceData_t     *oneDeviceData
 1079                  )
 1080 {
 1081   agsaRoot_t            *agRoot;
 1082   tdsaExpander_t        *oneExpander;
 1083   smpReqDiscoverList2_t smpDiscoverListReq;
 1084 
 1085   DM_DBG1(("tdsaDiscoverList2Send: start\n"));
 1086   DM_DBG1(("tdsaDiscoverList2Send: device %p did %d\n", oneDeviceData, oneDeviceData->id));
 1087   agRoot = oneDeviceData->agRoot;
 1088   oneExpander = oneDeviceData->dmExpander;
 1089   DM_DBG1(("tdsaDiscoverList2Send: phyID 0x%x\n", oneExpander->discoveringPhyId));
 1090 
 1091 
 1092   osti_memset(&smpDiscoverListReq, 0, sizeof(smpReqDiscoverList2_t));
 1093 
 1094   smpDiscoverListReq.reserved1 = 0;
 1095   smpDiscoverListReq.StartingPhyID = 0;
 1096   smpDiscoverListReq.MaxNumDiscoverDesc = 40; /* 40 for SHORT FORMAT; 8 for Long Format; SAS2 p630 */
 1097   smpDiscoverListReq.byte10 = 0x2; /* phy filter; all but "no device attached" */
 1098   smpDiscoverListReq.byte11 = 0x1; /* descriptor type; SHORT FORMAT */
 1099 
 1100 
 1101   dmSMPStart(
 1102              dmRoot,
 1103              agRoot,
 1104              oneDeviceData,
 1105              SMP_DISCOVER_LIST,
 1106              (bit8 *)&smpDiscoverListReq,
 1107              sizeof(smpReqDiscoverList2_t),
 1108              AGSA_SMP_INIT_REQ,
 1109              agNULL
 1110              );
 1111   return;
 1112 }
 1113 
 1114 osGLOBAL void
 1115 tdsaDiscoverList2RespRcvd(
 1116                      tiRoot_t              *tiRoot,
 1117                      agsaRoot_t            *agRoot,
 1118                      tdsaDeviceData_t      *oneDeviceData,
 1119                      tdssSMPFrameHeader_t  *frameHeader,
 1120                      agsaFrameHandle_t     frameHandle
 1121                      )
 1122 {
 1123   return;
 1124 }
 1125 #endif /* not yet */
 1126 
 1127 /*****************************************************************************
 1128 *! \brief  dmReportPhySataSend
 1129 *
 1130 *  Purpose:  This function sends Report Phy SATA to a device.
 1131 *
 1132 *  \param   dmRoot: Pointer to the OS Specific module allocated dmRoot_t
 1133 *                   instance.
 1134 *  \param   oneDeviceData: Pointer to the device data.
 1135 *  \param   phyId: Phy Identifier.
 1136 *
 1137 *  \return:
 1138 *           None
 1139 *
 1140 *   \note:
 1141 *
 1142 *****************************************************************************/
 1143 osGLOBAL void
 1144 dmReportPhySataSend(
 1145                     dmRoot_t           *dmRoot,
 1146                     dmDeviceData_t     *oneDeviceData,
 1147                     bit8               phyId
 1148                     )
 1149 {
 1150   dmIntRoot_t        *dmIntRoot   = (dmIntRoot_t *)dmRoot->dmData;
 1151   dmIntContext_t     *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
 1152   agsaRoot_t         *agRoot      = dmAllShared->agRoot;
 1153   dmExpander_t       *oneExpander;
 1154   smpReqReportPhySata_t  smpReportPhySataReq;
 1155 
 1156   DM_DBG3(("dmReportPhySataSend: start\n"));
 1157   DM_DBG3(("dmReportPhySataSend: oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
 1158   DM_DBG3(("dmReportPhySataSend: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
 1159   DM_DBG3(("dmReportPhySataSend: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
 1160 
 1161   oneExpander = oneDeviceData->dmExpander;
 1162 
 1163   if (oneExpander == agNULL)
 1164   {
 1165     DM_DBG1(("dmReportPhySataSend: Error!!! expander is NULL\n"));
 1166     return;
 1167   }
 1168   DM_DBG3(("dmReportPhySataSend: device %p did %d\n", oneDeviceData, oneDeviceData->id));
 1169   DM_DBG3(("dmReportPhySataSend: phyid %d\n", phyId));
 1170 
 1171   dm_memset(&smpReportPhySataReq, 0, sizeof(smpReqReportPhySata_t));
 1172 
 1173   smpReportPhySataReq.phyIdentifier = phyId;
 1174 
 1175   dmSMPStart(
 1176              dmRoot,
 1177              agRoot,
 1178              oneExpander->dmDevice,
 1179              SMP_REPORT_PHY_SATA,
 1180              (bit8 *)&smpReportPhySataReq,
 1181              sizeof(smpReqReportPhySata_t),
 1182              AGSA_SMP_INIT_REQ
 1183              );
 1184 
 1185   return;
 1186 }
 1187 /*****************************************************************************
 1188 *! \brief  dmReportPhySataRcvd
 1189 *
 1190 *  Purpose:  This function processes Report Phy SATA response.
 1191 *
 1192 *  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
 1193 *                   instance.
 1194 *  \param   agRoot: Pointer to chip/driver Instance.
 1195 *  \param   oneDeviceData: Pointer to the device data.
 1196 *  \param   frameHeader: Pointer to SMP frame header.
 1197 *  \param   frameHandle: A Handle used to refer to the response frame
 1198 *
 1199 *  \return:
 1200 *           None
 1201 *
 1202 *   \note:
 1203 *
 1204 *****************************************************************************/
 1205 
 1206 osGLOBAL void
 1207 dmReportPhySataRcvd(
 1208                     dmRoot_t              *dmRoot,
 1209                     agsaRoot_t            *agRoot,
 1210                     agsaIORequest_t       *agIORequest,
 1211                     dmDeviceData_t        *oneDeviceData,
 1212                     dmSMPFrameHeader_t    *frameHeader,
 1213                     agsaFrameHandle_t     frameHandle
 1214                    )
 1215 {
 1216   smpRespReportPhySata_t      SMPreportPhySataResp;
 1217   smpRespReportPhySata_t      *pSMPReportPhySataResp;
 1218   dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
 1219   dmIntPortContext_t          *onePortContext = agNULL;
 1220   agsaFisRegDeviceToHost_t    *fis;
 1221   dmDeviceData_t              *SataDevice = agNULL;
 1222 #ifndef DIRECT_SMP
 1223   dmSMPRequestBody_t          *tdSMPRequestBody;
 1224 #endif
 1225   bit8                        sataDeviceType;
 1226   bit8                        *bit8fis;
 1227   bit8                        i = 0;
 1228   bit32                       a = 0;
 1229   bit8                        bit8fisarray[20];
 1230 
 1231   DM_DBG3(("dmReportPhySataRcvd: start\n"));
 1232   DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
 1233   DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
 1234 
 1235 #ifndef DIRECT_SMP
 1236   tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
 1237 #endif
 1238   /* get the current sata device hanlde stored in the expander structure */
 1239   if (oneExpander != agNULL)
 1240   {
 1241       SataDevice = oneExpander->dmDeviceToProcess;
 1242   }
 1243 
 1244   if (SataDevice != agNULL)
 1245   {
 1246     DM_DBG3(("dmReportPhySataRcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
 1247     DM_DBG3(("dmReportPhySataRcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
 1248   }
 1249   else
 1250   {
 1251     DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
 1252   }
 1253 
 1254   pSMPReportPhySataResp = &SMPreportPhySataResp;
 1255 
 1256 #ifdef DIRECT_SMP
 1257   saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
 1258 #else
 1259   saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
 1260 #endif
 1261 
 1262   /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
 1263 
 1264 #ifndef DIRECT_SMP
 1265   ostiFreeMemory(
 1266                  dmRoot,
 1267                  tdSMPRequestBody->IndirectSMPReqosMemHandle,
 1268                  tdSMPRequestBody->IndirectSMPReqLen
 1269                 );
 1270   ostiFreeMemory(
 1271                  dmRoot,
 1272                  tdSMPRequestBody->IndirectSMPResposMemHandle,
 1273                  tdSMPRequestBody->IndirectSMPRespLen
 1274                 );
 1275 #endif
 1276 
 1277   onePortContext = oneDeviceData->dmPortContext;
 1278 
 1279   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
 1280   {
 1281     DM_DBG1(("dmReportPhySataRcvd: invalid port or aborted discovery!!!\n"));
 1282     return;
 1283   }
 1284 
 1285   if (SataDevice == agNULL)
 1286   {
 1287     DM_DBG1(("dmReportPhySataRcvd: SataDevice is NULL, wrong\n"));
 1288     dmDiscoverAbort(dmRoot, onePortContext);
 1289     return;
 1290   }
 1291 
 1292   if (frameHeader->smpFunctionResult == PHY_VACANT )
 1293   {
 1294      DM_DBG1(("dmReportPhySataRcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
 1295      return;
 1296   }
 1297 
 1298   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED  )
 1299   {
 1300     fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
 1301     if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
 1302     {
 1303       /* save signature */
 1304       DM_DBG3(("dmReportPhySataRcvd: saves the signature\n"));
 1305       /* saves signature */
 1306       SataDevice->satSignature[0] = fis->d.sectorCount;
 1307       SataDevice->satSignature[1] = fis->d.lbaLow;
 1308       SataDevice->satSignature[2] = fis->d.lbaMid;
 1309       SataDevice->satSignature[3] = fis->d.lbaHigh;
 1310       SataDevice->satSignature[4] = fis->d.device;
 1311       SataDevice->satSignature[5] = 0;
 1312       SataDevice->satSignature[6] = 0;
 1313       SataDevice->satSignature[7] = 0;
 1314 
 1315       DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
 1316        SataDevice->satSignature[0],
 1317        SataDevice->satSignature[1],
 1318        SataDevice->satSignature[2],
 1319        SataDevice->satSignature[3],
 1320        SataDevice->satSignature[4]));
 1321 
 1322        sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
 1323        if( sataDeviceType == SATA_ATAPI_DEVICE)
 1324        {
 1325           SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
 1326        }
 1327        SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
 1328     }
 1329     /* Handling DataDomain buggy FIS */
 1330     else if (fis->h.error == REG_DEV_TO_HOST_FIS)
 1331     {
 1332       /* needs to flip fis to host order */
 1333       bit8fis = (bit8*)fis;
 1334       for (i=0;i<5;i++)
 1335       {
 1336         a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
 1337         DM_DBG3(("dmReportPhySataRcvd: a 0x%8x\n", a));
 1338         bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
 1339         bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
 1340         bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
 1341         bit8fisarray[4*i+3] = (a & 0x000000FF);
 1342         bit8fis = bit8fis + 4;
 1343       }
 1344       fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
 1345       /* save signature */
 1346       DM_DBG3(("dmReportPhySataRcvd: DataDomain ATAPI saves the signature\n"));
 1347       /* saves signature */
 1348       SataDevice->satSignature[0] = fis->d.sectorCount;
 1349       SataDevice->satSignature[1] = fis->d.lbaLow;
 1350       SataDevice->satSignature[2] = fis->d.lbaMid;
 1351       SataDevice->satSignature[3] = fis->d.lbaHigh;
 1352       SataDevice->satSignature[4] = fis->d.device;
 1353       SataDevice->satSignature[5] = 0;
 1354       SataDevice->satSignature[6] = 0;
 1355       SataDevice->satSignature[7] = 0;
 1356 
 1357       DM_DBG3(("dmReportPhySataRcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
 1358        SataDevice->satSignature[0],
 1359        SataDevice->satSignature[1],
 1360        SataDevice->satSignature[2],
 1361        SataDevice->satSignature[3],
 1362        SataDevice->satSignature[4]));
 1363 
 1364        sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
 1365        if( sataDeviceType == SATA_ATAPI_DEVICE)
 1366        {
 1367           SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
 1368        }
 1369        SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
 1370     }
 1371     else
 1372     {
 1373       DM_DBG3(("dmReportPhySataRcvd: getting next stp bride\n"));
 1374     }
 1375 
 1376     /* Continure to report this STP device to TD*/
 1377     if (SataDevice->ExpDevice != agNULL)
 1378     {
 1379        tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
 1380     }
 1381     else
 1382     {
 1383        tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
 1384     }
 1385   }
 1386   else
 1387   {
 1388     DM_DBG3(("dmReportPhySataRcvd: siReportPhySataRcvd SMP function return result %x\n",
 1389              frameHeader->smpFunctionResult));
 1390     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 1391   }
 1392 
 1393   return;
 1394 }
 1395 
 1396 /*****************************************************************************
 1397 *! \brief  dmReportPhySata2Rcvd
 1398 *
 1399 *  Purpose:  This function processes SAS2.0 Report Phy SATA response.
 1400 *
 1401 *  \param   dmRoot_t: Pointer to the OS Specific module allocated dmRoot_t
 1402 *                   instance.
 1403 *  \param   agRoot: Pointer to chip/driver Instance.
 1404 *  \param   oneDeviceData: Pointer to the device data.
 1405 *  \param   frameHeader: Pointer to SMP frame header.
 1406 *  \param   frameHandle: A Handle used to refer to the response frame
 1407 *
 1408 *  \return:
 1409 *           None
 1410 *
 1411 *   \note:
 1412 *
 1413 *****************************************************************************/
 1414 osGLOBAL void
 1415 dmReportPhySata2Rcvd(
 1416                     dmRoot_t              *dmRoot,
 1417                     agsaRoot_t            *agRoot,
 1418                     agsaIORequest_t       *agIORequest,
 1419                     dmDeviceData_t        *oneDeviceData,
 1420                     dmSMPFrameHeader_t    *frameHeader,
 1421                     agsaFrameHandle_t     frameHandle
 1422                    )
 1423 {
 1424    smpRespReportPhySata2_t      SMPreportPhySataResp;
 1425    smpRespReportPhySata2_t      *pSMPReportPhySataResp;
 1426    dmExpander_t                *oneExpander = oneDeviceData->dmExpander;
 1427    dmIntPortContext_t          *onePortContext = agNULL;
 1428    agsaFisRegDeviceToHost_t    *fis;
 1429    dmDeviceData_t              *SataDevice = agNULL;
 1430 #ifndef DIRECT_SMP
 1431    dmSMPRequestBody_t          *tdSMPRequestBody;
 1432 #endif
 1433    bit8                         sataDeviceType = 0;
 1434    bit8                        *bit8fis;
 1435    bit8                        i = 0;
 1436    bit32                       a = 0;
 1437    bit8                        bit8fisarray[20];
 1438 
 1439    DM_DBG3(("dmReportPhySata2Rcvd: start\n"));
 1440    DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
 1441    DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
 1442 
 1443 #ifndef DIRECT_SMP
 1444    tdSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
 1445 #endif
 1446    /* get the current sata device hanlde stored in the expander structure */
 1447    if (oneExpander != agNULL)
 1448    {
 1449      SataDevice = oneExpander->dmDeviceToProcess;
 1450    }
 1451 
 1452    if (SataDevice != agNULL)
 1453    {
 1454      DM_DBG3(("dmReportPhySata2Rcvd: sasAddressHi 0x%08x\n", SataDevice->SASAddressID.sasAddressHi));
 1455      DM_DBG3(("dmReportPhySata2Rcvd: sasAddressLo 0x%08x\n", SataDevice->SASAddressID.sasAddressLo));
 1456    }
 1457    else
 1458    {
 1459      DM_DBG3(("dmReportPhySataRcvd: SataDevice is NULL\n"));
 1460    }
 1461 
 1462   pSMPReportPhySataResp = &SMPreportPhySataResp;
 1463 
 1464 #ifdef DIRECT_SMP
 1465    saFrameReadBlock(agRoot, frameHandle, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
 1466 #else
 1467    saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 4, pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));
 1468 #endif
 1469 
 1470    /* tdhexdump("dmReportPhySataRcvd", (bit8 *)pSMPReportPhySataResp, sizeof(smpRespReportPhySata_t));*/
 1471 
 1472 #ifndef DIRECT_SMP
 1473    ostiFreeMemory(
 1474                   dmRoot,
 1475                   tdSMPRequestBody->IndirectSMPReqosMemHandle,
 1476                   tdSMPRequestBody->IndirectSMPReqLen
 1477                  );
 1478    ostiFreeMemory(
 1479                   dmRoot,
 1480                   tdSMPRequestBody->IndirectSMPResposMemHandle,
 1481                   tdSMPRequestBody->IndirectSMPRespLen
 1482                  );
 1483 #endif
 1484 
 1485    onePortContext = oneDeviceData->dmPortContext;
 1486 
 1487    if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
 1488    {
 1489      DM_DBG1(("dmReportPhySata2Rcvd: invalid port or aborted discovery!!!\n"));
 1490      return;
 1491    }
 1492 
 1493    if (SataDevice == agNULL)
 1494    {
 1495      DM_DBG1(("dmReportPhySata2Rcvd: SataDevice is NULL, wrong\n"));
 1496      dmDiscoverAbort(dmRoot, onePortContext);
 1497      return;
 1498    }
 1499 
 1500    if ( frameHeader->smpFunctionResult == PHY_VACANT )
 1501    {
 1502       DM_DBG1(("dmReportPhySata2Rcvd: smpFunctionResult == PHY_VACANT, wrong\n"));
 1503       return;
 1504    }
 1505 
 1506    if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED )
 1507    {
 1508      fis = (agsaFisRegDeviceToHost_t*) &SMPreportPhySataResp.regDevToHostFis;
 1509      if (fis->h.fisType == REG_DEV_TO_HOST_FIS)
 1510      {
 1511        /* save signature */
 1512        DM_DBG3(("dmReportPhySata2Rcvd: saves the signature\n"));
 1513        /* saves signature */
 1514        SataDevice->satSignature[0] = fis->d.sectorCount;
 1515        SataDevice->satSignature[1] = fis->d.lbaLow;
 1516        SataDevice->satSignature[2] = fis->d.lbaMid;
 1517        SataDevice->satSignature[3] = fis->d.lbaHigh;
 1518        SataDevice->satSignature[4] = fis->d.device;
 1519        SataDevice->satSignature[5] = 0;
 1520        SataDevice->satSignature[6] = 0;
 1521        SataDevice->satSignature[7] = 0;
 1522        DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
 1523         SataDevice->satSignature[0],
 1524         SataDevice->satSignature[1],
 1525         SataDevice->satSignature[2],
 1526         SataDevice->satSignature[3],
 1527         SataDevice->satSignature[4]));
 1528        sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
 1529        if( sataDeviceType == SATA_ATAPI_DEVICE)
 1530        {
 1531           SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
 1532        }
 1533        SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
 1534     }
 1535     /* Handling DataDomain buggy FIS */
 1536     else if (fis->h.error == REG_DEV_TO_HOST_FIS)
 1537     {
 1538       /* needs to flip fis to host order */
 1539       bit8fis = (bit8*)fis;
 1540       for (i=0;i<5;i++)
 1541       {
 1542         a = DMA_LEBIT32_TO_BIT32(*(bit32*)bit8fis);
 1543         DM_DBG3(("dmReportPhySata2Rcvd: a 0x%8x\n", a));
 1544         bit8fisarray[4*i] = (a & 0xFF000000) >> 24;
 1545         bit8fisarray[4*i+1] = (a & 0x00FF0000) >> 16;
 1546         bit8fisarray[4*i+2] = (a & 0x0000FF00) >> 8;
 1547         bit8fisarray[4*i+3] = (a & 0x000000FF);
 1548         bit8fis = bit8fis + 4;
 1549       }
 1550       fis = (agsaFisRegDeviceToHost_t*) bit8fisarray;
 1551       /* save signature */
 1552       DM_DBG3(("dmReportPhySata2Rcvd: DataDomain ATAPI saves the signature\n"));
 1553       /* saves signature */
 1554       SataDevice->satSignature[0] = fis->d.sectorCount;
 1555       SataDevice->satSignature[1] = fis->d.lbaLow;
 1556       SataDevice->satSignature[2] = fis->d.lbaMid;
 1557       SataDevice->satSignature[3] = fis->d.lbaHigh;
 1558       SataDevice->satSignature[4] = fis->d.device;
 1559       SataDevice->satSignature[5] = 0;
 1560       SataDevice->satSignature[6] = 0;
 1561       SataDevice->satSignature[7] = 0;
 1562       DM_DBG3(("dmReportPhySata2Rcvd: SATA Signature = %02x %02x %02x %02x %02x\n",
 1563        SataDevice->satSignature[0],
 1564        SataDevice->satSignature[1],
 1565        SataDevice->satSignature[2],
 1566        SataDevice->satSignature[3],
 1567        SataDevice->satSignature[4]));
 1568 
 1569        sataDeviceType = tddmSATADeviceTypeDecode(SataDevice->satSignature);
 1570        if( sataDeviceType == SATA_ATAPI_DEVICE)
 1571        {
 1572           SataDevice->agDeviceInfo.flag |=  ATAPI_DEVICE_FLAG;
 1573        }
 1574        SataDevice->dmDeviceInfo.sataDeviceType = sataDeviceType;
 1575     }
 1576     else
 1577     {
 1578       DM_DBG3(("dmReportPhySata2Rcvd: getting next stp bride\n"));
 1579     }
 1580 
 1581     /* Continue to report this STP device to TD*/
 1582     if (SataDevice->ExpDevice != agNULL)
 1583     {
 1584        tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, &SataDevice->ExpDevice->dmDeviceInfo, dmDeviceArrival);
 1585     }
 1586     else
 1587     {
 1588        tddmReportDevice(dmRoot, onePortContext->dmPortContext, &SataDevice->dmDeviceInfo, agNULL, dmDeviceArrival);
 1589     }
 1590 
 1591    }
 1592    else
 1593    {
 1594      DM_DBG3(("dmReportPhySata2Rcvd: siReportPhySataRcvd SMP function return result %x\n",
 1595               frameHeader->smpFunctionResult));
 1596      dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 1597    }
 1598 
 1599    return;
 1600 }
 1601 
 1602 
 1603 
 1604 osGLOBAL bit32
 1605 dmRoutingEntryAdd(
 1606                   dmRoot_t          *dmRoot,
 1607                   dmExpander_t      *oneExpander,
 1608                   bit32             phyId,
 1609                   bit32             configSASAddressHi,
 1610                   bit32             configSASAddressLo
 1611                  )
 1612 {
 1613   dmIntRoot_t                             *dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
 1614   dmIntContext_t                          *dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
 1615   agsaRoot_t                              *agRoot = dmAllShared->agRoot;
 1616   bit32                                   ret = agTRUE;
 1617   dmIntPortContext_t                      *onePortContext;
 1618   smpReqConfigureRouteInformation_t       confRoutingInfo;
 1619   bit32                                   i;
 1620 
 1621   DM_DBG3(("dmRoutingEntryAdd: start\n"));
 1622   DM_DBG3(("dmRoutingEntryAdd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
 1623   DM_DBG3(("dmRoutingEntryAdd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
 1624   DM_DBG3(("dmRoutingEntryAdd: phyid %d\n", phyId));
 1625 
 1626   if (oneExpander->dmDevice->SASAddressID.sasAddressHi == configSASAddressHi &&
 1627       oneExpander->dmDevice->SASAddressID.sasAddressLo == configSASAddressLo
 1628      )
 1629   {
 1630     DM_DBG3(("dmRoutingEntryAdd: unnecessary\n"));
 1631     return ret;
 1632   }
 1633   if (oneExpander->routingAttribute[phyId] != SAS_ROUTING_TABLE)
 1634   {
 1635     DM_DBG3(("dmRoutingEntryAdd: not table routing, routing is %d\n", oneExpander->routingAttribute[phyId]));
 1636     return ret;
 1637   }
 1638 
 1639   onePortContext = oneExpander->dmDevice->dmPortContext;
 1640 
 1641   onePortContext->discovery.status = DISCOVERY_CONFIG_ROUTING;
 1642 
 1643   /* reset smpReqConfigureRouteInformation_t */
 1644   dm_memset(&confRoutingInfo, 0, sizeof(smpReqConfigureRouteInformation_t));
 1645   if ( oneExpander->currentIndex[phyId] < oneExpander->routingIndex )
 1646   {
 1647     DM_DBG3(("dmRoutingEntryAdd: adding sasAddressHi 0x%08x\n", configSASAddressHi));
 1648     DM_DBG3(("dmRoutingEntryAdd: adding sasAddressLo 0x%08x\n", configSASAddressLo));
 1649     DM_DBG3(("dmRoutingEntryAdd: phyid %d currentIndex[phyid] %d\n", phyId, oneExpander->currentIndex[phyId]));
 1650 
 1651     oneExpander->configSASAddressHi = configSASAddressHi;
 1652     oneExpander->configSASAddressLo = configSASAddressLo;
 1653     confRoutingInfo.reserved1[0] = 0;
 1654     confRoutingInfo.reserved1[1] = 0;
 1655     OSSA_WRITE_BE_16(agRoot, confRoutingInfo.expanderRouteIndex, 0, (oneExpander->currentIndex[phyId]));
 1656     confRoutingInfo.reserved2 = 0;
 1657     confRoutingInfo.phyIdentifier = (bit8)phyId;
 1658     confRoutingInfo.reserved3[0] = 0;
 1659     confRoutingInfo.reserved3[1] = 0;
 1660     confRoutingInfo.disabledBit_reserved4 = 0;
 1661     confRoutingInfo.reserved5[0] = 0;
 1662     confRoutingInfo.reserved5[1] = 0;
 1663     confRoutingInfo.reserved5[2] = 0;
 1664     OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressHi, 0, configSASAddressHi);
 1665     OSSA_WRITE_BE_32(agRoot, confRoutingInfo.routedSasAddressLo, 0, configSASAddressLo);
 1666     for ( i = 0; i < 16; i ++ )
 1667     {
 1668       confRoutingInfo.reserved6[i] = 0;
 1669     }
 1670     dmSMPStart(dmRoot, agRoot, oneExpander->dmDevice, SMP_CONFIGURE_ROUTING_INFORMATION, (bit8 *)&confRoutingInfo, sizeof(smpReqConfigureRouteInformation_t), AGSA_SMP_INIT_REQ);
 1671 
 1672     oneExpander->currentIndex[phyId] ++;
 1673   }
 1674   else
 1675   {
 1676     DM_DBG3(("dmRoutingEntryAdd: Discovery Error routing index overflow for currentIndex=%d, routingIndex=%d\n", oneExpander->currentIndex[phyId], oneExpander->routingIndex));
 1677     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 1678 
 1679     ret = agFALSE;
 1680   }
 1681   return ret;
 1682 }
 1683 
 1684 
 1685 osGLOBAL void
 1686 dmConfigRoutingInfoRespRcvd(
 1687                             dmRoot_t              *dmRoot,
 1688                             agsaRoot_t            *agRoot,
 1689                             agsaIORequest_t       *agIORequest,
 1690                             dmDeviceData_t        *oneDeviceData,
 1691                             dmSMPFrameHeader_t    *frameHeader,
 1692                             agsaFrameHandle_t     frameHandle
 1693                            )
 1694 {
 1695   dmIntPortContext_t                    *onePortContext;
 1696   dmExpander_t                          *oneExpander = oneDeviceData->dmExpander;
 1697   dmExpander_t                          *UpStreamExpander;
 1698   dmExpander_t                          *DownStreamExpander;
 1699   dmExpander_t                          *ReturningExpander;
 1700   dmExpander_t                          *ConfigurableExpander;
 1701   dmDeviceData_t                        *ReturningExpanderDeviceData = agNULL;
 1702   bit32                                 dupConfigSASAddr = agFALSE;
 1703 
 1704 
 1705   DM_DBG3(("dmConfigRoutingInfoRespRcvd: start\n"));
 1706   DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
 1707   DM_DBG3(("dmConfigRoutingInfoRespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
 1708 
 1709   onePortContext = oneDeviceData->dmPortContext;
 1710 
 1711   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
 1712   {
 1713     DM_DBG1(("dmConfigRoutingInfoRespRcvd: invalid port or aborted discovery!!!\n"));
 1714     return;
 1715   }
 1716 
 1717   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
 1718        frameHeader->smpFunctionResult == PHY_VACANT
 1719      )
 1720   {
 1721     DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
 1722     if (DownStreamExpander != agNULL)
 1723     {
 1724       DownStreamExpander->currentUpStreamPhyIndex ++;
 1725       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
 1726       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
 1727       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
 1728       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
 1729 
 1730     }
 1731 
 1732     oneExpander->currentDownStreamPhyIndex++;
 1733     DM_DBG3(("dmConfigRoutingInfoRespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
 1734 
 1735     if ( (DownStreamExpander != agNULL) &&
 1736          (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
 1737        )
 1738     {
 1739       DM_DBG3(("dmConfigRoutingInfoRespRcvd: first if\n"));
 1740       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
 1741 
 1742       DM_DBG3(("dmConfigRoutingInfoRespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
 1743 
 1744       dmRoutingEntryAdd(dmRoot,
 1745                            oneExpander,
 1746                            DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
 1747                            oneExpander->configSASAddressHi,
 1748                            oneExpander->configSASAddressLo
 1749                           );
 1750     }
 1751     else
 1752     {
 1753       /* traversing up till discovery Root onePortContext->discovery.RootExp */
 1754       DM_DBG3(("dmConfigRoutingInfoRespRcvd: else\n"));
 1755 
 1756       UpStreamExpander = oneExpander->dmUpStreamExpander;
 1757       ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
 1758       if (UpStreamExpander != agNULL)
 1759       {
 1760         DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
 1761         DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
 1762       }
 1763       else
 1764       {
 1765         DM_DBG3(("dmConfigRoutingInfoRespRcvd: UpStreamExpander is NULL\n"));
 1766       }
 1767       dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
 1768                                                   ConfigurableExpander,
 1769                                                   oneExpander->configSASAddressHi,
 1770                                                   oneExpander->configSASAddressLo
 1771                                                   );
 1772 
 1773       if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
 1774       {
 1775         DM_DBG3(("dmConfigRoutingInfoRespRcvd: else if\n"));
 1776 
 1777         DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
 1778         DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
 1779 
 1780         if ( UpStreamExpander != agNULL)
 1781         {
 1782           UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
 1783         }
 1784         ConfigurableExpander->currentDownStreamPhyIndex =
 1785                 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
 1786         ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
 1787         if ( DownStreamExpander != agNULL)
 1788         {
 1789           DownStreamExpander->currentUpStreamPhyIndex = 0;
 1790         }
 1791         DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
 1792 
 1793         DM_DBG3(("dmConfigRoutingInfoRespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
 1794         dmRoutingEntryAdd(dmRoot,
 1795                              ConfigurableExpander,
 1796                              ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
 1797                              oneExpander->configSASAddressHi,
 1798                              oneExpander->configSASAddressLo
 1799                             );
 1800       }
 1801       else
 1802       {
 1803         /* going back to where it was */
 1804         /* ConfigRoutingInfo is done for a target */
 1805         DM_DBG3(("dmConfigRoutingInfoRespRcvd: $$$$$$ my change $$$$$ \n"));
 1806         ReturningExpander = oneExpander->dmReturnginExpander;
 1807         if ( DownStreamExpander != agNULL)
 1808         {
 1809           DownStreamExpander->currentUpStreamPhyIndex = 0;
 1810         }
 1811         /* debugging */
 1812         if (ReturningExpander != agNULL)
 1813         {
 1814           DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
 1815           DM_DBG3(("dmConfigRoutingInfoRespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
 1816           ReturningExpanderDeviceData = ReturningExpander->dmDevice;
 1817         }
 1818 
 1819         /* No longer in DISCOVERY_CONFIG_ROUTING */
 1820         onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
 1821 
 1822         if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
 1823         {
 1824       /* If not the last phy */
 1825           if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
 1826           {
 1827             DM_DBG3(("dmConfigRoutingInfoRespRcvd: More Phys to discover\n"));
 1828             /* continue discovery for the next phy */
 1829             /* needs to send only one Discovery not multiple times */
 1830             if (ReturningExpander->discoverSMPAllowed == agTRUE)
 1831             {
 1832               dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
 1833             }
 1834             if (ReturningExpander != agNULL)
 1835             {
 1836               ReturningExpander->discoverSMPAllowed = agFALSE;
 1837             }
 1838           }
 1839           /* If the last phy */
 1840           else
 1841           {
 1842             DM_DBG3(("dmConfigRoutingInfoRespRcvd: No More Phys\n"));
 1843             ReturningExpander->discoverSMPAllowed = agTRUE;
 1844 
 1845             /* remove the expander from the discovering list */
 1846             dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
 1847             /* continue downstream discovering */
 1848             dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
 1849 
 1850             //DownStreamExpander
 1851           }
 1852     }
 1853       }
 1854     }
 1855   }
 1856   else
 1857   {
 1858     DM_DBG1(("dmConfigRoutingInfoRespRcvd: Discovery Error SMP function return result error=0x%x !!!\n", frameHeader->smpFunctionResult));
 1859     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 1860   }
 1861   return;
 1862 }
 1863 
 1864 osGLOBAL void
 1865 dmConfigRoutingInfo2RespRcvd(
 1866                             dmRoot_t              *dmRoot,
 1867                             agsaRoot_t            *agRoot,
 1868                             agsaIORequest_t       *agIORequest,
 1869                             dmDeviceData_t        *oneDeviceData,
 1870                             dmSMPFrameHeader_t    *frameHeader,
 1871                             agsaFrameHandle_t     frameHandle
 1872                            )
 1873 {
 1874   dmExpander_t                            *oneExpander = oneDeviceData->dmExpander;
 1875   dmExpander_t                            *UpStreamExpander;
 1876   dmExpander_t                            *DownStreamExpander;
 1877   dmExpander_t                            *ReturningExpander;
 1878   dmExpander_t                            *ConfigurableExpander;
 1879 
 1880   dmIntPortContext_t                      *onePortContext;
 1881   dmDeviceData_t                          *ReturningExpanderDeviceData = agNULL;
 1882   bit32                                   dupConfigSASAddr = agFALSE;
 1883 
 1884   DM_DBG2(("dmConfigRoutingInfo2RespRcvd: start\n"));
 1885   DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrHi 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressHi));
 1886   DM_DBG2(("dmConfigRoutingInfo2RespRcvd: exp addrLo 0x%08x\n", oneExpander->dmDevice->SASAddressID.sasAddressLo));
 1887 
 1888   onePortContext = oneDeviceData->dmPortContext;
 1889 
 1890   if (dmDiscoverCheck(dmRoot, onePortContext) == agTRUE)
 1891   {
 1892     DM_DBG1(("dmConfigRoutingInfo2RespRcvd: invalid port or aborted discovery!!!\n"));
 1893     return;
 1894   }
 1895 
 1896   if (frameHeader->smpFunctionResult == PHY_VACANT)
 1897   {
 1898     DM_DBG1(("dmConfigRoutingInfo2RespRcvd: smpFunctionResult is PHY_VACANT\n"));
 1899   }
 1900 
 1901   if ( frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED ||
 1902        frameHeader->smpFunctionResult == PHY_VACANT
 1903      )
 1904   {
 1905     DownStreamExpander = oneExpander->dmCurrentDownStreamExpander;
 1906     if (DownStreamExpander != agNULL)
 1907     {
 1908       DownStreamExpander->currentUpStreamPhyIndex ++;
 1909       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
 1910       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->numOfUpStreamPhys %d\n", DownStreamExpander->numOfUpStreamPhys));
 1911       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrHi 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressHi));
 1912       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander addrLo 0x%08x\n", DownStreamExpander->dmDevice->SASAddressID.sasAddressLo));
 1913 
 1914     }
 1915 
 1916     oneExpander->currentDownStreamPhyIndex++;
 1917     DM_DBG2(("dmConfigRoutingInfo2RespRcvd: oneExpander->currentDownStreamPhyIndex %d oneExpander->numOfDownStreamPhys %d\n", oneExpander->currentDownStreamPhyIndex, oneExpander->numOfDownStreamPhys));
 1918 
 1919     if ( (DownStreamExpander != agNULL) &&
 1920          (DownStreamExpander->currentUpStreamPhyIndex < DownStreamExpander->numOfUpStreamPhys)
 1921        )
 1922     {
 1923       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: first if\n"));
 1924       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->currentUpStreamPhyIndex %d\n", DownStreamExpander->currentUpStreamPhyIndex));
 1925 
 1926       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: DownStreamExpander->upStreamPhys[] %d\n", DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex]));
 1927 
 1928       dmRoutingEntryAdd(dmRoot,
 1929                         oneExpander,
 1930                         DownStreamExpander->upStreamPhys[DownStreamExpander->currentUpStreamPhyIndex],
 1931                         oneExpander->configSASAddressHi,
 1932                         oneExpander->configSASAddressLo
 1933                        );
 1934     }
 1935     else
 1936     {
 1937       /* traversing up till discovery Root onePortContext->discovery.RootExp */
 1938       DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else\n"));
 1939 
 1940       UpStreamExpander = oneExpander->dmUpStreamExpander;
 1941       ConfigurableExpander = dmFindConfigurableExp(dmRoot, onePortContext, oneExpander);
 1942       if (UpStreamExpander != agNULL)
 1943       {
 1944         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrHi 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressHi));
 1945         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander addrLo 0x%08x\n", UpStreamExpander->dmDevice->SASAddressID.sasAddressLo));
 1946       }
 1947       else
 1948       {
 1949         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: UpStreamExpander is NULL\n"));
 1950       }
 1951       dupConfigSASAddr = dmDuplicateConfigSASAddr(dmRoot,
 1952                                                   ConfigurableExpander,
 1953                                                   oneExpander->configSASAddressHi,
 1954                                                   oneExpander->configSASAddressLo
 1955                                                   );
 1956 
 1957       if ( ConfigurableExpander != agNULL && dupConfigSASAddr == agFALSE)
 1958       {
 1959         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: else if\n"));
 1960 
 1961         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrHi 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressHi));
 1962         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander addrLo 0x%08x\n", ConfigurableExpander->dmDevice->SASAddressID.sasAddressLo));
 1963 
 1964         if ( UpStreamExpander != agNULL)
 1965         {
 1966     UpStreamExpander->dmCurrentDownStreamExpander = oneExpander;
 1967         }
 1968         ConfigurableExpander->currentDownStreamPhyIndex =
 1969                 dmFindCurrentDownStreamPhyIndex(dmRoot, ConfigurableExpander);
 1970         ConfigurableExpander->dmReturnginExpander = oneExpander->dmReturnginExpander;
 1971         if ( DownStreamExpander != agNULL)
 1972         {
 1973           DownStreamExpander->currentUpStreamPhyIndex = 0;
 1974         }
 1975         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->currentDownStreamPhyIndex %d\n", ConfigurableExpander->currentDownStreamPhyIndex));
 1976 
 1977         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ConfigurableExpander->downStreamPhys[] %d\n", ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex]));
 1978         dmRoutingEntryAdd(dmRoot,
 1979                           ConfigurableExpander,
 1980                           ConfigurableExpander->downStreamPhys[ConfigurableExpander->currentDownStreamPhyIndex],
 1981                           oneExpander->configSASAddressHi,
 1982                           oneExpander->configSASAddressLo
 1983                          );
 1984       }
 1985       else
 1986       {
 1987         /* going back to where it was */
 1988         /* ConfigRoutingInfo is done for a target */
 1989         DM_DBG2(("dmConfigRoutingInfo2RespRcvd: $$$$$$ my change $$$$$ \n"));
 1990         ReturningExpander = oneExpander->dmReturnginExpander;
 1991         if ( DownStreamExpander != agNULL)
 1992         {
 1993           DownStreamExpander->currentUpStreamPhyIndex = 0;
 1994         }
 1995         /* debugging */
 1996         if (ReturningExpander != agNULL)
 1997         {
 1998            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrHi 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressHi));
 1999            DM_DBG2(("dmConfigRoutingInfo2RespRcvd: ReturningExpander addrLo 0x%08x\n", ReturningExpander->dmDevice->SASAddressID.sasAddressLo));
 2000            ReturningExpanderDeviceData = ReturningExpander->dmDevice;
 2001         }
 2002 
 2003         /* No longer in DISCOVERY_CONFIG_ROUTING */
 2004         onePortContext->discovery.status = DISCOVERY_DOWN_STREAM;
 2005 
 2006         if (ReturningExpander != agNULL && ReturningExpanderDeviceData != agNULL)
 2007         {
 2008       /* If not the last phy */
 2009           if ( ReturningExpander->discoveringPhyId < ReturningExpanderDeviceData->numOfPhys )
 2010           {
 2011             DM_DBG2(("dmConfigRoutingInfo2RespRcvd: More Phys to discover\n"));
 2012             /* continue discovery for the next phy */
 2013             /* needs to send only one Discovery not multiple times */
 2014             if (ReturningExpander->discoverSMPAllowed == agTRUE)
 2015             {
 2016               dmDiscoverSend(dmRoot, ReturningExpanderDeviceData);
 2017             }
 2018             if (ReturningExpander != agNULL)
 2019             {
 2020               ReturningExpander->discoverSMPAllowed = agFALSE;
 2021             }
 2022           }
 2023           /* If the last phy */
 2024           else
 2025           {
 2026             DM_DBG2(("dmConfigRoutingInfo2RespRcvd: No More Phys\n"));
 2027             ReturningExpander->discoverSMPAllowed = agTRUE;
 2028 
 2029             /* remove the expander from the discovering list */
 2030             dmDiscoveringExpanderRemove(dmRoot, onePortContext, ReturningExpander);
 2031             /* continue downstream discovering */
 2032             dmDownStreamDiscovering(dmRoot, onePortContext, ReturningExpanderDeviceData);
 2033 
 2034             //DownStreamExpander
 2035           }
 2036         }
 2037       }
 2038     }
 2039   }
 2040   else
 2041   {
 2042     DM_DBG1(("dmConfigRoutingInfo2RespRcvd: Discovery Error SMP function return result error=0x%x!!!\n", frameHeader->smpFunctionResult));
 2043     dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2044   }
 2045   return;
 2046 }
 2047 
 2048 
 2049 /* no task management case here for phyControl*/
 2050 
 2051 /* no task management case here for phyControl*/
 2052 osGLOBAL void
 2053 dmPhyControlRespRcvd(
 2054                      dmRoot_t              *dmRoot,
 2055                      agsaRoot_t            *agRoot,
 2056                      agsaIORequest_t       *agIORequest,
 2057                      dmDeviceData_t        *oneDeviceData,
 2058                      dmSMPFrameHeader_t    *frameHeader,
 2059                      agsaFrameHandle_t     frameHandle
 2060                     )
 2061 {
 2062   DM_DBG3(("dmPhyControlRespRcvd: start\n"));
 2063   DM_DBG3(("dmPhyControlRespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
 2064   DM_DBG3(("dmPhyControlRespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
 2065 
 2066   if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2067   {
 2068     DM_DBG3(("dmPhyControlRespRcvd: SMP success\n"));
 2069   }
 2070   else
 2071   {
 2072     DM_DBG1(("dmPhyControlRespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
 2073   }
 2074 
 2075   return;
 2076 }
 2077 
 2078 /* no task management case here for phyControl*/
 2079 osGLOBAL void
 2080 dmPhyControl2RespRcvd(
 2081                      dmRoot_t              *dmRoot,
 2082                      agsaRoot_t            *agRoot,
 2083                      agsaIORequest_t       *agIORequest,
 2084                      dmDeviceData_t        *oneDeviceData,
 2085                      dmSMPFrameHeader_t    *frameHeader,
 2086                      agsaFrameHandle_t     frameHandle
 2087                     )
 2088 {
 2089   DM_DBG2(("dmPhyControl2RespRcvd: start\n"));
 2090   DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
 2091   DM_DBG2(("dmPhyControl2RespRcvd: expander device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
 2092 
 2093   if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2094   {
 2095     DM_DBG2(("dmPhyControl2RespRcvd: SMP success\n"));
 2096   }
 2097   else
 2098   {
 2099     DM_DBG1(("dmPhyControl2RespRcvd: SMP failure; result 0x%x !!!\n", frameHeader->smpFunctionResult));
 2100   }
 2101 
 2102   return;
 2103 }
 2104 
 2105 osGLOBAL void
 2106 dmPhyControlFailureRespRcvd(
 2107                             dmRoot_t              *dmRoot,
 2108                             agsaRoot_t            *agRoot,
 2109                             dmDeviceData_t        *oneDeviceData,
 2110                             dmSMPFrameHeader_t    *frameHeader,
 2111                             agsaFrameHandle_t     frameHandle
 2112                            )
 2113 {
 2114   DM_DBG1(("dmPhyControlFailureRespRcvd: start\n"));
 2115   return;
 2116 }
 2117 
 2118 GLOBAL void dmSetDeviceInfoCB(
 2119                                 agsaRoot_t        *agRoot,
 2120                                 agsaContext_t     *agContext,
 2121                                 agsaDevHandle_t   *agDevHandle,
 2122                                 bit32             status,
 2123                                 bit32             option,
 2124                                 bit32             param
 2125                                 )
 2126 {
 2127   dmRoot_t                  *dmRoot = agNULL;
 2128   agsaIORequest_t           *agIORequest;
 2129   bit32                     smstatus;
 2130   agsaSASRequestBody_t      *agSASRequestBody;
 2131   dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
 2132   dmIntPortContext_t        *onePortContext = agNULL;
 2133   dmDeviceData_t            *oneDeviceData;
 2134   bit8                      SMPRequestFunction;
 2135   bit8                      devType_S_Rate;
 2136   DM_DBG1(("dmSetDeviceInfoCB: start\n"));
 2137   DM_DBG4(("dmSetDeviceInfoCB: status 0x%x\n", status));
 2138   DM_DBG4(("dmSetDeviceInfoCB: option 0x%x\n", option));
 2139   DM_DBG4(("dmSetDeviceInfoCB: param 0x%x\n", param));
 2140   if (status != OSSA_SUCCESS)
 2141   {
 2142     DM_DBG1(("dmSetDeviceInfoCB: status %d\n", status));
 2143     DM_DBG1(("dmSetDeviceInfoCB: option 0x%x\n", option));
 2144     DM_DBG1(("dmSetDeviceInfoCB: param 0x%x\n", param));
 2145     if (option == 32) /* set connection rate */
 2146     {
 2147       DM_DBG1(("dmSetDeviceInfoCB: IO failure\n"));
 2148       agIORequest = (agsaIORequest_t *)agContext->osData;
 2149       dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
 2150       dmRoot = dmSMPRequestBody->dmRoot;
 2151       oneDeviceData = dmSMPRequestBody->dmDevice;
 2152       onePortContext = oneDeviceData->dmPortContext;
 2153       SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
 2154       if (SMPRequestFunction == SMP_REPORT_GENERAL ||
 2155           SMPRequestFunction == SMP_DISCOVER ||
 2156           SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2157           SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2158         )
 2159       {
 2160         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2161       }
 2162       else if (SMPRequestFunction == SMP_PHY_CONTROL)
 2163       {
 2164         /* task management failure */
 2165         dmPhyControlFailureRespRcvd(
 2166                                     dmRoot,
 2167                                     agRoot,
 2168                                     oneDeviceData,
 2169                                     agNULL,
 2170                                     agNULL
 2171                                    );
 2172       }
 2173     }
 2174   }
 2175   if (agDevHandle == agNULL)
 2176   {
 2177     DM_DBG1(("dmSetDeviceInfoCB: agDevHandle is NULL\n"));
 2178     return;
 2179   }
 2180 
 2181   /* retry SMP */
 2182   if (option == 32) /* set connection rate */
 2183   {
 2184     DM_DBG1(("dmSetDeviceInfoCB: set connection rate option\n"));
 2185     agIORequest = (agsaIORequest_t *)agContext->osData;
 2186     dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
 2187     dmRoot = dmSMPRequestBody->dmRoot;
 2188     agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
 2189     oneDeviceData = dmSMPRequestBody->dmDevice;
 2190     onePortContext = oneDeviceData->dmPortContext;
 2191     devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
 2192     devType_S_Rate = (devType_S_Rate & 0xF0) | (param >> 28);
 2193     oneDeviceData->agDeviceInfo.devType_S_Rate =  devType_S_Rate;
 2194     SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
 2195     DM_DBG1(("dmSetDeviceInfoCB: SMPRequestFunction 0x%x\n", SMPRequestFunction));
 2196     DM_DBG1(("dmSetDeviceInfoCB: new rate is 0x%x\n", DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo)));
 2197     smstatus = saSMPStart(
 2198                           agRoot,
 2199                           agIORequest,
 2200                           0,
 2201                           agDevHandle,
 2202                           AGSA_SMP_INIT_REQ,
 2203                           agSASRequestBody,
 2204                           &dmsaSMPCompleted
 2205                          );
 2206     if (status == AGSA_RC_SUCCESS)
 2207     {
 2208       /* increment the number of pending SMP */
 2209       onePortContext->discovery.pendingSMP++;
 2210 //          dmSMPRequestBody->retries++;
 2211       if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 2212           SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2213           SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2214          )
 2215       {
 2216         /* start discovery-related SMP timer */
 2217         dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)SMPRequestFunction, dmSMPRequestBody);
 2218       }
 2219       return;
 2220     }
 2221     else if (status == AGSA_RC_BUSY)
 2222     {
 2223       onePortContext->discovery.pendingSMP++;
 2224 //          dmSMPRequestBody->retries++;
 2225       if (SMPRequestFunction == SMP_REPORT_GENERAL ||
 2226           SMPRequestFunction == SMP_DISCOVER ||
 2227           SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2228           SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2229          )
 2230       {
 2231         dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
 2232       }
 2233       else if (SMPRequestFunction == SMP_PHY_CONTROL)
 2234       {
 2235         /* For taskmanagement SMP, let's fail task management failure */
 2236         dmPhyControlFailureRespRcvd(
 2237                                     dmRoot,
 2238                                     agRoot,
 2239                                     oneDeviceData,
 2240                                     agNULL,
 2241                                     agNULL
 2242                                    );
 2243       }
 2244       else
 2245       {
 2246       }
 2247     }
 2248     else /* AGSA_RC_FAILURE */
 2249     {
 2250       if (SMPRequestFunction == SMP_REPORT_GENERAL ||
 2251           SMPRequestFunction == SMP_DISCOVER ||
 2252           SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2253           SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2254          )
 2255       {
 2256         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2257       }
 2258       else if (SMPRequestFunction == SMP_PHY_CONTROL)
 2259       {
 2260         /* task management failure */
 2261         dmPhyControlFailureRespRcvd(
 2262                                     dmRoot,
 2263                                     agRoot,
 2264                                     oneDeviceData,
 2265                                     agNULL,
 2266                                     agNULL
 2267                                    );
 2268       }
 2269       else
 2270       {
 2271       }
 2272     }
 2273   }
 2274   return;
 2275 }
 2276 /* smp completion */
 2277 osGLOBAL void
 2278 dmSMPCompleted(
 2279                agsaRoot_t            *agRoot,
 2280                agsaIORequest_t       *agIORequest,
 2281                bit32                 agIOStatus,
 2282                bit32                 agIOInfoLen,
 2283                agsaFrameHandle_t     agFrameHandle
 2284               )
 2285 {
 2286   dmIntRoot_t               *dmIntRoot    = agNULL;
 2287   dmIntContext_t            *dmAllShared = agNULL;
 2288   dmSMPRequestBody_t        *dmSMPRequestBody = agNULL;
 2289   agsaSMPFrame_t            *agSMPFrame;
 2290   dmRoot_t                  *dmRoot = agNULL;
 2291   dmIntPortContext_t        *onePortContext = agNULL;
 2292   dmIntPortContext_t        *oldonePortContext;
 2293   dmExpander_t              *oneExpander = agNULL;
 2294   dmDeviceData_t            *oneDeviceData;
 2295   agsaDevHandle_t           *agDevHandle = agNULL;
 2296   agsaSASRequestBody_t      *agSASRequestBody;
 2297   bit8                      smpHeader[4];
 2298   bit8                      SMPRequestFunction;
 2299   dmSMPFrameHeader_t        *dmResponseSMPFrameHeader;
 2300   dmSMPFrameHeader_t        *dmSMPFrameHeader;
 2301   bit8                      *dmSMPPayload;
 2302   smpReqPhyControl_t        *smpPhyControlReq;
 2303   smpReqPhyControl2_t       *smpPhyControl2Req;
 2304 #ifndef DIRECT_SMP
 2305   dmSMPRequestBody_t        *dmSMPResponseBody = agNULL;
 2306   dmSMPFrameHeader_t        *dmRequestSMPFrameHeader;
 2307   bit8                      smpRequestHeader[4];
 2308 #endif
 2309   bit32                     status;
 2310   bit32                     ConnRate = SAS_CONNECTION_RATE_12_0G;
 2311   agsaContext_t             *agContext = agNULL;
 2312 
 2313   DM_DBG3(("dmSMPCompleted: start\n"));
 2314 
 2315   dmSMPRequestBody = (dmSMPRequestBody_t *)agIORequest->osData;
 2316 
 2317   dmRoot = dmSMPRequestBody->dmRoot;
 2318   dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
 2319   dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
 2320 
 2321   oneDeviceData = dmSMPRequestBody->dmDevice;
 2322   agSASRequestBody = &(dmSMPRequestBody->agSASRequestBody);
 2323   agSMPFrame = &(agSASRequestBody->smpFrame);
 2324 
 2325   if (oneDeviceData->valid == agFALSE &&
 2326       oneDeviceData->valid2 == agFALSE &&
 2327       oneDeviceData->dmPortContext == agNULL &&
 2328       dmSMPRequestBody->dmPortContext->valid == agFALSE
 2329       )
 2330   {
 2331     DM_DBG3(("dmSMPCompleted: port has been destroyed\n"));
 2332     /* all device, port information have been reset
 2333        just put smp to freeList
 2334     */
 2335     /* SMP request */
 2336     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2337     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2338     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2339 
 2340 #ifndef DIRECT_SMP
 2341     /* SMP response */
 2342     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2343     if (dmSMPResponseBody == agNULL)
 2344     {
 2345       DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2346       return;
 2347     }
 2348     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2349     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2350     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2351 #endif
 2352     return;
 2353   }
 2354 
 2355   onePortContext = oneDeviceData->dmPortContext;
 2356   oneExpander = oneDeviceData->dmExpander;
 2357   agDevHandle = oneExpander->agDevHandle;
 2358 
 2359 
 2360 #ifdef DIRECT_SMP
 2361   SMPRequestFunction = dmSMPRequestBody->smpPayload[1];
 2362 #else
 2363   saFrameReadBlock(agRoot, dmSMPRequestBody->IndirectSMP, 0, smpRequestHeader, 4);
 2364   dmRequestSMPFrameHeader = (dmSMPFrameHeader_t *)smpRequestHeader;
 2365   SMPRequestFunction = dmRequestSMPFrameHeader->smpFunction;
 2366 #endif
 2367 
 2368 #ifdef NOT_IN_USE
 2369   /* for debugging; dump SMP request payload */
 2370   dmhexdump("smp payload",
 2371             (bit8 *)agSASRequestBody->smpFrame.outFrameBuf,
 2372             agSASRequestBody->smpFrame.outFrameLen
 2373            );
 2374   dmhexdump("smp payload new",
 2375             (bit8 *)dmSMPRequestBody->smpPayload,
 2376             agSASRequestBody->smpFrame.outFrameLen
 2377            );
 2378 #endif
 2379 
 2380   /* sanity check */
 2381   if (onePortContext != agNULL)
 2382   {
 2383     DM_DBG5(("dmSMPCompleted: pid %d\n", onePortContext->id));
 2384   }
 2385   else
 2386   {
 2387     DM_DBG1(("dmSMPCompleted: Wrong, onePortContext is NULL!!!\n"));
 2388     /* SMP request */
 2389     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2390     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2391     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2392 
 2393 #ifndef DIRECT_SMP
 2394     /* SMP response */
 2395     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2396     if (dmSMPResponseBody == agNULL)
 2397     {
 2398       DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2399       return;
 2400     }
 2401     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2402     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2403     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2404 #endif
 2405     return;
 2406   }
 2407 
 2408   oldonePortContext = dmSMPRequestBody->dmPortContext;
 2409   if (oldonePortContext != agNULL)
 2410   {
 2411     DM_DBG5(("dmSMPCompleted: old pid %d\n", oldonePortContext->id));
 2412   }
 2413   else
 2414   {
 2415     DM_DBG1(("dmSMPCompleted: Wrong, oldonePortContext is NULL!!!\n"));
 2416     /* SMP request */
 2417     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2418     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2419     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2420 
 2421 #ifndef DIRECT_SMP
 2422     /* SMP response */
 2423     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2424     if (dmSMPResponseBody == agNULL)
 2425     {
 2426       DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2427       return;
 2428     }
 2429     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2430     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2431     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2432 #endif
 2433     return;
 2434   }
 2435 
 2436   /* decrement the number of pending SMP */
 2437   onePortContext->discovery.pendingSMP--;
 2438 
 2439 
 2440   /* for port invalid case;
 2441      full discovery -> full discovery; incremental discovery -> full discovery
 2442    */
 2443   if (onePortContext != oldonePortContext)
 2444   {
 2445     DM_DBG1(("dmSMPCompleted: portcontext has changed!!!\n"));
 2446     if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 2447         SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2448         SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2449         )
 2450     {
 2451       /* stop SMP timer */
 2452       tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2453       if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2454       {
 2455         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2456         dmKillTimer(
 2457                       dmRoot,
 2458                       &(onePortContext->discovery.DiscoverySMPTimer)
 2459                      );
 2460       }
 2461       else
 2462       {
 2463         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2464       }
 2465 
 2466       tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2467       if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2468       {
 2469         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2470         dmKillTimer(
 2471                       dmRoot,
 2472                       &(oldonePortContext->discovery.DiscoverySMPTimer)
 2473                      );
 2474       }
 2475       else
 2476       {
 2477         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2478       }
 2479     }
 2480     /* clean up expanders data strucures; move to free exp when device is cleaned */
 2481     dmCleanAllExp(dmRoot, oldonePortContext);
 2482     /* remove devices */
 2483     dmInternalRemovals(dmRoot, oldonePortContext);
 2484 
 2485     /* SMP request */
 2486     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2487     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2488     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2489 
 2490 #ifndef DIRECT_SMP
 2491     /* SMP response */
 2492     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2493     if (dmSMPResponseBody == agNULL)
 2494     {
 2495       DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2496       return;
 2497     }
 2498     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2499     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2500     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2501 #endif
 2502 
 2503 
 2504     return;
 2505   }
 2506 
 2507   if (onePortContext->valid == agFALSE ||
 2508       onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
 2509       onePortContext->discovery.status == DISCOVERY_SAS_DONE  ||
 2510       onePortContext->DiscoveryAbortInProgress == agTRUE
 2511      )
 2512   {
 2513     if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 2514         SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2515         SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2516         )
 2517     {
 2518       /* stop SMP timer */
 2519       tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2520       if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2521       {
 2522         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2523         dmKillTimer(
 2524                     dmRoot,
 2525                     &(onePortContext->discovery.DiscoverySMPTimer)
 2526                    );
 2527       }
 2528       else
 2529       {
 2530         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2531       }
 2532 
 2533 
 2534 
 2535       tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2536       if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2537       {
 2538         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2539         dmKillTimer(
 2540                     dmRoot,
 2541                     &(oldonePortContext->discovery.DiscoverySMPTimer)
 2542                    );
 2543       }
 2544       else
 2545       {
 2546         tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2547       }
 2548     }
 2549 
 2550     /* SMP request */
 2551     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2552     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2553     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2554 
 2555 #ifndef DIRECT_SMP
 2556     /* SMP response */
 2557     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2558     if (dmSMPResponseBody == agNULL)
 2559     {
 2560       DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2561       return;
 2562     }
 2563     tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2564     DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2565     tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2566 #endif
 2567 
 2568     if (onePortContext->discovery.pendingSMP == 0)
 2569     {
 2570       DM_DBG1(("dmSMPCompleted: aborting discovery\n"));
 2571       if (onePortContext->DiscoveryState == DM_DSTATE_COMPLETED ||
 2572           onePortContext->discovery.status == DISCOVERY_SAS_DONE ||
 2573           onePortContext->DiscoveryAbortInProgress == agTRUE
 2574          )
 2575       {
 2576         onePortContext->DiscoveryAbortInProgress = agFALSE;
 2577         onePortContext->DiscoveryState = DM_DSTATE_COMPLETED;
 2578         onePortContext->discovery.status = DISCOVERY_SAS_DONE;
 2579         dmCleanAllExp(dmRoot, onePortContext);
 2580         if ( onePortContext->DiscoveryAbortInProgress == agTRUE)
 2581         {
 2582           tddmDiscoverCB(
 2583                          dmRoot,
 2584                          onePortContext->dmPortContext,
 2585                          dmDiscAborted
 2586                   );
 2587         }
 2588       }
 2589     }
 2590     else
 2591     {
 2592       DM_DBG3(("dmSMPCompleted: not yet abort; non zero pendingSMP %d\n", onePortContext->discovery.pendingSMP));
 2593     }
 2594     return;
 2595   }
 2596 
 2597   if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 2598       SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2599       SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2600       )
 2601   {
 2602     /* stop SMP timer */
 2603     tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2604     if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2605     {
 2606       tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2607       dmKillTimer(
 2608                   dmRoot,
 2609                   &(onePortContext->discovery.DiscoverySMPTimer)
 2610                  );
 2611     }
 2612     else
 2613     {
 2614       tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2615     }
 2616 
 2617 
 2618     tddmSingleThreadedEnter(dmRoot, DM_TIMER_LOCK);
 2619     if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE)
 2620     {
 2621       tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2622       dmKillTimer(
 2623                   dmRoot,
 2624                   &(oldonePortContext->discovery.DiscoverySMPTimer)
 2625                  );
 2626     }
 2627     else
 2628     {
 2629       tddmSingleThreadedLeave(dmRoot, DM_TIMER_LOCK);
 2630     }
 2631   }
 2632 
 2633   if (oneExpander->SAS2 == 0)
 2634   {
 2635     DM_DBG3(("dmSMPCompleted: SAS 1.1\n"));
 2636     if (agIOStatus == OSSA_IO_SUCCESS)
 2637     {
 2638       //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
 2639       /* parsing SMP payload */
 2640 #ifdef DIRECT_SMP
 2641       saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 2642 #else
 2643       dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2644       saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
 2645 #endif
 2646       dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 2647 
 2648       /* SMP function dependent payload */
 2649       switch (dmResponseSMPFrameHeader->smpFunction)
 2650       {
 2651       case SMP_REPORT_GENERAL:
 2652         DM_DBG3(("dmSMPCompleted: report general\n"));
 2653         if (agIOInfoLen != sizeof(smpRespReportGeneral_t) + 4 &&
 2654             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2655         {
 2656           DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportGeneral_t) + 4));
 2657           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2658 
 2659           /* SMP request */
 2660           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2661           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2662           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2663 
 2664 #ifndef DIRECT_SMP
 2665           /* SMP response */
 2666           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2667           if (dmSMPResponseBody == agNULL)
 2668           {
 2669             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2670             return;
 2671           }
 2672           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2673           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2674           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2675 #endif
 2676           return;
 2677         }
 2678         /* start here */
 2679         dmReportGeneralRespRcvd(
 2680                                 dmRoot,
 2681                                 agRoot,
 2682                                 agIORequest,
 2683                                 oneDeviceData,
 2684                                 dmResponseSMPFrameHeader,
 2685                                 agFrameHandle
 2686                                 );
 2687         break;
 2688       case SMP_DISCOVER:
 2689         DM_DBG3(("dmSMPCompleted: discover\n"));
 2690         if (agIOInfoLen != sizeof(smpRespDiscover_t) + 4 &&
 2691             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2692         {
 2693           DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespDiscover_t) + 4));
 2694           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2695           /* SMP request */
 2696           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2697           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2698           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2699 
 2700 #ifndef DIRECT_SMP
 2701           /* SMP response */
 2702           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2703           if (dmSMPResponseBody == agNULL)
 2704           {
 2705             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2706             return;
 2707           }
 2708           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2709           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2710           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2711 #endif
 2712           return;
 2713         }
 2714         dmDiscoverRespRcvd(
 2715                            dmRoot,
 2716                            agRoot,
 2717                            agIORequest,
 2718                            oneDeviceData,
 2719                            dmResponseSMPFrameHeader,
 2720                            agFrameHandle
 2721                            );
 2722         break;
 2723       case SMP_REPORT_PHY_SATA:
 2724         DM_DBG3(("dmSMPCompleted: report phy sata\n"));
 2725         if (agIOInfoLen != sizeof(smpRespReportPhySata_t) + 4 &&
 2726             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2727         {
 2728           DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportPhySata_t) + 4));
 2729           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2730           /* SMP request */
 2731           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2732           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2733           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2734 
 2735 #ifndef DIRECT_SMP
 2736           /* SMP response */
 2737           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2738           if (dmSMPResponseBody == agNULL)
 2739           {
 2740             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2741             return;
 2742           }
 2743           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2744           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2745           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2746 #endif
 2747           return;
 2748         }
 2749         dmReportPhySataRcvd(
 2750                             dmRoot,
 2751                             agRoot,
 2752                             agIORequest,
 2753                             oneDeviceData,
 2754                             dmResponseSMPFrameHeader,
 2755                             agFrameHandle
 2756                             );
 2757         break;
 2758       case SMP_CONFIGURE_ROUTING_INFORMATION:
 2759         DM_DBG3(("dmSMPCompleted: configure routing information\n"));
 2760         if (agIOInfoLen != 4 &&
 2761             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
 2762         {
 2763           DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
 2764           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2765           /* SMP request */
 2766           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2767           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2768           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2769 
 2770 #ifndef DIRECT_SMP
 2771           /* SMP response */
 2772           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2773           if (dmSMPResponseBody == agNULL)
 2774           {
 2775             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2776             return;
 2777           }
 2778           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2779           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2780           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2781 #endif
 2782           return;
 2783         }
 2784         dmConfigRoutingInfoRespRcvd(
 2785                                     dmRoot,
 2786                                     agRoot,
 2787                                     agIORequest,
 2788                                     oneDeviceData,
 2789                                     dmResponseSMPFrameHeader,
 2790                                     agFrameHandle
 2791                                     );
 2792 
 2793         break;
 2794       case SMP_PHY_CONTROL:
 2795         DM_DBG3(("dmSMPCompleted: phy control\n"));
 2796         if (agIOInfoLen != 4 &&
 2797             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */
 2798         {
 2799           DM_DBG3(("dmSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
 2800           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2801 
 2802           /* SMP request */
 2803           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2804           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 2805           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2806 
 2807 #ifndef DIRECT_SMP
 2808           /* SMP response */
 2809           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 2810           if (dmSMPResponseBody == agNULL)
 2811           {
 2812             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 2813             return;
 2814           }
 2815           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 2816           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 2817           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 2818 #endif
 2819           return;
 2820         }
 2821         dmPhyControlRespRcvd(
 2822                              dmRoot,
 2823                              agRoot,
 2824                              agIORequest,
 2825                              oneDeviceData,
 2826                              dmResponseSMPFrameHeader,
 2827                              agFrameHandle
 2828                             );
 2829         break;
 2830       case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
 2831       case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
 2832       case SMP_PHY_TEST_FUNCTION: /* fall through */
 2833       case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
 2834       case SMP_READ_GPIO_REGISTER: /* fall through */
 2835       case SMP_WRITE_GPIO_REGISTER: /* fall through */
 2836       default:
 2837         DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunction));
 2838         DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x !!!\n", dmResponseSMPFrameHeader->smpFrameType));
 2839         DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x !!!\n", dmResponseSMPFrameHeader->smpFunctionResult));
 2840         DM_DBG1(("dmSMPCompleted: smpReserved 0x%x !!!\n", dmResponseSMPFrameHeader->smpReserved));
 2841         dmhexdump("dmSMPCompleted: SMP payload !!!", (bit8 *)agFrameHandle, agIOInfoLen);
 2842         break;
 2843       } /* switch */
 2844     } /* OSSA_IO_SUCCESS */
 2845     else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
 2846     {
 2847       /* no retry this case */
 2848       DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
 2849     }
 2850     else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
 2851     {
 2852       DM_DBG3(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
 2853       saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 2854       dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 2855 
 2856       status = saSMPStart(
 2857                  agRoot,
 2858                  agIORequest,
 2859                  0,
 2860                  agDevHandle,
 2861                  AGSA_SMP_INIT_REQ,
 2862                  agSASRequestBody,
 2863                  &dmsaSMPCompleted
 2864                  );
 2865 
 2866       if (status == AGSA_RC_SUCCESS)
 2867       {
 2868         /* increment the number of pending SMP */
 2869         onePortContext->discovery.pendingSMP++;
 2870         if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 2871             SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2872             SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2873            )
 2874         {
 2875           /* start discovery-related SMP timer */
 2876           dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
 2877         }
 2878         return;
 2879       }
 2880       else if (status == AGSA_RC_BUSY)
 2881       {
 2882         if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 2883             dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 2884             dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 2885             dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2886            )
 2887         {
 2888           dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
 2889         }
 2890         else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 2891         {
 2892           /* For taskmanagement SMP, let's fail task management failure */
 2893           dmPhyControlFailureRespRcvd(
 2894                                       dmRoot,
 2895                                       agRoot,
 2896                                       oneDeviceData,
 2897                                       dmResponseSMPFrameHeader,
 2898                                       agFrameHandle
 2899                                      );
 2900         }
 2901         else
 2902         {
 2903         }
 2904       }
 2905       else /* AGSA_RC_FAILURE */
 2906       {
 2907         if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 2908             dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 2909             dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 2910             dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2911            )
 2912         {
 2913           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2914         }
 2915         else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 2916         {
 2917           /* task management failure */
 2918           dmPhyControlFailureRespRcvd(
 2919                                       dmRoot,
 2920                                       agRoot,
 2921                                       oneDeviceData,
 2922                                       dmResponseSMPFrameHeader,
 2923                                       agFrameHandle
 2924                                      );
 2925         }
 2926         else
 2927         {
 2928         }
 2929       }
 2930     }   /* OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE*/
 2931     else
 2932     {
 2933       if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
 2934           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
 2935           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
 2936           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
 2937           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
 2938           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
 2939           agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
 2940       {
 2941         DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
 2942         saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
 2943       }
 2944       if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
 2945       {
 2946         DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
 2947         DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
 2948         ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
 2949         if (ConnRate == SAS_CONNECTION_RATE_1_5G)
 2950         {
 2951           /* no retry; failure ??? */
 2952           if (SMPRequestFunction == SMP_REPORT_GENERAL ||
 2953               SMPRequestFunction == SMP_DISCOVER ||
 2954               SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 2955               SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 2956              )
 2957           {
 2958             dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 2959           }
 2960           else if (SMPRequestFunction == SMP_PHY_CONTROL)
 2961           {
 2962             /* task management failure */
 2963             dmPhyControlFailureRespRcvd(
 2964                                         dmRoot,
 2965                                         agRoot,
 2966                                         oneDeviceData,
 2967                                         agNULL,
 2968                                         agNULL
 2969                                        );
 2970           }
 2971           else
 2972           {
 2973           }
 2974         }
 2975         else
 2976         {
 2977           ConnRate = ConnRate - 1;
 2978         }
 2979         agContext = &(dmSMPRequestBody->agContext);
 2980         agContext->osData = agIORequest;
 2981         saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
 2982       }
 2983       else
 2984       {
 2985         if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
 2986         {
 2987           /* retry the SMP again */
 2988           DM_DBG1(("dmSMPCompleted: failed, but retries %d agIOStatus 0x%x %d agIOInfoLen %d !!!\n",
 2989                    dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
 2990           saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 2991           dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 2992           status = saSMPStart(
 2993                               agRoot,
 2994                               agIORequest,
 2995                               0,
 2996                               agDevHandle,
 2997                               AGSA_SMP_INIT_REQ,
 2998                               agSASRequestBody,
 2999                               &dmsaSMPCompleted
 3000                              );
 3001           if (status == AGSA_RC_SUCCESS)
 3002           {
 3003             /* increment the number of pending SMP */
 3004             onePortContext->discovery.pendingSMP++;
 3005             dmSMPRequestBody->retries++;
 3006             if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 3007                 SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 3008                 SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3009                )
 3010             {
 3011               /* start discovery-related SMP timer */
 3012               dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
 3013             }
 3014             return;
 3015           }
 3016           else if (status == AGSA_RC_BUSY)
 3017           {
 3018             onePortContext->discovery.pendingSMP++;
 3019             dmSMPRequestBody->retries++;
 3020             if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3021                 dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3022                 dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3023                 dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3024                )
 3025             {
 3026               dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
 3027               return;
 3028             }
 3029             else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3030             {
 3031               /* For taskmanagement SMP, let's fail task management failure */
 3032               dmPhyControlFailureRespRcvd(
 3033                                           dmRoot,
 3034                                           agRoot,
 3035                                           oneDeviceData,
 3036                                           dmResponseSMPFrameHeader,
 3037                                           agFrameHandle
 3038                                          );
 3039             }
 3040             else
 3041             {
 3042             }
 3043           }
 3044           else /* AGSA_RC_FAILURE */
 3045           {
 3046             if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3047                 dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3048                 dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3049                 dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3050                )
 3051             {
 3052               dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3053             }
 3054             else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3055             {
 3056               /* task management failure */
 3057               dmPhyControlFailureRespRcvd(
 3058                                           dmRoot,
 3059                                           agRoot,
 3060                                           oneDeviceData,
 3061                                           dmResponseSMPFrameHeader,
 3062                                           agFrameHandle
 3063                                          );
 3064             }
 3065             else
 3066             {
 3067             }
 3068           }
 3069         }
 3070         else
 3071         {
 3072           dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
 3073           dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
 3074           DM_DBG1(("dmSMPCompleted: failed. no more retry. agIOStatus 0x%x %d !!!\n", agIOStatus, agIOStatus));
 3075           if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
 3076           {
 3077             DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
 3078           }
 3079           if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
 3080           {
 3081             DM_DBG1(("dmSMPCompleted: failed, agIOStatus is OSSA_IO_DS_IN_RECOVERY!!!\n"));
 3082           }
 3083           if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3084               dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3085               dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3086               dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3087              )
 3088           {
 3089             /* discovery failure */
 3090             DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
 3091             DM_DBG1(("dmSMPCompleted: discover done with error\n"));
 3092             dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3093           }
 3094           else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3095           {
 3096             DM_DBG3(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
 3097             smpPhyControlReq = (smpReqPhyControl_t *)dmSMPPayload;
 3098             if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
 3099             {
 3100               DM_DBG3(("dmSMPCompleted: discover done with error\n"));
 3101               dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3102             }
 3103             else
 3104             {
 3105               DM_DBG3(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControlReq->phyOperation));
 3106             }
 3107           } /* SMP_PHY_CONTROL */
 3108           else
 3109           {
 3110             DM_DBG3(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
 3111           }
 3112         } /* else */
 3113       } /* for RateAdjust */
 3114     } /* outer else */
 3115   } /* SAS 1.1 */
 3116   /************************************     SAS 2     ***********************************************/
 3117   else
 3118   {
 3119     DM_DBG2(("dmSMPCompleted: SAS 2\n"));
 3120     if (agIOStatus == OSSA_IO_SUCCESS)
 3121     {
 3122       //tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
 3123       /* parsing SMP payload */
 3124 #ifdef DIRECT_SMP
 3125     saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 3126 #else
 3127     dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3128     saFrameReadBlock(agRoot, dmSMPResponseBody->IndirectSMP, 0, smpHeader, 4);
 3129 #endif
 3130     dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 3131 
 3132       /* SMP function dependent payload */
 3133       switch (dmResponseSMPFrameHeader->smpFunction)
 3134       {
 3135       case SMP_REPORT_GENERAL:
 3136         DM_DBG2(("dmSMPCompleted: report general\n"));
 3137         if ((agIOInfoLen != sizeof(smpRespReportGeneral2_t) + 4) &&
 3138              dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
 3139            )
 3140         {
 3141           DM_DBG1(("dmSMPCompleted: report general mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportGeneral2_t) + 4));
 3142           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3143 
 3144           /* SMP request */
 3145           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3146           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3147           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3148 
 3149 #ifndef DIRECT_SMP
 3150           /* SMP response */
 3151           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3152           if (dmSMPResponseBody == agNULL)
 3153           {
 3154             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3155             return;
 3156           }
 3157           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3158           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3159           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3160 #endif
 3161 
 3162           return;
 3163         }
 3164 
 3165         dmReportGeneral2RespRcvd(
 3166                                   dmRoot,
 3167                                   agRoot,
 3168                                   agIORequest,
 3169                                   oneDeviceData,
 3170                                   dmResponseSMPFrameHeader,
 3171                                   agFrameHandle
 3172                                   );
 3173         break;
 3174       case SMP_DISCOVER:
 3175         DM_DBG2(("dmSMPCompleted: discover\n"));
 3176         if ((agIOInfoLen != sizeof(smpRespDiscover2_t) + 4) &&
 3177              dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
 3178            )
 3179         {
 3180           DM_DBG1(("dmSMPCompleted: discover mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespDiscover2_t) + 4));
 3181           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3182 
 3183           /* SMP request */
 3184           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3185           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3186           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3187 
 3188 #ifndef DIRECT_SMP
 3189           /* SMP response */
 3190           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3191           if (dmSMPResponseBody == agNULL)
 3192           {
 3193             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3194             return;
 3195           }
 3196           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3197           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3198           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3199 #endif
 3200 
 3201           return;
 3202         }
 3203         dmDiscover2RespRcvd(
 3204                              dmRoot,
 3205                              agRoot,
 3206                              agIORequest,
 3207                                 oneDeviceData,
 3208                              dmResponseSMPFrameHeader,
 3209                              agFrameHandle
 3210                              );
 3211         break;
 3212       case SMP_REPORT_PHY_SATA:
 3213         DM_DBG2(("dmSMPCompleted: report phy sata\n"));
 3214         if ((agIOInfoLen != sizeof(smpRespReportPhySata2_t) + 4) &&
 3215              dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
 3216            )
 3217         {
 3218           DM_DBG1(("dmSMPCompleted: report phy sata mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (int)sizeof(smpRespReportPhySata2_t) + 4));
 3219           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3220 
 3221           /* SMP request */
 3222           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3223           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3224           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3225 
 3226 #ifndef DIRECT_SMP
 3227           /* SMP response */
 3228           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3229           if (dmSMPResponseBody == agNULL)
 3230           {
 3231             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3232             return;
 3233           }
 3234           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3235           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3236           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3237 #endif
 3238 
 3239           return;
 3240         }
 3241         dmReportPhySata2Rcvd(
 3242                               dmRoot,
 3243                               agRoot,
 3244                               agIORequest,
 3245                               oneDeviceData,
 3246                               dmResponseSMPFrameHeader,
 3247                               agFrameHandle
 3248                               );
 3249         break;
 3250       case SMP_CONFIGURE_ROUTING_INFORMATION:
 3251         DM_DBG2(("dmSMPCompleted: configure routing information\n"));
 3252         if (agIOInfoLen != 4 &&
 3253             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
 3254            )
 3255         {
 3256           DM_DBG1(("dmSMPCompleted: configure routing information mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
 3257           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3258 
 3259           /* SMP request */
 3260           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3261           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3262           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3263 
 3264 #ifndef DIRECT_SMP
 3265           /* SMP response */
 3266           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3267           if (dmSMPResponseBody == agNULL)
 3268           {
 3269             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3270             return;
 3271           }
 3272           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3273           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3274           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3275 #endif
 3276 
 3277           return;
 3278         }
 3279         dmConfigRoutingInfo2RespRcvd(
 3280                                       dmRoot,
 3281                                       agRoot,
 3282                                       agIORequest,
 3283                                       oneDeviceData,
 3284                                       dmResponseSMPFrameHeader,
 3285                                       agFrameHandle
 3286                                       );
 3287 
 3288         break;
 3289       case SMP_PHY_CONTROL:
 3290         DM_DBG2(("dmSMPCompleted: phy control\n"));
 3291         if (agIOInfoLen != 4 &&
 3292             dmResponseSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED
 3293            ) /*zero length is expected */
 3294         {
 3295           DM_DBG1(("dmSMPCompleted: phy control mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4));
 3296           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3297 
 3298           /* SMP request */
 3299           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3300           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3301           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3302 
 3303 #ifndef DIRECT_SMP
 3304           /* SMP response */
 3305           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3306           if (dmSMPResponseBody == agNULL)
 3307           {
 3308             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3309             return;
 3310           }
 3311           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3312           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3313           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3314 #endif
 3315 
 3316           return;
 3317         }
 3318         dmPhyControl2RespRcvd(
 3319                                dmRoot,
 3320                                agRoot,
 3321                                agIORequest,
 3322              oneDeviceData,
 3323                                dmResponseSMPFrameHeader,
 3324                                agFrameHandle
 3325             );
 3326 
 3327 
 3328         break;
 3329 #ifdef NOT_YET
 3330       case SMP_DISCOVER_LIST:
 3331         DM_DBG1(("dmSMPCompleted: SMP_DISCOVER_LIST\n"));
 3332         DM_DBG1(("dmSMPCompleted: agIOInfoLen 0x%x \n", agIOInfoLen));
 3333         tdhexdump("dmSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen);
 3334         dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3335 
 3336           /* SMP request */
 3337           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3338           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3339           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3340 
 3341 #ifndef DIRECT_SMP
 3342           /* SMP response */
 3343           dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3344           if (dmSMPResponseBody == agNULL)
 3345           {
 3346             DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3347             return;
 3348           }
 3349           tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3350           DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3351           tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3352 #endif
 3353 
 3354         return;
 3355         break;
 3356 #endif
 3357       case SMP_REPORT_ROUTING_INFORMATION: /* fall through */
 3358       case SMP_REPORT_PHY_ERROR_LOG: /* fall through */
 3359       case SMP_PHY_TEST_FUNCTION: /* fall through */
 3360       case SMP_REPORT_MANUFACTURE_INFORMATION: /* fall through */
 3361       case SMP_READ_GPIO_REGISTER: /* fall through */
 3362       case SMP_WRITE_GPIO_REGISTER: /* fall through */
 3363       default:
 3364         DM_DBG1(("dmSMPCompleted: wrong SMP function 0x%x\n", dmResponseSMPFrameHeader->smpFunction));
 3365         DM_DBG1(("dmSMPCompleted: smpFrameType 0x%x\n", dmResponseSMPFrameHeader->smpFrameType));
 3366         DM_DBG1(("dmSMPCompleted: smpFunctionResult 0x%x\n", dmResponseSMPFrameHeader->smpFunctionResult));
 3367         DM_DBG1(("dmSMPCompleted: smpReserved 0x%x\n", dmResponseSMPFrameHeader->smpReserved));
 3368         dmhexdump("dmSMPCompleted: SMP payload", (bit8 *)agFrameHandle, agIOInfoLen);
 3369         break;
 3370       }
 3371     } /* agIOStatus == OSSA_IO_SUCCESS */
 3372     else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH)
 3373     {
 3374       /* no retry this case */
 3375       DM_DBG1(("dmSMPCompleted: OSSA_IO_ABORTED or OSSA_IO_INVALID_LENGTH, status 0x%x\n", agIOStatus));
 3376     }
 3377     else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE)
 3378     {
 3379       DM_DBG1(("dmSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n"));
 3380       saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 3381       dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 3382 
 3383       status = saSMPStart(
 3384                           agRoot,
 3385                           agIORequest,
 3386                           0,
 3387                           agDevHandle,
 3388                           AGSA_SMP_INIT_REQ,
 3389                           agSASRequestBody,
 3390                           &dmsaSMPCompleted
 3391                          );
 3392 
 3393 
 3394       if (status == AGSA_RC_SUCCESS)
 3395       {
 3396         /* increment the number of pending SMP */
 3397         onePortContext->discovery.pendingSMP++;
 3398         if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 3399             SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 3400             SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3401            )
 3402         {
 3403           /* start discovery-related SMP timer */
 3404           dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
 3405         }
 3406         return;
 3407       }
 3408       else if (status == AGSA_RC_BUSY)
 3409       {
 3410         if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3411             dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3412             dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3413             dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3414            )
 3415         {
 3416           dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
 3417         }
 3418         else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3419         {
 3420           /* For taskmanagement SMP, let's fail task management failure */
 3421           dmPhyControlFailureRespRcvd(
 3422                                       dmRoot,
 3423                                       agRoot,
 3424                                       oneDeviceData,
 3425                                       dmResponseSMPFrameHeader,
 3426                                       agFrameHandle
 3427                                      );
 3428         }
 3429         else
 3430         {
 3431         }
 3432       }
 3433       else /* AGSA_RC_FAILURE */
 3434       {
 3435         if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3436             dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3437             dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3438             dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3439       )
 3440         {
 3441           dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3442         }
 3443         else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3444         {
 3445           /* task management failure */
 3446           dmPhyControlFailureRespRcvd(
 3447                                       dmRoot,
 3448                                       agRoot,
 3449                                       oneDeviceData,
 3450                                       dmResponseSMPFrameHeader,
 3451                                       agFrameHandle
 3452                                      );
 3453         }
 3454         else
 3455         {
 3456         }
 3457       }
 3458     }
 3459     else if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION)
 3460     {
 3461       DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n"));
 3462       /*
 3463          skip to the next expander
 3464       */
 3465       dmHandleZoneViolation(
 3466                            dmRoot,
 3467                            agRoot,
 3468                            agIORequest,
 3469                            oneDeviceData,
 3470                            agNULL,
 3471                            agFrameHandle
 3472                            );
 3473     }
 3474     else
 3475     {
 3476       if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
 3477           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
 3478           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
 3479           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
 3480           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
 3481           agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
 3482           agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
 3483       {
 3484         DM_DBG1(("dmSMPCompleted: setting back to operational\n"));
 3485         saSetDeviceState(agRoot, agNULL, 0, agDevHandle, SA_DS_OPERATIONAL);
 3486       }
 3487       if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED && dmAllShared->RateAdjust)
 3488       {
 3489         DM_DBG1(("dmSMPCompleted: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n"));
 3490         DM_DBG1(("dmSMPCompleted: SMPRequestFunction 0x%x\n", SMPRequestFunction));
 3491         ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo);
 3492         if (ConnRate == SAS_CONNECTION_RATE_1_5G)
 3493         {
 3494           /* no retry; failure ??? */
 3495           if (SMPRequestFunction == SMP_REPORT_GENERAL ||
 3496               SMPRequestFunction == SMP_DISCOVER ||
 3497               SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 3498               SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3499              )
 3500           {
 3501             dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3502           }
 3503           else if (SMPRequestFunction == SMP_PHY_CONTROL)
 3504           {
 3505             /* task management failure */
 3506             dmPhyControlFailureRespRcvd(
 3507                                         dmRoot,
 3508                                         agRoot,
 3509                                         oneDeviceData,
 3510                                         agNULL,
 3511                                         agNULL
 3512                                        );
 3513           }
 3514           else
 3515           {
 3516           }
 3517         }
 3518         else
 3519         {
 3520           ConnRate = ConnRate - 1;
 3521         }
 3522         agContext = &(dmSMPRequestBody->agContext);
 3523         agContext->osData = agIORequest;
 3524         saSetDeviceInfo(agRoot, agContext, 0, agDevHandle, 32, ConnRate << 28, dmSetDeviceInfoCB);
 3525       }
 3526       else
 3527       {
 3528         if (dmSMPRequestBody->retries < SMP_RETRIES) /* 5 */
 3529         {
 3530           /* retry the SMP again */
 3531           DM_DBG1(("dmSMPCompleted: failed! but retries %d agIOStatus 0x%x %d agIOInfoLen %d\n",
 3532                    dmSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen));
 3533           saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
 3534           dmResponseSMPFrameHeader = (dmSMPFrameHeader_t *)smpHeader;
 3535           status = saSMPStart(
 3536                               agRoot,
 3537                               agIORequest,
 3538                               0,
 3539                               agDevHandle,
 3540                               AGSA_SMP_INIT_REQ,
 3541                               agSASRequestBody,
 3542                               &dmsaSMPCompleted
 3543                              );
 3544 
 3545           if (status == AGSA_RC_SUCCESS)
 3546           {
 3547             /* increment the number of pending SMP */
 3548             onePortContext->discovery.pendingSMP++;
 3549             dmSMPRequestBody->retries++;
 3550             if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER ||
 3551                 SMPRequestFunction == SMP_REPORT_PHY_SATA ||
 3552                 SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3553                )
 3554             {
 3555               /* start discovery-related SMP timer */
 3556               dmDiscoverySMPTimer(dmRoot, onePortContext, (bit32)(dmResponseSMPFrameHeader->smpFunction), dmSMPRequestBody);
 3557             }
 3558             return;
 3559           }
 3560           else if (status == AGSA_RC_BUSY)
 3561           {
 3562             onePortContext->discovery.pendingSMP++;
 3563             dmSMPRequestBody->retries++;
 3564             if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3565                 dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3566                 dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3567                 dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3568                )
 3569             {
 3570               dmSMPBusyTimer(dmRoot, onePortContext, oneDeviceData, dmSMPRequestBody);
 3571               return;
 3572             }
 3573             else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3574             {
 3575               /* For taskmanagement SMP, let's fail task management failure */
 3576               dmPhyControlFailureRespRcvd(
 3577                                           dmRoot,
 3578                                           agRoot,
 3579                                           oneDeviceData,
 3580                                           dmResponseSMPFrameHeader,
 3581                                           agFrameHandle
 3582                                          );
 3583             }
 3584             else
 3585             {
 3586             }
 3587           }
 3588           else /* AGSA_RC_FAILURE */
 3589           {
 3590             if (dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3591                 dmResponseSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3592                 dmResponseSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3593                 dmResponseSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3594                )
 3595             {
 3596               dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3597             }
 3598             else if (dmResponseSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3599             {
 3600               /* task management failure */
 3601               dmPhyControlFailureRespRcvd(
 3602                                           dmRoot,
 3603                                           agRoot,
 3604                                           oneDeviceData,
 3605                                           dmResponseSMPFrameHeader,
 3606                                           agFrameHandle
 3607                                          );
 3608             }
 3609             else
 3610             {
 3611             }
 3612           }
 3613         }
 3614         else
 3615         {
 3616           dmSMPFrameHeader = (dmSMPFrameHeader_t *)agSMPFrame->outFrameBuf;
 3617           dmSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4;
 3618           DM_DBG1(("dmSMPCompleted: failed! no more retry! agIOStatus 0x%x %d\n", agIOStatus, agIOStatus));
 3619           if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
 3620           {
 3621             DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_NON_OPERATIONAL\n"));
 3622           }
 3623           if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
 3624           {
 3625             DM_DBG1(("dmSMPCompleted: failed! agIOStatus is OSSA_IO_DS_IN_RECOVERY\n"));
 3626           }
 3627           if (dmSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL ||
 3628               dmSMPFrameHeader->smpFunction == SMP_DISCOVER ||
 3629               dmSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA ||
 3630               dmSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION
 3631              )
 3632           {
 3633             /* discovery failure */
 3634             DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
 3635             DM_DBG1(("dmSMPCompleted: discover done with error\n"));
 3636             dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3637           }
 3638           else if (dmSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
 3639           {
 3640             DM_DBG1(("dmSMPCompleted: SMP_PHY_CONTROL\n"));
 3641             smpPhyControl2Req = (smpReqPhyControl2_t *)dmSMPPayload;
 3642             if (smpPhyControl2Req->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION)
 3643             {
 3644               DM_DBG1(("dmSMPCompleted: discover done with error\n"));
 3645               dmDiscoverDone(dmRoot, onePortContext, DM_RC_FAILURE);
 3646             }
 3647             else
 3648             {
 3649               DM_DBG1(("dmSMPCompleted: unknown phy operation 0x%x\n", smpPhyControl2Req->phyOperation));
 3650             }
 3651           } /* SMP_PHY_CONTROL */
 3652           else
 3653           {
 3654             DM_DBG1(("dmSMPCompleted: SMP function 0x%x\n", dmSMPFrameHeader->smpFunction));
 3655           }
 3656         } /* else */
 3657       } /* for RateAdjust */
 3658     } /* outer else */
 3659   } /* SAS 2 else */
 3660 
 3661   /* SMP request */
 3662   tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3663   DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3664   tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3665 
 3666 #ifndef DIRECT_SMP
 3667   /* SMP response */
 3668   dmSMPResponseBody = (dmSMPRequestBody_t *)dmSMPRequestBody->IndirectSMPResponse;
 3669   if (dmSMPResponseBody == agNULL)
 3670   {
 3671     DM_DBG1(("dmSMPCompleted: Wrong, dmSMPResponseBody is NULL!!!\n"));
 3672     return;
 3673   }
 3674   tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3675   DMLIST_ENQUEUE_AT_TAIL(&(dmSMPResponseBody->Link), &(dmAllShared->freeSMPList));
 3676   tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3677 #endif
 3678 
 3679   return;
 3680 }
 3681 
 3682 osGLOBAL void
 3683 dmSMPAbortCB(
 3684              agsaRoot_t           *agRoot,
 3685              agsaIORequest_t      *agIORequest,
 3686              bit32                flag,
 3687              bit32                status)
 3688 {
 3689   dmRoot_t             *dmRoot = agNULL;
 3690   dmIntRoot_t          *dmIntRoot    = agNULL;
 3691   dmIntContext_t       *dmAllShared = agNULL;
 3692   dmSMPRequestBody_t   *dmSMPRequestBody = (dmSMPRequestBody_t *) agIORequest->osData;
 3693 
 3694   DM_DBG5(("dmSMPAbortCB: start\n"));
 3695 
 3696   if (dmSMPRequestBody == agNULL)
 3697   {
 3698     DM_DBG1(("dmSMPAbortCB: pSMPRequestBody is NULL!!! \n"));
 3699     return;
 3700   }
 3701 
 3702   dmRoot = dmSMPRequestBody->dmRoot;
 3703   dmIntRoot    = (dmIntRoot_t *)dmRoot->dmData;
 3704   dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
 3705 
 3706 
 3707   /* put back into free smplist */
 3708   tddmSingleThreadedEnter(dmRoot, DM_SMP_LOCK);
 3709   DMLIST_ENQUEUE_AT_TAIL(&(dmSMPRequestBody->Link), &(dmAllShared->freeSMPList));
 3710   tddmSingleThreadedLeave(dmRoot, DM_SMP_LOCK);
 3711 
 3712   /* start here */
 3713   if (flag == 2)
 3714   {
 3715     /* abort all per port */
 3716     DM_DBG1(("dmSMPAbortCB: abort per port; not used!!!\n"));
 3717   }
 3718   else if (flag == 1)
 3719   {
 3720     /* abort all */
 3721     DM_DBG1(("dmSMPAbortCB: abort all; not used!!!\n"));
 3722   }
 3723   else if (flag == 0)
 3724   {
 3725     /* abort one */
 3726     DM_DBG1(("ossaSMPAbortCB: abort one\n"));
 3727     if (status != OSSA_IO_SUCCESS)
 3728     {
 3729       DM_DBG1(("dmSMPAbortCB: abort one, status 0x%x\n", status));
 3730     }
 3731   }
 3732   else
 3733   {
 3734     DM_DBG1(("dmSMPAbortCB: not allowed case, flag 0x%x!!!\n", flag));
 3735   }
 3736 
 3737   return;
 3738 }
 3739 
 3740 
 3741 #endif /* FDS_DM */
 3742 
 3743 

Cache object: 4a2355080df46bf98e841f257eba716e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.