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 #include <sys/cdefs.h> 23 __FBSDID("$FreeBSD$"); 24 #include <dev/pms/config.h> 25 26 #include <dev/pms/freebsd/driver/common/osenv.h> 27 #include <dev/pms/freebsd/driver/common/ostypes.h> 28 #include <dev/pms/freebsd/driver/common/osdebug.h> 29 30 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 31 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 32 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 33 34 #ifdef FDS_DM 35 #include <dev/pms/RefTisa/discovery/api/dm.h> 36 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 37 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 38 39 #include <dev/pms/RefTisa/discovery/dm/dmdefs.h> 40 #include <dev/pms/RefTisa/discovery/dm/dmtypes.h> 41 #include <dev/pms/RefTisa/discovery/dm/dmproto.h> 42 43 /*****************************************************************************/ 44 /*! \brief dmCreatePort 45 * 46 * 47 * Purpose: A port context is created by this function 48 * 49 * \param dmRoot: DM context handle. 50 * \param dmPortContext: Pointer to this instance of port context 51 * 52 * \return: 53 * DM_RC_SUCCESS 54 * DM_RC_FAILURE 55 * 56 */ 57 /*****************************************************************************/ 58 osGLOBAL bit32 59 dmCreatePort( 60 dmRoot_t *dmRoot, 61 dmPortContext_t *dmPortContext, 62 dmPortInfo_t *dmPortInfo) 63 { 64 dmIntRoot_t *dmIntRoot = agNULL; 65 dmIntContext_t *dmAllShared = agNULL; 66 dmIntPortContext_t *onePortContext = agNULL; 67 dmList_t *PortContextList = agNULL; 68 69 DM_DBG3(("dmCreatePort: start\n")); 70 71 if (dmRoot == agNULL) 72 { 73 DM_DBG1(("dmCreatePort: dmRoot is NULL, wrong!!!\n")); 74 return DM_RC_FAILURE; 75 } 76 77 if (dmPortContext == agNULL) 78 { 79 DM_DBG1(("dmCreatePort: dmPortContext is NULL, wrong!!!\n")); 80 return DM_RC_FAILURE; 81 } 82 83 /* the duplicacy of a port is checked */ 84 if (dmPortContext->dmData != agNULL) 85 { 86 DM_DBG1(("dmCreatePort: dmPortContext->dmData is not NULL, wrong, Already created!!!\n")); 87 return DM_RC_FAILURE; 88 } 89 90 if (dmPortInfo == agNULL) 91 { 92 DM_DBG1(("dmCreatePort: dmPortInfo is NULL, wrong!!!\n")); 93 return DM_RC_FAILURE; 94 } 95 96 dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 97 98 if (dmIntRoot == agNULL) 99 { 100 DM_DBG1(("dmCreatePort: dmIntRoot is NULL, wrong!!!\n")); 101 return DM_RC_FAILURE; 102 } 103 104 dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 105 106 if (dmAllShared == agNULL) 107 { 108 DM_DBG1(("dmCreatePort: dmAllShared is NULL, wrong!!!\n")); 109 return DM_RC_FAILURE; 110 } 111 112 tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 113 if (DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList))) 114 { 115 DMLIST_DEQUEUE_FROM_HEAD(&PortContextList, &(dmAllShared->FreePortContextList)); 116 tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 117 onePortContext = DMLIST_OBJECT_BASE(dmIntPortContext_t, FreeLink, PortContextList); 118 if (onePortContext == agNULL) 119 { 120 DM_DBG1(("dmCreatePort: onePortContext is NULL in allocation, wrong!!!\n")); 121 return DM_RC_FAILURE; 122 } 123 124 dmPortContext->dmData = onePortContext; 125 onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED; 126 onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_FULL_START; 127 128 onePortContext->dmRoot = dmRoot; 129 onePortContext->dmPortContext = dmPortContext; 130 onePortContext->valid = agTRUE; 131 onePortContext->RegFailed = agFALSE; 132 133 onePortContext->LinkRate = DM_GET_LINK_RATE(dmPortInfo->flag); 134 DM_DBG3(("dmCreatePort: linkrate %0x\n", onePortContext->LinkRate)); 135 136 onePortContext->sasRemoteAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasRemoteAddressHi); 137 onePortContext->sasRemoteAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasRemoteAddressLo); 138 onePortContext->sasLocalAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasLocalAddressHi); 139 onePortContext->sasLocalAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasLocalAddressLo); 140 DM_DBG3(("dmCreatePort: pid %d\n", onePortContext->id)); 141 DM_DBG3(("dmCreatePort: RemoteAddrHi 0x%08x RemoteAddrLo 0x%08x\n", onePortContext->sasRemoteAddressHi, onePortContext->sasRemoteAddressLo)); 142 DM_DBG3(("dmCreatePort: LocalAddrHi 0x%08x LocaAddrLo 0x%08x\n", onePortContext->sasLocalAddressHi, onePortContext->sasLocalAddressLo)); 143 144 tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 145 DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->MainLink), &(dmAllShared->MainPortContextList)); 146 tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 147 } 148 else 149 { 150 tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 151 DM_DBG1(("dmCreatePort: Attention. no more free PortContext!!!\n")); 152 return DM_RC_FAILURE; 153 } 154 155 return DM_RC_SUCCESS; 156 } 157 158 /*****************************************************************************/ 159 /*! \brief dmDestroyPort 160 * 161 * 162 * Purpose: A port context is destroyed by this function 163 * 164 * \param dmRoot: DM context handle. 165 * \param dmPortContext: Pointer to this instance of port context 166 * 167 * \return: 168 * DM_RC_SUCCESS 169 * DM_RC_FAILURE 170 * 171 */ 172 /*****************************************************************************/ 173 osGLOBAL bit32 174 dmDestroyPort( 175 dmRoot_t *dmRoot, 176 dmPortContext_t *dmPortContext, 177 dmPortInfo_t *dmPortInfo) 178 { 179 dmIntRoot_t *dmIntRoot = agNULL; 180 dmIntContext_t *dmAllShared = agNULL; 181 dmIntPortContext_t *onePortContext = agNULL; 182 183 DM_DBG1(("dmDestroyPort: start\n")); 184 if (dmRoot == agNULL) 185 { 186 DM_DBG1(("dmDestroyPort: dmRoot is NULL, wrong!!!\n")); 187 return DM_RC_FAILURE; 188 } 189 190 if (dmPortContext == agNULL) 191 { 192 DM_DBG1(("dmDestroyPort: dmPortContext is NULL, wrong!!!\n")); 193 return DM_RC_FAILURE; 194 } 195 196 if (dmPortInfo == agNULL) 197 { 198 DM_DBG1(("dmDestroyPort: dmPortInfo is NULL, wrong!!!\n")); 199 return DM_RC_FAILURE; 200 } 201 202 dmIntRoot = (dmIntRoot_t *)dmRoot->dmData; 203 204 if (dmIntRoot == agNULL) 205 { 206 DM_DBG1(("dmDestroyPort: dmIntRoot is NULL, wrong!!!\n")); 207 return DM_RC_FAILURE; 208 } 209 210 dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared; 211 212 if (dmAllShared == agNULL) 213 { 214 DM_DBG1(("dmDestroyPort: dmAllShared is NULL, wrong!!!\n")); 215 return DM_RC_FAILURE; 216 } 217 218 /* 219 no device(expander) to be removed since all devices should 220 be in freelist at the end of discovery 221 But if the discovery is in progress, abort it and clean up 222 */ 223 onePortContext = (dmIntPortContext_t *)dmPortContext->dmData; 224 225 if (onePortContext == agNULL) 226 { 227 DM_DBG1(("dmDestroyPort: onePortContext is NULL, wrong!!!\n")); 228 return DM_RC_FAILURE; 229 } 230 231 #if 1 232 if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 233 { 234 dmDiscoverAbort(dmRoot, onePortContext); 235 } 236 else 237 { 238 /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList; dmDiscoveryDeviceCleanUp() 239 move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList; dmDiscoveryExpanderCleanUp() 240 */ 241 } 242 #endif 243 244 if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED) 245 { 246 /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList 247 move from dmAllShared->UpdiscoveringExpanderList to dmAllShared->mainExpanderList 248 */ 249 dmCleanAllExp(dmRoot, onePortContext); 250 } 251 252 /* move mainExpanderList then MainDeviceList */ 253 DM_DBG3(("dmDestroyPort: before dmDiscoveryExpanderCleanUp\n")); 254 dmDumpAllMainExp(dmRoot, onePortContext); 255 256 /* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */ 257 dmDiscoveryExpanderCleanUp(dmRoot, onePortContext); 258 259 DM_DBG3(("dmDestroyPort: after dmDiscoveryExpanderCleanUp\n")); 260 dmDumpAllMainExp(dmRoot, onePortContext); 261 262 DM_DBG3(("dmDestroyPort: before dmDiscoveryDeviceCleanUp\n")); 263 dmDumpAllMainDevice(dmRoot, onePortContext); 264 /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */ 265 dmDiscoveryDeviceCleanUp(dmRoot, onePortContext); 266 267 DM_DBG3(("dmDestroyPort: after dmDiscoveryDeviceCleanUp\n")); 268 dmDumpAllMainDevice(dmRoot, onePortContext); 269 270 dmPortContextReInit(dmRoot, onePortContext); 271 272 tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK); 273 274 if (DMLIST_NOT_EMPTY(&(onePortContext->MainLink))) 275 { 276 DMLIST_DEQUEUE_THIS(&(onePortContext->MainLink)); 277 } 278 else 279 { 280 DM_DBG1(("dmDestroyPort: onePortContext->MainLink is NULL, wrong!!!\n")); 281 } 282 283 if (DMLIST_NOT_EMPTY(&(onePortContext->FreeLink)) && DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList))) 284 { 285 DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(dmAllShared->FreePortContextList)); 286 } 287 else 288 { 289 DM_DBG1(("dmDestroyPort: onePortContext->FreeLink or dmAllShared->FreePortContextList is NULL, wrong!!!\n")); 290 } 291 292 tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK); 293 294 return DM_RC_SUCCESS; 295 } 296 #endif /* FDS_ DM */ 297 298 299 300 301 302 303 304 305