Whamcloud - gitweb
b=2776
[fs/lustre-release.git] / lustre / portals / portals / api-ni.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * api/api-ni.c
5  * Network Interface code
6  *
7  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
8  *  Copyright (c) 2001-2002 Sandia National Laboratories
9  *
10  *   This file is part of Lustre, http://www.sf.net/projects/lustre/
11  *
12  *   Lustre is free software; you can redistribute it and/or
13  *   modify it under the terms of version 2 of the GNU General Public
14  *   License as published by the Free Software Foundation.
15  *
16  *   Lustre is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Lustre; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include <portals/api-support.h>
27
28 /* Put some magic in the NI handle so uninitialised/zeroed handles are easy
29  * to spot */
30 #define NI_HANDLE_MAGIC  0xebc0de00
31 #define NI_HANDLE_MASK   0x000000ff
32 #define MAX_NIS          8         
33 static nal_t *ptl_interfaces[MAX_NIS];
34 int ptl_num_interfaces = 0;
35
36 nal_t *ptl_hndl2nal(ptl_handle_any_t *handle)
37 {
38         unsigned int idx = handle->nal_idx;
39
40         /* XXX we really rely on the caller NOT racing with interface
41          * setup/teardown.  That ensures her NI handle can't get
42          * invalidated out from under her (or worse, swapped for a
43          * completely different interface!) */
44
45         if (((idx ^ NI_HANDLE_MAGIC) & ~NI_HANDLE_MASK) != 0)
46                 return NULL;
47
48         idx &= NI_HANDLE_MASK;
49         if (idx < MAX_NIS)
50                 return ptl_interfaces[idx];
51
52         return NULL;
53 }
54
55 int ptl_ni_init(void)
56 {
57         int i;
58
59         LASSERT (MAX_NIS <= (NI_HANDLE_MASK + 1));
60         
61         for (i = 0; i < MAX_NIS; i++)
62                 ptl_interfaces[i] = NULL;
63
64         return PTL_OK;
65 }
66
67 void ptl_ni_fini(void)
68 {
69         int i;
70
71         for (i = 0; i < MAX_NIS; i++) {
72                 nal_t *nal = ptl_interfaces[i];
73                 if (!nal)
74                         continue;
75
76                 if (nal->shutdown)
77                         nal->shutdown(nal, i);
78         }
79 }
80
81 #ifdef __KERNEL__
82 DECLARE_MUTEX(ptl_ni_init_mutex);
83
84 static void ptl_ni_init_mutex_enter (void) 
85 {
86         down (&ptl_ni_init_mutex);
87 }
88
89 static void ptl_ni_init_mutex_exit (void)
90 {
91         up (&ptl_ni_init_mutex);
92 }
93
94 #else
95 static void ptl_ni_init_mutex_enter (void)
96 {
97 }
98
99 static void ptl_ni_init_mutex_exit (void) 
100 {
101 }
102
103 #endif
104
105 int PtlNIInit(ptl_interface_t interface, ptl_pt_index_t ptl_size,
106               ptl_ac_index_t acl_size, ptl_pid_t requested_pid,
107               ptl_handle_ni_t * handle)
108 {
109         nal_t *nal;
110         int i;
111
112         if (!ptl_init)
113                 return PTL_NO_INIT;
114
115         ptl_ni_init_mutex_enter ();
116
117         nal = interface(ptl_num_interfaces, ptl_size, acl_size, requested_pid);
118
119         if (!nal) {
120                 ptl_ni_init_mutex_exit ();
121                 return PTL_NAL_FAILED;
122         }
123
124         for (i = 0; i < ptl_num_interfaces; i++) {
125                 if (ptl_interfaces[i] == nal) {
126                         nal->refct++;
127                         handle->nal_idx = (NI_HANDLE_MAGIC & ~NI_HANDLE_MASK) | i;
128                         CDEBUG(D_OTHER, "Returning existing NAL (%d)\n", i);
129                         ptl_ni_init_mutex_exit ();
130                         return PTL_OK;
131                 }
132         }
133         nal->refct = 1;
134
135         if (ptl_num_interfaces >= MAX_NIS) {
136                 if (nal->shutdown)
137                         nal->shutdown (nal, ptl_num_interfaces);
138                 ptl_ni_init_mutex_exit ();
139                 return PTL_NO_SPACE;
140         }
141
142         handle->nal_idx = (NI_HANDLE_MAGIC & ~NI_HANDLE_MASK) | ptl_num_interfaces;
143         ptl_interfaces[ptl_num_interfaces++] = nal;
144
145         ptl_eq_ni_init(nal);
146         ptl_me_ni_init(nal);
147
148         ptl_ni_init_mutex_exit ();
149         return PTL_OK;
150 }
151
152
153 int PtlNIFini(ptl_handle_ni_t ni)
154 {
155         nal_t *nal;
156         int idx;
157         int rc;
158
159         if (!ptl_init)
160                 return PTL_NO_INIT;
161
162         ptl_ni_init_mutex_enter ();
163
164         nal = ptl_hndl2nal (&ni);
165         if (nal == NULL) {
166                 ptl_ni_init_mutex_exit ();
167                 return PTL_HANDLE_INVALID;
168         }
169
170         idx = ni.nal_idx & NI_HANDLE_MASK;
171
172         nal->refct--;
173         if (nal->refct > 0) {
174                 ptl_ni_init_mutex_exit ();
175                 return PTL_OK;
176         }
177
178         ptl_me_ni_fini(nal);
179         ptl_eq_ni_fini(nal);
180
181         rc = PTL_OK;
182         if (nal->shutdown)
183                 rc = nal->shutdown(nal, idx);
184
185         ptl_interfaces[idx] = NULL;
186         ptl_num_interfaces--;
187
188         ptl_ni_init_mutex_exit ();
189         return rc;
190 }
191
192 int PtlNIHandle(ptl_handle_any_t handle_in, ptl_handle_ni_t * ni_out)
193 {
194         *ni_out = handle_in;
195
196         return PTL_OK;
197 }