1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ********************************************************************************/ 22 /*******************************************************************************/ 23 /*! \file sadisc.c 24 * \brief The file implements the functions to do SAS/SATA discovery 25 */ 26 27 /******************************************************************************/ 28 29 #include <sys/cdefs.h> 30 #include <dev/pms/config.h> 31 32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 33 #ifdef SA_ENABLE_TRACE_FUNCTIONS 34 #ifdef siTraceFileID 35 #undef siTraceFileID 36 #endif 37 #define siTraceFileID 'C' 38 #endif 39 40 /******************************************************************************/ 41 /*! \brief Start/Abort SAS/SATA discovery 42 * 43 * Start/Abort SAS/SATA discovery 44 * 45 * \param agRoot Handles for this instance of SAS/SATA hardware 46 * \param agPortContext Pointer to this instance of port context 47 * \param type Specifies the type(s) of discovery operation to start or cancel 48 * \param option Specified the discovery option 49 * 50 * \return If discovery is started/aborted successfully 51 * - \e AGSA_RC_SUCCESS discovery is started/aborted successfully 52 * - \e AGSA_RC_FAILURE discovery is not started/aborted successfully 53 * 54 */ 55 /*******************************************************************************/ 56 GLOBAL bit32 saDiscover( 57 agsaRoot_t *agRoot, 58 agsaPortContext_t *agPortContext, 59 bit32 type, 60 bit32 option 61 ) 62 { 63 /* Currently not supported */ 64 return AGSA_RC_FAILURE; 65 } 66 67 /******************************************************************************/ 68 /*! \brief Function for target to remove stale initiator device handle 69 * 70 * function is called to ask the LL layer to remove all LL layer and SPC firmware 71 * internal resources associated with a device handle 72 * 73 * \param agRoot Handles for this instance of SAS/SATA hardware 74 * \param agDevHandle Handle of the device that this I/O request will be made on 75 * 76 * \return If the device handle is removed successfully 77 * - \e AGSA_RC_SUCCESS the device handle is removed successfully 78 * - \e AGSA_RC_BUSY the device is busy, cannot be removed now 79 * 80 */ 81 /*******************************************************************************/ 82 GLOBAL bit32 saDeregisterDeviceHandle( 83 agsaRoot_t *agRoot, 84 agsaContext_t *agContext, 85 agsaDevHandle_t *agDevHandle, 86 bit32 queueNum 87 ) 88 { 89 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 90 agsaDeviceDesc_t *pDevice; 91 agsaPort_t *pPort; 92 bit32 ret = AGSA_RC_SUCCESS; 93 bit32 deviceid, portid; 94 bit32 deviceIdx; 95 96 OS_ASSERT(agDevHandle != agNULL, "saDeregisterDeviceHandle agDevHandle is NULL"); 97 98 smTraceFuncEnter(hpDBG_VERY_LOUD, "za"); 99 100 if(agNULL == agDevHandle) 101 { 102 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "za"); 103 return AGSA_RC_FAILURE; 104 } 105 106 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 107 108 OS_ASSERT(pDevice != agNULL, "saDeregisterDeviceHandle pDevice is NULL"); 109 if(pDevice == agNULL) 110 { 111 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "za"); 112 return AGSA_RC_FAILURE; 113 } 114 115 /* find device id */ 116 deviceid = pDevice->DeviceMapIndex; 117 deviceIdx = deviceid & DEVICE_ID_BITS; 118 OS_ASSERT(deviceIdx < MAX_IO_DEVICE_ENTRIES, "deviceIdx MAX_IO_DEVICE_ENTRIES"); 119 pPort = pDevice->pPort; 120 /* find port id */ 121 portid = pPort->portId; 122 123 SA_DBG3(("saDeregisterDeviceHandle: start DeviceHandle %p\n", agDevHandle)); 124 SA_DBG1(("saDeregisterDeviceHandle: deviceId 0x%x Device Context %p\n", deviceid, pDevice)); 125 126 if ((deviceid != saRoot->DeviceMap[deviceIdx].DeviceIdFromFW) || 127 (pDevice != saRoot->DeviceMap[deviceIdx].DeviceHandle)) 128 { 129 SA_DBG1(("saDeregisterDeviceHandle: Not match failure\n")); 130 ret = AGSA_RC_FAILURE; 131 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "za"); 132 return ret; 133 } 134 135 /* Build IOMB and send it to SPC */ 136 ret = mpiDeregDevHandleCmd(agRoot, agContext, pDevice, deviceid, portid, queueNum); 137 138 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "za"); 139 return ret; 140 } 141 142 /******************************************************************************/ 143 /*! \brief Function for target to remove stale initiator device handle 144 * 145 * function is called to ask the LL layer to remove all LL layer internal resources 146 * associated with a device handle 147 * 148 * \param agRoot Handles for this instance of SAS/SATA hardware 149 * \param agDevHandle Handle of the device that this I/O request will be made on 150 * 151 * \return If the device handle is removed successfully 152 * - \e AGSA_RC_SUCCESS the device handle is removed successfully 153 * - \e AGSA_RC_BUSY the device is busy, cannot be removed now 154 * 155 */ 156 /*******************************************************************************/ 157 GLOBAL bit32 siRemoveDevHandle( 158 agsaRoot_t *agRoot, 159 agsaDevHandle_t *agDevHandle 160 ) 161 { 162 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 163 agsaPort_t *pPort; 164 bit32 ret = AGSA_RC_SUCCESS; 165 166 OS_ASSERT(pDevice != agNULL, "siRemoveDevHandle is NULL"); 167 smTraceFuncEnter(hpDBG_VERY_LOUD,"zb"); 168 169 if (pDevice == agNULL) 170 { 171 SA_DBG1(("siRemoveDevHandle: pDevice is NULL \n")); 172 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zb"); 173 return AGSA_RC_FAILURE; 174 } 175 176 /* If it's to remove an initiator device handle */ 177 if ( &(pDevice->initiatorDevHandle) == agDevHandle ) 178 { 179 (pDevice->initiatorDevHandle).sdkData = agNULL; 180 } 181 /* If it's to remove an target device handle */ 182 else if ( &(pDevice->targetDevHandle) == agDevHandle ) 183 { 184 (pDevice->targetDevHandle).sdkData = agNULL; 185 } 186 else 187 { 188 SA_ASSERT(agFALSE, ""); 189 } 190 191 /* remove the device descriptor if it doesn't have either initiator handle and target handle */ 192 if ( (agNULL == (pDevice->initiatorDevHandle).sdkData) 193 && (agNULL == (pDevice->targetDevHandle).sdkData) ) 194 { 195 /* Find the port of the device */ 196 pPort = pDevice->pPort; 197 198 /* remove the device descriptor free discover list */ 199 switch ( pDevice->deviceType ) 200 { 201 case STP_DEVICE: /* fall through */ 202 case SSP_SMP_DEVICE: 203 case DIRECT_SATA_DEVICE: 204 { 205 SA_DBG3(("siRemoveDevHandle: remove device context %p\n", pDevice)); 206 siPortDeviceRemove(agRoot, pPort, pDevice, agTRUE); 207 break; 208 } 209 default: 210 { 211 SA_DBG1(("siRemoveDevHandle: switch. Not calling siPortDeviceRemove %d\n", pDevice->deviceType)); 212 break; 213 } 214 } 215 } 216 else 217 { 218 SA_DBG1(("siRemoveDevHandle: else. Not caling siPortDeviceRemove\n")); 219 } 220 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zb"); 221 return ret; 222 } 223 224 /******************************************************************************/ 225 /*! \brief Get Device Handles from a specific local port 226 * 227 * Get a Device Handles 228 * 229 * \param agRoot Handles for this instance of SAS/SATA hardware 230 * \param agsaContext Pointer to this API context 231 * \param agPortContext Pointer to this instance of port context 232 * \param flags Device flags 233 * \param agDev[] Pointer of array of device handles 234 * \param MaxDevs Specified Maximum number of Device Handles 235 * 236 * \return If GetDeviceHandles is successfully or failure 237 * - \e AGSA_RC_SUCCESS GetDeviceHandles is successfully 238 * - \e AGSA_RC_FAILURE GetDeviceHandles is not successfully 239 * 240 */ 241 /*******************************************************************************/ 242 GLOBAL bit32 saGetDeviceHandles( 243 agsaRoot_t *agRoot, 244 agsaContext_t *agContext, 245 bit32 queueNum, 246 agsaPortContext_t *agPortContext, 247 bit32 flags, 248 agsaDevHandle_t *agDev[], 249 bit32 skipCount, 250 bit32 MaxDevs 251 ) 252 { 253 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 254 agsaPort_t *pPort = (agsaPort_t *) (agPortContext->sdkData); 255 bit32 portIndex, i; 256 bit32 ret = AGSA_RC_SUCCESS; 257 258 OS_ASSERT(pPort != agNULL, "saGetDeviceHandles is NULL"); 259 smTraceFuncEnter(hpDBG_VERY_LOUD,"zc"); 260 261 if (pPort == agNULL) 262 { 263 SA_DBG1(("saGetDeviceHandles: pPort is NULL \n")); 264 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zc"); 265 return AGSA_RC_FAILURE; 266 } 267 268 SA_DBG1(("saGetDeviceHandles: start portId %d\n", pPort->portId)); 269 270 /* save the device handles arrary pointer */ 271 for (i = 0; i < MaxDevs; i ++) 272 { 273 saRoot->DeviceHandle[i] = agDev[i]; 274 } 275 276 /* send GET_DEVICE_HANDLE IOMB to SPC */ 277 portIndex = pPort->portId; 278 mpiGetDeviceHandleCmd(agRoot, agContext, portIndex, flags, MaxDevs, queueNum, skipCount); 279 280 /* return */ 281 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zc"); 282 return ret; 283 } 284 285 /******************************************************************************/ 286 /*! \brief Register New Device from a specific local port 287 * 288 * Register New Device API 289 * 290 * \param agRoot Handles for this instance of SAS/SATA hardware 291 * \param agContext Pointer to this API context 292 * \param agDeviceInfo Pointer to this instance of device info 293 * \param agPortContext Pointer to this instance of port context 294 * 295 * \return If discovery is started/aborted successfully 296 * - \e AGSA_RC_SUCCESS discovery is started/aborted successfully 297 * - \e AGSA_RC_FAILURE discovery is not started/aborted successfully 298 * 299 */ 300 /*******************************************************************************/ 301 GLOBAL bit32 saRegisterNewDevice( 302 agsaRoot_t *agRoot, 303 agsaContext_t *agContext, 304 bit32 queueNum, 305 agsaDeviceInfo_t *agDeviceInfo, 306 agsaPortContext_t *agPortContext, 307 bit16 hostAssignedDeviceId 308 ) 309 { 310 bit32 ret = AGSA_RC_SUCCESS; 311 agsaRegDevCmd_t payload; 312 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 313 agsaIORequestDesc_t *pRequest; 314 agsaPort_t *pPort = (agsaPort_t *) (agPortContext->sdkData); 315 agsaSASIdentify_t remoteIdentify; 316 bit32 i, phyId, sDTypeRate; 317 agsaDeviceDesc_t *pDevice = agNULL; 318 319 OS_ASSERT(pPort != agNULL, "saRegisterNewDevice is NULL"); 320 OS_ASSERT(saRoot != agNULL, "saRoot is NULL"); 321 smTraceFuncEnter(hpDBG_VERY_LOUD,"zd"); 322 323 if(saRoot == agNULL) 324 { 325 SA_DBG1(("saRegisterNewDevice: saRoot == agNULL\n")); 326 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zd"); 327 return(AGSA_RC_FAILURE); 328 } 329 330 if (pPort == agNULL) 331 { 332 SA_DBG1(("saRegisterNewDevice: pPort is NULL \n")); 333 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zd"); 334 return AGSA_RC_FAILURE; 335 } 336 337 SA_DBG2(("saRegisterNewDevice: start portId %d Port Context %p\n", pPort->portId, agPortContext)); 338 339 SA_DBG2(("saRegisterNewDevice: smpTimeout 0x%x\n", agDeviceInfo->smpTimeout)); 340 SA_DBG2(("saRegisterNewDevice: it_NexusTimeout 0x%x\n", agDeviceInfo->it_NexusTimeout)); 341 SA_DBG2(("saRegisterNewDevice: firstBurstSize 0x%x\n", agDeviceInfo->firstBurstSize)); 342 SA_DBG2(("saRegisterNewDevice: devType_S_Rate 0x%x\n", agDeviceInfo->devType_S_Rate)); 343 SA_DBG2(("saRegisterNewDevice: flag 0x%x\n", agDeviceInfo->flag)); 344 SA_DBG2(("saRegisterNewDevice: hostAssignedDeviceId 0x%x\n",hostAssignedDeviceId )); 345 SA_DBG2(("saRegisterNewDevice: Addr 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x\n", 346 agDeviceInfo->sasAddressHi[0],agDeviceInfo->sasAddressHi[1],agDeviceInfo->sasAddressHi[2],agDeviceInfo->sasAddressHi[3], 347 agDeviceInfo->sasAddressLo[0],agDeviceInfo->sasAddressLo[1],agDeviceInfo->sasAddressLo[2],agDeviceInfo->sasAddressLo[3] )); 348 349 agDeviceInfo->devType_S_Rate &= DEV_LINK_RATE; 350 351 /* 352 Using agsaDeviceInfo_t, fill in only sas address and device type 353 of identify address frame 354 */ 355 si_memset(&remoteIdentify, 0, sizeof(agsaSASIdentify_t)); 356 for (i=0;i<4;i++) 357 { 358 remoteIdentify.sasAddressHi[i] = agDeviceInfo->sasAddressHi[i]; 359 remoteIdentify.sasAddressLo[i] = agDeviceInfo->sasAddressLo[i]; 360 } 361 remoteIdentify.deviceType_addressFrameType = (bit8)(agDeviceInfo->devType_S_Rate & 0xC0); 362 363 /* Get request from free IORequests */ 364 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 365 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 366 367 /* If no LL Control request entry available */ 368 if ( agNULL == pRequest ) 369 { 370 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/ 371 if(agNULL != pRequest) 372 { 373 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 374 SA_DBG1(("saRegisterNewDevice, using saRoot->freeReservedRequests\n")); 375 } 376 else 377 { 378 SA_DBG1(("saRegisterNewDevice, No request from free list Not using saRoot->freeReservedRequests\n")); 379 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 380 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zd"); 381 return AGSA_RC_BUSY; 382 } 383 } 384 else 385 { 386 /* If LL Control request entry avaliable */ 387 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 388 } 389 390 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 391 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 392 saRoot->IOMap[pRequest->HTag].agContext = agContext; 393 pRequest->valid = agTRUE; 394 395 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 396 /* checking bit5 for SATA direct device */ 397 if (!(agDeviceInfo->devType_S_Rate & 0x20)) 398 { 399 /* SAS device */ 400 /* Add SAS device to the device list */ 401 pDevice = siPortSASDeviceAdd(agRoot, 402 pPort, 403 remoteIdentify, 404 agFALSE, 405 agDeviceInfo->smpTimeout, 406 agDeviceInfo->it_NexusTimeout, 407 agDeviceInfo->firstBurstSize, 408 agDeviceInfo->devType_S_Rate, 409 (agDeviceInfo->flag & DEV_INFO_MASK)); 410 } 411 else 412 { 413 /* SATA device */ 414 /* Add SATA device to the device list */ 415 pDevice = siPortSATADeviceAdd(agRoot, 416 pPort, 417 agNULL, 418 agNULL, /* no signature */ 419 agFALSE, 420 0, 421 agDeviceInfo->smpTimeout, 422 agDeviceInfo->it_NexusTimeout, 423 agDeviceInfo->firstBurstSize, 424 agDeviceInfo->devType_S_Rate, 425 (agDeviceInfo->flag & DEV_INFO_MASK)); 426 } 427 428 SA_DBG1(("saRegisterNewDevice: Device Context %p, TypeRate 0x%x\n", pDevice, agDeviceInfo->devType_S_Rate)); 429 430 pRequest->pDevice = pDevice; 431 432 /* adjust the flag bit to build the IOMB; use only bit0 and 1 */ 433 sDTypeRate = agDeviceInfo->devType_S_Rate << SHIFT24; 434 sDTypeRate |= (agDeviceInfo->flag & 0x01); 435 /* set AWT flag */ 436 sDTypeRate |= (agDeviceInfo->flag & 0x02) << 1; 437 438 /* If the host assigned device ID is used, then set the HA bit. */ 439 if ( hostAssignedDeviceId != 0 ) 440 { 441 sDTypeRate |= 2; 442 SA_DBG3(("saRegisterNewDevice:hostAssignedDeviceId 0x%x sDTypeRate 0x%x\n",hostAssignedDeviceId,sDTypeRate )); 443 } 444 445 /* Add the MCN field */ 446 447 sDTypeRate |= ((agDeviceInfo->flag >> DEV_INFO_MCN_SHIFT) & 0xf) << 4; 448 449 /* Add the IR field */ 450 sDTypeRate |= ((agDeviceInfo->flag >> DEV_INFO_IR_SHIFT) & 0x1) << 3; 451 452 /* Add the ATAPI protocol flag */ 453 sDTypeRate |= ((agDeviceInfo->flag & ATAPI_DEVICE_FLAG) << SHIFT9 ); 454 455 /* Add the AWT flag */ 456 sDTypeRate |= (agDeviceInfo->flag & AWT_DEVICE_FLAG) ? (1 << SHIFT2) : 0; 457 458 /* Add the XFER_READY flag */ 459 sDTypeRate |= (agDeviceInfo->flag & XFER_RDY_PRIORTY_DEVICE_FLAG) ? (1 << SHIFT31) : 0; 460 if(agDeviceInfo->flag & XFER_RDY_PRIORTY_DEVICE_FLAG) 461 { 462 SA_DBG1(("saRegisterNewDevice: sflag XFER_RDY_PRIORTY_DEVICE_FLAG sDTypeRate 0x%x\n",sDTypeRate )); 463 } 464 #ifdef CCFLAG_FORCE_AWT_ON 465 sDTypeRate |= (1 << SHIFT2); 466 SA_DBG1(("saRegisterNewDevice: Force AWT_DEVICE_FLAG sDTypeRate 0x%x\n",sDTypeRate )); 467 #endif /* CCFLAG_FORCE_AWT_ON */ 468 469 /* create payload for IOMB */ 470 si_memset(&payload, 0, sizeof(agsaRegDevCmd_t)); 471 472 SA_DBG2(("saRegisterNewDevice,flag 0x%08X\n",agDeviceInfo->flag)); 473 if ((agDeviceInfo->devType_S_Rate & 0x30) == 0x20) 474 { 475 if(smIS_SPC(agRoot)) 476 { 477 /* direct SATA device */ 478 phyId = (agDeviceInfo->flag & 0xF0); 479 } 480 else 481 { 482 phyId = (agDeviceInfo->flag & 0xF0) << SHIFT4; 483 } 484 } 485 else 486 { 487 phyId = 0; 488 } 489 490 smTrace(hpDBG_VERY_LOUD,"QQ",phyId); 491 /* TP:QQ phyId */ 492 smTrace(hpDBG_VERY_LOUD,"QR",pPort->portId); 493 /* TP:QR portId */ 494 smTrace(hpDBG_VERY_LOUD,"QS",sDTypeRate); 495 /* TP:QS sDTypeRate */ 496 smTrace(hpDBG_VERY_LOUD,"QT",agDeviceInfo->it_NexusTimeout); 497 /* TP:QT agDeviceInfo->it_NexusTimeout */ 498 499 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, phyIdportId), (bit32)(pPort->portId & PORTID_MASK) | phyId); 500 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, dTypeLRateAwtHa), sDTypeRate); 501 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, ITNexusTimeOut), (agDeviceInfo->it_NexusTimeout)); 502 503 smTrace(hpDBG_VERY_LOUD,"QT",(bit32)(pPort->portId & PORTID_MASK) | phyId); 504 /* TP:QT phyIdportId */ 505 /* no conversion is needed since SAS address is in BE format */ 506 payload.sasAddrHi = *(bit32*)agDeviceInfo->sasAddressHi; 507 payload.sasAddrLo = *(bit32*)agDeviceInfo->sasAddressLo; 508 509 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, tag), pRequest->HTag); 510 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaRegDevCmd_t, DeviceId), ((bit32)hostAssignedDeviceId) << 16); 511 512 if(smIS_SPC(agRoot)) 513 { 514 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_REG_DEV, IOMB_SIZE64, queueNum); 515 } 516 else 517 { 518 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_REG_DEV, IOMB_SIZE64, queueNum); 519 } 520 521 if (AGSA_RC_SUCCESS != ret) 522 { 523 /* return the request to free pool */ 524 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 525 /* remove the request from IOMap */ 526 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 527 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 528 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 529 pRequest->valid = agFALSE; 530 531 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 532 { 533 SA_DBG1(("saRegisterNewDevice: saving pRequest (%p) for later use\n", pRequest)); 534 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 535 } 536 else 537 { 538 /* return the request to free pool */ 539 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 540 } 541 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 542 SA_DBG1(("saRegisterNewDevice, sending IOMB failed\n" )); 543 } 544 SA_DBG3(("saRegisterNewDevice: end\n")); 545 546 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "zd"); 547 return ret; 548 } 549 550 /******************************************************************************/ 551 /*! \brief Register a callback for a specific event 552 * 553 * Register a callback for a Event API 554 * 555 * \param agRoot Handles for this instance of SAS/SATA hardware 556 * \param eventSourceType Event Type 557 * \param callbackPtr Function pointer to OS layer 558 * 559 * \return 560 * - \e AGSA_RC_SUCCESS 561 * - \e AGSA_RC_FAILURE 562 * 563 */ 564 /*******************************************************************************/ 565 GLOBAL bit32 saRegisterEventCallback( 566 agsaRoot_t *agRoot, 567 bit32 eventSourceType, 568 ossaGenericCB_t callbackPtr 569 ) 570 { 571 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 572 bit32 ret = AGSA_RC_FAILURE; 573 574 SA_DBG3(("saRegisterEventCallback: start\n")); 575 switch (eventSourceType) 576 { 577 case OSSA_EVENT_SOURCE_DEVICE_HANDLE_ADDED: 578 saRoot->DeviceRegistrationCB = (ossaDeviceRegistrationCB_t)callbackPtr; 579 ret = AGSA_RC_SUCCESS; 580 break; 581 case OSSA_EVENT_SOURCE_DEVICE_HANDLE_REMOVED: 582 saRoot->DeviceDeregistrationCB = (ossaDeregisterDeviceHandleCB_t) callbackPtr; 583 ret = AGSA_RC_SUCCESS; 584 break; 585 default: 586 SA_DBG1(("saRegisterEventCallback: not allowed case %d\n", eventSourceType)); 587 ret = AGSA_RC_FAILURE; 588 break; 589 } 590 return ret; 591 } 592 593 /******************************************************************************/ 594 /*! \brief Get Device Information 595 * 596 * Get SAS/SATA device information API 597 * 598 * \param agRoot Handles for this instance of SAS/SATA hardware 599 * \param option device general information or extended information 600 * \param agDevHandle Pointer of device handle 601 * 602 * \return 603 * - \e AGSA_RC_SUCCESS 604 * - \e AGSA_RC_FAILURE 605 * 606 */ 607 /*******************************************************************************/ 608 GLOBAL bit32 saGetDeviceInfo( 609 agsaRoot_t *agRoot, 610 agsaContext_t *agContext, 611 bit32 option, 612 bit32 queueNum, 613 agsaDevHandle_t *agDevHandle 614 ) 615 { 616 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 617 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 618 bit32 deviceid; 619 bit32 ret = AGSA_RC_FAILURE; 620 621 OS_ASSERT(pDevice != agNULL, "saGetDeviceInfo is NULL"); 622 smTraceFuncEnter(hpDBG_VERY_LOUD,"ze"); 623 624 if (pDevice == agNULL) 625 { 626 SA_DBG1(("saGetDeviceInfo: pDevice is NULL \n")); 627 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "ze"); 628 return AGSA_RC_FAILURE; 629 } 630 631 /* Get deviceid */ 632 deviceid = pDevice->DeviceMapIndex; 633 SA_DBG3(("saGetDeviceInfo: start pDevice %p, deviceId %d\n", pDevice, deviceid)); 634 635 /* verify the agDeviceHandle with the one in the deviceMap */ 636 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) || 637 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle)) 638 { 639 SA_DBG1(("saGetDeviceInfo: Not match failure or device not exist\n")); 640 ret = AGSA_RC_FAILURE; 641 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "ze"); 642 return ret; 643 } 644 645 /* send IOMB to the SPC */ 646 ret = mpiGetDeviceInfoCmd(agRoot, agContext, deviceid, option, queueNum); 647 648 SA_DBG3(("saGetDeviceInfo: end\n")); 649 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "ze"); 650 return ret; 651 } 652 653 /******************************************************************************/ 654 /*! \brief Set Device Information 655 * 656 * Set SAS/SATA device information API 657 * 658 * \param agRoot Handles for this instance of SAS/SATA hardware 659 * \param agContext Pointer to this API context 660 * \param queueNum IQ/OQ number 661 * \param agDevHandle Pointer of device handle 662 * \param option device general information or extended information 663 * \param param Parameter of Set Device Infomation 664 * 665 * \return 666 * - \e AGSA_RC_SUCCESS 667 * - \e AGSA_RC_FAILURE 668 * 669 */ 670 /*******************************************************************************/ 671 GLOBAL bit32 saSetDeviceInfo( 672 agsaRoot_t *agRoot, 673 agsaContext_t *agContext, 674 bit32 queueNum, 675 agsaDevHandle_t *agDevHandle, 676 bit32 option, 677 bit32 param, 678 ossaSetDeviceInfoCB_t agCB 679 ) 680 { 681 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 682 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 683 bit32 deviceid; 684 bit32 ret = AGSA_RC_FAILURE; 685 686 OS_ASSERT(pDevice != agNULL, "saSetDeviceInfo is NULL"); 687 smTraceFuncEnter(hpDBG_VERY_LOUD,"zf"); 688 689 SA_DBG2(("saSetDeviceInfo: start pDevice %p, option=0x%x param=0x0%x\n", pDevice, option, param)); 690 if(agNULL == pDevice ) 691 { 692 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zf"); 693 return ret; 694 } 695 696 697 /* Get deviceid */ 698 deviceid = pDevice->DeviceMapIndex; 699 pDevice->option = option; 700 pDevice->param = param; 701 702 SA_DBG3(("saSetDeviceInfo: deviceId %d\n", deviceid)); 703 704 /* verify the agDeviceHandle with the one in the deviceMap */ 705 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) || 706 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle)) 707 { 708 SA_DBG1(("saSetDeviceInfo: Not match failure or device not exist\n")); 709 ret = AGSA_RC_FAILURE; 710 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zf"); 711 return ret; 712 } 713 714 /* send IOMB to the SPC */ 715 ret = mpiSetDeviceInfoCmd(agRoot, agContext, deviceid, option, queueNum, param, agCB); 716 717 SA_DBG3(("saSetDeviceInfo: end\n")); 718 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zf"); 719 return ret; 720 } 721 722 /******************************************************************************/ 723 /*! \brief Get Device State 724 * 725 * Get SAS/SATA device state API 726 * 727 * \param agRoot Handles for this instance of SAS/SATA hardware 728 * \param agContext Pointer to this API context 729 * \param queueNum IQ/OQ number 730 * \param agDevHandle Pointer of device handler 731 * 732 * \return 733 * - \e AGSA_RC_SUCCESS 734 * - \e AGSA_RC_FAILURE 735 * 736 */ 737 /*******************************************************************************/ 738 GLOBAL bit32 saGetDeviceState( 739 agsaRoot_t *agRoot, 740 agsaContext_t *agContext, 741 bit32 queueNum, 742 agsaDevHandle_t *agDevHandle 743 ) 744 { 745 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 746 agsaDeviceDesc_t *pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 747 bit32 deviceid; 748 bit32 ret = AGSA_RC_FAILURE; 749 750 OS_ASSERT(pDevice != agNULL, "saGetDeviceState is NULL"); 751 smTraceFuncEnter(hpDBG_VERY_LOUD,"zg"); 752 753 if (pDevice == agNULL) 754 { 755 SA_DBG1(("saGetDeviceState: pDevice is NULL \n")); 756 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zg"); 757 return AGSA_RC_FAILURE; 758 } 759 760 SA_DBG3(("saGetDeviceState: start pDevice %p\n", pDevice)); 761 762 /* Get deviceid */ 763 deviceid = pDevice->DeviceMapIndex; 764 765 /* verify the agDeviceHandle with the one in the deviceMap */ 766 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) || 767 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle)) 768 { 769 SA_DBG1(("saGetDeviceState: Not match failure or device not exist\n")); 770 ret = AGSA_RC_FAILURE; 771 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zg"); 772 return ret; 773 } 774 775 /* send IOMB to the SPC */ 776 ret = mpiGetDeviceStateCmd(agRoot, agContext, deviceid, queueNum); 777 778 SA_DBG3(("saGetDeviceState: end\n")); 779 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zg"); 780 return ret; 781 } 782 783 /******************************************************************************/ 784 /*! \brief Set Device State 785 * 786 * Set SAS/SATA device state API 787 * 788 * \param agRoot Handles for this instance of SAS/SATA hardware 789 * \param agContext Pointer to this API context 790 * \param queueNum IQ/OQ number 791 * \param agDevHandle Pointer of device handler 792 * \param newDeviceState new device state 793 * 794 * \return 795 * - \e AGSA_RC_SUCCESS 796 * - \e AGSA_RC_FAILURE 797 * 798 */ 799 /*******************************************************************************/ 800 GLOBAL bit32 saSetDeviceState( 801 agsaRoot_t *agRoot, 802 agsaContext_t *agContext, 803 bit32 queueNum, 804 agsaDevHandle_t *agDevHandle, 805 bit32 newDeviceState 806 ) 807 { 808 agsaLLRoot_t *saRoot; 809 agsaDeviceDesc_t *pDevice; 810 bit32 deviceid; 811 bit32 ret = AGSA_RC_FAILURE; 812 813 saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 814 OS_ASSERT(saRoot != agNULL, "saSetDeviceState saRoot"); 815 816 if(saRoot == agNULL ) 817 { 818 SA_DBG1(("saSetDeviceState: saRoot is NULL\n")); 819 return ret; 820 } 821 822 OS_ASSERT(agDevHandle != agNULL, "saSetDeviceState agDevHandle is NULL"); 823 824 smTraceFuncEnter(hpDBG_VERY_LOUD,"zh"); 825 826 if(agDevHandle == agNULL ) 827 { 828 SA_DBG1(("saSetDeviceState: agDevHandle is NULL\n")); 829 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "zh"); 830 return ret; 831 } 832 833 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 834 835 OS_ASSERT(pDevice != agNULL, "saSetDeviceState pDevice is NULL"); 836 837 SA_DBG3(("saSetDeviceState: start pDevice %p\n", pDevice)); 838 839 if(pDevice == agNULL ) 840 { 841 SA_DBG1(("saSetDeviceState: pDevice is NULL\n")); 842 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "zh"); 843 return ret; 844 } 845 /* Get deviceid */ 846 deviceid = pDevice->DeviceMapIndex; 847 848 /* verify the agDeviceHandle with the one in the deviceMap */ 849 if ((deviceid != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceIdFromFW) || 850 (pDevice != saRoot->DeviceMap[deviceid & DEVICE_ID_BITS].DeviceHandle)) 851 { 852 SA_DBG1(("saSetDeviceState: Not match failure or device not exist\n")); 853 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "zh"); 854 return ret; 855 } 856 857 /* send IOMB to the SPC */ 858 ret = mpiSetDeviceStateCmd(agRoot, agContext, deviceid, newDeviceState, queueNum); 859 860 SA_DBG3(("saSetDeviceState: end\n")); 861 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "zh"); 862 return ret; 863 } 864