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