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