]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/pms/RefTisa/discovery/dm/dmport.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / pms / RefTisa / discovery / dm / dmport.c
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