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