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