1285809Sscottl/*******************************************************************************
2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285809Sscottl*
4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285809Sscottl*that the following conditions are met:
6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285809Sscottl*following disclaimer.
8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice,
9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285809Sscottl*with the distribution.
11285809Sscottl*
12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285809Sscottl
21285809Sscottl********************************************************************************/
22285809Sscottl#include <sys/cdefs.h>
23285809Sscottl__FBSDID("$FreeBSD$");
24285809Sscottl#include <dev/pms/config.h>
25285809Sscottl
26285809Sscottl#include <dev/pms/freebsd/driver/common/osenv.h>
27285809Sscottl#include <dev/pms/freebsd/driver/common/ostypes.h>
28285809Sscottl#include <dev/pms/freebsd/driver/common/osdebug.h>
29285809Sscottl
30285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/sa.h>
31285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
32285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
33285809Sscottl
34285809Sscottl#ifdef FDS_DM
35285809Sscottl#include <dev/pms/RefTisa/discovery/api/dm.h>
36285809Sscottl#include <dev/pms/RefTisa/discovery/api/dmapi.h>
37285809Sscottl#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
38285809Sscottl
39285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmdefs.h>
40285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmtypes.h>
41285809Sscottl#include <dev/pms/RefTisa/discovery/dm/dmproto.h>
42285809Sscottl
43285809Sscottl/*****************************************************************************/
44285809Sscottl/*! \brief dmCreatePort
45285809Sscottl *
46285809Sscottl *
47285809Sscottl *  Purpose: A port context is created by this function
48285809Sscottl *
49285809Sscottl *  \param   dmRoot:              DM context handle.
50285809Sscottl *  \param   dmPortContext:       Pointer to this instance of port context
51285809Sscottl *
52285809Sscottl *  \return:
53285809Sscottl *          DM_RC_SUCCESS
54285809Sscottl *          DM_RC_FAILURE
55285809Sscottl *
56285809Sscottl */
57285809Sscottl/*****************************************************************************/
58285809SscottlosGLOBAL bit32
59285809SscottldmCreatePort(
60285809Sscottl             dmRoot_t        *dmRoot,
61285809Sscottl             dmPortContext_t *dmPortContext,
62285809Sscottl             dmPortInfo_t    *dmPortInfo)
63285809Sscottl{
64285809Sscottl  dmIntRoot_t               *dmIntRoot    = agNULL;
65285809Sscottl  dmIntContext_t            *dmAllShared = agNULL;
66285809Sscottl  dmIntPortContext_t        *onePortContext = agNULL;
67285809Sscottl  dmList_t                  *PortContextList = agNULL;
68285809Sscottl
69285809Sscottl  DM_DBG3(("dmCreatePort: start\n"));
70285809Sscottl
71285809Sscottl  if (dmRoot == agNULL)
72285809Sscottl  {
73285809Sscottl    DM_DBG1(("dmCreatePort: dmRoot is NULL, wrong!!!\n"));
74285809Sscottl    return DM_RC_FAILURE;
75285809Sscottl  }
76285809Sscottl
77285809Sscottl  if (dmPortContext == agNULL)
78285809Sscottl  {
79285809Sscottl    DM_DBG1(("dmCreatePort: dmPortContext is NULL, wrong!!!\n"));
80285809Sscottl    return DM_RC_FAILURE;
81285809Sscottl  }
82285809Sscottl
83285809Sscottl  /* the duplicacy of a port is checked */
84285809Sscottl  if (dmPortContext->dmData != agNULL)
85285809Sscottl  {
86285809Sscottl    DM_DBG1(("dmCreatePort: dmPortContext->dmData is not NULL, wrong, Already created!!!\n"));
87285809Sscottl    return DM_RC_FAILURE;
88285809Sscottl  }
89285809Sscottl
90285809Sscottl  if (dmPortInfo == agNULL)
91285809Sscottl  {
92285809Sscottl    DM_DBG1(("dmCreatePort: dmPortInfo is NULL, wrong!!!\n"));
93285809Sscottl    return DM_RC_FAILURE;
94285809Sscottl  }
95285809Sscottl
96285809Sscottl  dmIntRoot = (dmIntRoot_t *)dmRoot->dmData;
97285809Sscottl
98285809Sscottl  if (dmIntRoot == agNULL)
99285809Sscottl  {
100285809Sscottl    DM_DBG1(("dmCreatePort: dmIntRoot is NULL, wrong!!!\n"));
101285809Sscottl    return DM_RC_FAILURE;
102285809Sscottl  }
103285809Sscottl
104285809Sscottl  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
105285809Sscottl
106285809Sscottl  if (dmAllShared == agNULL)
107285809Sscottl  {
108285809Sscottl    DM_DBG1(("dmCreatePort: dmAllShared is NULL, wrong!!!\n"));
109285809Sscottl    return DM_RC_FAILURE;
110285809Sscottl  }
111285809Sscottl
112285809Sscottl  tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
113285809Sscottl  if (DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList)))
114285809Sscottl  {
115285809Sscottl    DMLIST_DEQUEUE_FROM_HEAD(&PortContextList, &(dmAllShared->FreePortContextList));
116285809Sscottl    tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
117285809Sscottl    onePortContext = DMLIST_OBJECT_BASE(dmIntPortContext_t, FreeLink, PortContextList);
118285809Sscottl    if (onePortContext == agNULL)
119285809Sscottl    {
120285809Sscottl      DM_DBG1(("dmCreatePort: onePortContext is NULL in allocation, wrong!!!\n"));
121285809Sscottl      return DM_RC_FAILURE;
122285809Sscottl    }
123285809Sscottl
124285809Sscottl    dmPortContext->dmData =  onePortContext;
125285809Sscottl    onePortContext->DiscoveryState = DM_DSTATE_NOT_STARTED;
126285809Sscottl    onePortContext->discoveryOptions = DM_DISCOVERY_OPTION_FULL_START;
127285809Sscottl
128285809Sscottl    onePortContext->dmRoot = dmRoot;
129285809Sscottl    onePortContext->dmPortContext = dmPortContext;
130285809Sscottl    onePortContext->valid = agTRUE;
131285809Sscottl    onePortContext->RegFailed = agFALSE;
132285809Sscottl
133285809Sscottl    onePortContext->LinkRate = DM_GET_LINK_RATE(dmPortInfo->flag);
134285809Sscottl    DM_DBG3(("dmCreatePort: linkrate %0x\n", onePortContext->LinkRate));
135285809Sscottl
136285809Sscottl    onePortContext->sasRemoteAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasRemoteAddressHi);
137285809Sscottl    onePortContext->sasRemoteAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasRemoteAddressLo);
138285809Sscottl    onePortContext->sasLocalAddressHi = DM_GET_SAS_ADDRESSHI(dmPortInfo->sasLocalAddressHi);
139285809Sscottl    onePortContext->sasLocalAddressLo = DM_GET_SAS_ADDRESSLO(dmPortInfo->sasLocalAddressLo);
140285809Sscottl    DM_DBG3(("dmCreatePort: pid %d\n", onePortContext->id));
141285809Sscottl    DM_DBG3(("dmCreatePort: RemoteAddrHi 0x%08x RemoteAddrLo 0x%08x\n", onePortContext->sasRemoteAddressHi, onePortContext->sasRemoteAddressLo));
142285809Sscottl    DM_DBG3(("dmCreatePort: LocalAddrHi 0x%08x LocaAddrLo 0x%08x\n", onePortContext->sasLocalAddressHi, onePortContext->sasLocalAddressLo));
143285809Sscottl
144285809Sscottl    tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
145285809Sscottl    DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->MainLink), &(dmAllShared->MainPortContextList));
146285809Sscottl    tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
147285809Sscottl  }
148285809Sscottl  else
149285809Sscottl  {
150285809Sscottl    tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
151285809Sscottl    DM_DBG1(("dmCreatePort: Attention. no more free PortContext!!!\n"));
152285809Sscottl    return DM_RC_FAILURE;
153285809Sscottl  }
154285809Sscottl
155285809Sscottl  return DM_RC_SUCCESS;
156285809Sscottl}
157285809Sscottl
158285809Sscottl/*****************************************************************************/
159285809Sscottl/*! \brief dmDestroyPort
160285809Sscottl *
161285809Sscottl *
162285809Sscottl *  Purpose: A port context is destroyed by this function
163285809Sscottl *
164285809Sscottl *  \param   dmRoot:              DM context handle.
165285809Sscottl *  \param   dmPortContext:       Pointer to this instance of port context
166285809Sscottl *
167285809Sscottl *  \return:
168285809Sscottl *          DM_RC_SUCCESS
169285809Sscottl *          DM_RC_FAILURE
170285809Sscottl *
171285809Sscottl */
172285809Sscottl/*****************************************************************************/
173285809SscottlosGLOBAL bit32
174285809SscottldmDestroyPort(
175285809Sscottl          dmRoot_t        *dmRoot,
176285809Sscottl          dmPortContext_t *dmPortContext,
177285809Sscottl          dmPortInfo_t    *dmPortInfo)
178285809Sscottl{
179285809Sscottl  dmIntRoot_t               *dmIntRoot    = agNULL;
180285809Sscottl  dmIntContext_t            *dmAllShared = agNULL;
181285809Sscottl  dmIntPortContext_t        *onePortContext = agNULL;
182285809Sscottl
183285809Sscottl  DM_DBG1(("dmDestroyPort: start\n"));
184285809Sscottl  if (dmRoot == agNULL)
185285809Sscottl  {
186285809Sscottl    DM_DBG1(("dmDestroyPort: dmRoot is NULL, wrong!!!\n"));
187285809Sscottl    return DM_RC_FAILURE;
188285809Sscottl  }
189285809Sscottl
190285809Sscottl  if (dmPortContext == agNULL)
191285809Sscottl  {
192285809Sscottl    DM_DBG1(("dmDestroyPort: dmPortContext is NULL, wrong!!!\n"));
193285809Sscottl    return DM_RC_FAILURE;
194285809Sscottl  }
195285809Sscottl
196285809Sscottl  if (dmPortInfo == agNULL)
197285809Sscottl  {
198285809Sscottl    DM_DBG1(("dmDestroyPort: dmPortInfo is NULL, wrong!!!\n"));
199285809Sscottl    return DM_RC_FAILURE;
200285809Sscottl  }
201285809Sscottl
202285809Sscottl  dmIntRoot = (dmIntRoot_t *)dmRoot->dmData;
203285809Sscottl
204285809Sscottl  if (dmIntRoot == agNULL)
205285809Sscottl  {
206285809Sscottl    DM_DBG1(("dmDestroyPort: dmIntRoot is NULL, wrong!!!\n"));
207285809Sscottl    return DM_RC_FAILURE;
208285809Sscottl  }
209285809Sscottl
210285809Sscottl  dmAllShared = (dmIntContext_t *)&dmIntRoot->dmAllShared;
211285809Sscottl
212285809Sscottl  if (dmAllShared == agNULL)
213285809Sscottl  {
214285809Sscottl    DM_DBG1(("dmDestroyPort: dmAllShared is NULL, wrong!!!\n"));
215285809Sscottl    return DM_RC_FAILURE;
216285809Sscottl  }
217285809Sscottl
218285809Sscottl  /*
219285809Sscottl    no device(expander) to be removed since all devices should
220285809Sscottl    be in freelist at the end of discovery
221285809Sscottl    But if the discovery is in progress, abort it and clean up
222285809Sscottl  */
223285809Sscottl  onePortContext = (dmIntPortContext_t *)dmPortContext->dmData;
224285809Sscottl
225285809Sscottl  if (onePortContext == agNULL)
226285809Sscottl  {
227285809Sscottl    DM_DBG1(("dmDestroyPort: onePortContext is NULL, wrong!!!\n"));
228285809Sscottl    return DM_RC_FAILURE;
229285809Sscottl  }
230285809Sscottl
231285809Sscottl#if 1
232285809Sscottl  if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED)
233285809Sscottl  {
234285809Sscottl    dmDiscoverAbort(dmRoot, onePortContext);
235285809Sscottl  }
236285809Sscottl  else
237285809Sscottl  {
238285809Sscottl    /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList; dmDiscoveryDeviceCleanUp()
239285809Sscottl       move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList; dmDiscoveryExpanderCleanUp()
240285809Sscottl    */
241285809Sscottl  }
242285809Sscottl#endif
243285809Sscottl
244285809Sscottl  if (onePortContext->DiscoveryState != DM_DSTATE_COMPLETED)
245285809Sscottl  {
246285809Sscottl    /* move from dmAllShared->discoveringExpanderList to dmAllShared->mainExpanderList
247285809Sscottl       move from dmAllShared->UpdiscoveringExpanderList to dmAllShared->mainExpanderList
248285809Sscottl    */
249285809Sscottl    dmCleanAllExp(dmRoot, onePortContext);
250285809Sscottl  }
251285809Sscottl
252285809Sscottl  /* move mainExpanderList then MainDeviceList */
253285809Sscottl  DM_DBG3(("dmDestroyPort: before dmDiscoveryExpanderCleanUp\n"));
254285809Sscottl  dmDumpAllMainExp(dmRoot, onePortContext);
255285809Sscottl
256285809Sscottl  /* move from dmAllShared->mainExpanderList to dmAllShared->freeExpanderList */
257285809Sscottl  dmDiscoveryExpanderCleanUp(dmRoot, onePortContext);
258285809Sscottl
259285809Sscottl  DM_DBG3(("dmDestroyPort: after dmDiscoveryExpanderCleanUp\n"));
260285809Sscottl  dmDumpAllMainExp(dmRoot, onePortContext);
261285809Sscottl
262285809Sscottl  DM_DBG3(("dmDestroyPort: before dmDiscoveryDeviceCleanUp\n"));
263285809Sscottl  dmDumpAllMainDevice(dmRoot, onePortContext);
264285809Sscottl  /* move devices from dmAllShared->MainDeviceList to dmAllShared->FreeDeviceList */
265285809Sscottl  dmDiscoveryDeviceCleanUp(dmRoot, onePortContext);
266285809Sscottl
267285809Sscottl  DM_DBG3(("dmDestroyPort: after dmDiscoveryDeviceCleanUp\n"));
268285809Sscottl  dmDumpAllMainDevice(dmRoot, onePortContext);
269285809Sscottl
270285809Sscottl  dmPortContextReInit(dmRoot, onePortContext);
271285809Sscottl
272285809Sscottl  tddmSingleThreadedEnter(dmRoot, DM_PORT_LOCK);
273285809Sscottl
274285809Sscottl  if (DMLIST_NOT_EMPTY(&(onePortContext->MainLink)))
275285809Sscottl  {
276285809Sscottl    DMLIST_DEQUEUE_THIS(&(onePortContext->MainLink));
277285809Sscottl  }
278285809Sscottl  else
279285809Sscottl  {
280285809Sscottl    DM_DBG1(("dmDestroyPort: onePortContext->MainLink is NULL, wrong!!!\n"));
281285809Sscottl  }
282285809Sscottl
283285809Sscottl  if (DMLIST_NOT_EMPTY(&(onePortContext->FreeLink)) && DMLIST_NOT_EMPTY(&(dmAllShared->FreePortContextList)))
284285809Sscottl  {
285285809Sscottl    DMLIST_ENQUEUE_AT_TAIL(&(onePortContext->FreeLink), &(dmAllShared->FreePortContextList));
286285809Sscottl  }
287285809Sscottl  else
288285809Sscottl  {
289285809Sscottl    DM_DBG1(("dmDestroyPort: onePortContext->FreeLink or dmAllShared->FreePortContextList is NULL, wrong!!!\n"));
290285809Sscottl  }
291285809Sscottl
292285809Sscottl  tddmSingleThreadedLeave(dmRoot, DM_PORT_LOCK);
293285809Sscottl
294285809Sscottl  return DM_RC_SUCCESS;
295285809Sscottl}
296285809Sscottl#endif /* FDS_ DM */
297285809Sscottl
298285809Sscottl
299285809Sscottl
300285809Sscottl
301285809Sscottl
302285809Sscottl
303285809Sscottl
304285809Sscottl
305