Whamcloud - gitweb
* Landed b_cray_portals_merge.
[fs/lustre-release.git] / lnet / klnds / scimaclnd / scimacnal.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:cindent:
3  *
4  * Copyright (C) 2003 High Performance Computing Center North (HPC2N)
5  *   Author: Niklas Edmundsson <nikke@hpc2n.umu.se>
6
7  * Based on gmnal, which is based on ksocknal and qswnal
8  *
9  * This file is part of Portals, http://www.sf.net/projects/lustre/
10  *
11  * Portals is free software; you can redistribute it and/or
12  * modify it under the terms of version 2 of the GNU General Public
13  * License as published by the Free Software Foundation.
14  *
15  * Portals is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Portals; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25
26
27 #include "scimacnal.h"
28
29 nal_t  kscimacnal_api;
30
31 kscimacnal_data_t kscimacnal_data;
32
33 kpr_nal_interface_t kscimacnal_router_interface = {
34         kprni_nalid:    SCIMACNAL,
35         kprni_arg:      NULL,
36         kprni_fwd:      kscimacnal_fwd_packet,
37 };
38
39
40 int kscimacnal_cmd (struct portal_ioctl_data *data, void *private)
41 {
42         LASSERT (data != NULL);
43
44         switch (data->ioc_nal_cmd) {
45                 case NAL_CMD_REGISTER_MYNID:
46                         if(kscimacnal_lib.ni.nid == data->ioc_nid) {
47                                 break;
48                         }
49                         CDEBUG (D_IOCTL, "Can't change NID from "LPX64" to "LPX64")\n", kscimacnal_lib.ni.nid, data->ioc_nid);
50                         return(-EINVAL);
51                 default:
52                         return(-EINVAL);
53         }
54
55         return(0);
56 }
57
58 static int kscimacnal_forward(nal_t   *nal,
59                           int     id,
60                           void    *args,  size_t args_len,
61                           void    *ret,   size_t ret_len)
62 {
63         kscimacnal_data_t *ksci = nal->nal_data;
64         nal_cb_t      *nal_cb = ksci->ksci_cb;
65
66         LASSERT (nal == &kscimacnal_api);
67         LASSERT (ksci == &kscimacnal_data);
68         LASSERT (nal_cb == &kscimacnal_lib);
69
70         lib_dispatch(nal_cb, ksci, id, args, ret); /* nal needs ksci */
71         return PTL_OK;
72 }
73
74
75 static void kscimacnal_lock(nal_t *nal, unsigned long *flags)
76 {
77         kscimacnal_data_t *ksci = nal->nal_data;
78         nal_cb_t      *nal_cb = ksci->ksci_cb;
79
80
81         LASSERT (nal == &kscimacnal_api);
82         LASSERT (ksci == &kscimacnal_data);
83         LASSERT (nal_cb == &kscimacnal_lib);
84
85         nal_cb->cb_cli(nal_cb,flags);
86 }
87
88
89 static void kscimacnal_unlock(nal_t *nal, unsigned long *flags)
90 {
91         kscimacnal_data_t *ksci = nal->nal_data;
92         nal_cb_t      *nal_cb = ksci->ksci_cb;
93
94
95         LASSERT (nal == &kscimacnal_api);
96         LASSERT (ksci == &kscimacnal_data);
97         LASSERT (nal_cb == &kscimacnal_lib);
98
99         nal_cb->cb_sti(nal_cb,flags);
100 }
101
102
103 static void kscimacnal_shutdown(nal_t *nal, int ni)
104 {
105         LASSERT (nal == &kscimacnal_api);
106         LASSERT (kscimacnal_data.ksci_init);
107
108         if (nal->nal_refct != 0)
109                 return;
110
111         /* Called on last matching PtlNIFini() */
112
113         /* FIXME: How should the shutdown procedure really look? 
114          */
115         kscimacnal_data.ksci_shuttingdown=1;
116
117         /* Stop handling ioctls */
118         libcfs_nal_cmd_unregister(SCIMACNAL);
119
120         mac_finish(kscimacnal_data.ksci_machandle);
121
122         /* finalise lib after net shuts up */
123         lib_fini(&kscimacnal_lib);
124
125         kscimacnal_data.ksci_init = 0;
126
127         /* Allow unload */
128         PORTAL_MODULE_UNUSE;
129
130         return;
131 }
132
133
134 static void kscimacnal_yield( nal_t *nal, unsigned long *flags, int milliseconds )
135 {
136         LASSERT (nal == &kscimacnal_api);
137
138         if (milliseconds != 0) {
139                 CERROR ("Blocking yield not implemented yet\n");
140                 LBUG();
141         }
142
143         if (current->need_resched) 
144                 schedule();
145         return;
146 }
147
148
149 static int kscimacnal_startup(nal_t *nal, ptl_pid_t requested_pid,
150                               ptl_ni_limits_t *requested_limits,
151                               ptl_ni_limits_t *actual_limits)
152 {
153         int rc;
154         mac_physaddr_t   mac_physaddr;
155         ptl_process_id_t process_id;
156         mac_handle_t    *machandle = NULL;
157
158         if (nal->nal_refct != 0) {
159                 if (actual_limits != NULL)
160                         *actual_limits = kscimacnal_lib.ni.actual_limits;
161                 return (PTL_OK);
162         }
163
164         /* Called on first PtlNIInit(SCIMACNAL) */
165
166         LASSERT (nal == kscimacnal_api);
167         LASSERT (!kscimacnal_data.ksci_init);
168         
169         kscimacnal_lib.nal_data = &kscimacnal_data;
170
171         memset(&kscimacnal_data, 0, sizeof(kscimacnal_data));
172
173         kscimacnal_data.ksci_cb = &kscimacnal_lib;
174
175         /* We're not using this, but cli/sti callbacks does... ??? */
176         spin_lock_init(&kscimacnal_data.ksci_dispatch_lock);
177
178         /* FIXME: We only support one adapter for now */
179         machandle = mac_init(0, MAC_SAPID_LUSTRE, kscimacnal_rx,
180                         &kscimacnal_data);
181
182         if(!machandle) {
183                 CERROR("mac_init() failed\n");
184                 return PTL_FAIL;
185         }
186
187         kscimacnal_data.ksci_machandle = machandle;
188
189         /* Make sure the scimac MTU is tuned */
190         if(mac_get_mtusize(machandle) < SCIMACNAL_MTU) {
191                 CERROR("scimac mtu of %ld smaller than SCIMACNAL MTU of %d\n",
192                                 mac_get_mtusize(machandle), SCIMACNAL_MTU);
193                 CERROR("Consult README.scimacnal for more information\n");
194                 mac_finish(machandle);
195                 return PTL_FAIL;
196         }
197
198         /* Get the node ID */
199         /* mac_get_physaddrlen() is a function instead of define, sigh */
200         LASSERT(mac_get_physaddrlen(machandle) <= sizeof(mac_physaddr));
201         if(mac_get_physaddr(machandle, &mac_physaddr)) {
202                 CERROR("mac_get_physaddr() failed\n");
203                 mac_finish(machandle);
204                 return PTL_FAIL;
205         }
206         kscimacnal_data.ksci_nid = (ptl_nid_t)(ntohl(mac_physaddr));
207
208         process_id.pid = 0;
209         process_id.nid = kscimacnal_data.ksci_nid;
210
211         CDEBUG(D_NET, "calling lib_init with nid "LPX64"\n",
212                kscimacnal_data.ksci_nid);
213
214         rc = lib_init(&kscimacnal_lib, process_id,
215                       requested_limits, actual_limits);
216         if (rc != PTL_OK) {
217                 CERROR("PtlNIInit failed %d\n", rc);
218                 mac_finish(machandle);
219                 return (rc);
220         }
221
222         /* Init command interface */
223         rc = libcfs_nal_cmd_register (SCIMACNAL, &kscimacnal_cmd, NULL);
224         if (rc != 0) {
225                 CERROR ("Can't initialise command interface (rc = %d)\n", rc);
226                 lib_fini(&kscimacnal_lib);
227                 mac_finish(machandle);
228                 return (PTL_FAIL);
229         }
230
231         /* We're done now, it's OK for the RX callback to do stuff */
232         kscimacnal_data.ksci_init = 1;
233
234         /* Prevent unload before matching PtlNIFini() */
235         PORTAL_MODULE_USE;
236         
237         return (PTL_OK);
238 }
239
240
241 /* Called by kernel at module unload time */
242 static void /*__exit*/ 
243 kscimacnal_finalize(void)
244 {
245         LASSERT (!kscimacnal_data.ksci_init);
246         
247         ptl_unregister_nal(SCIMACNAL);
248
249         CDEBUG (D_MALLOC, "done kmem %d\n", atomic_read (&portal_kmemory));
250
251         return;
252 }
253
254
255 /* Called by kernel at module insertion time */
256 static int __init
257 kscimacnal_initialize(void)
258 {
259         int rc;
260
261         CDEBUG (D_MALLOC, "start kmem %d\n", atomic_read (&portal_kmemory));
262
263         kscimacnal_api.startup = kscimacnal_startup;
264         kscimacnal_api.forward = kscimacnal_forward;
265         kscimacnal_api.shutdown = kscimacnal_shutdown;
266         kscimacnal_api.yield = kscimacnal_yield;
267         kscimacnal_api.lock= kscimacnal_lock;
268         kscimacnal_api.unlock= kscimacnal_unlock;
269         kscimacnal_api.nal_data = &kscimacnal_data;
270
271         rc = ptl_register_nal(SCIMACNAL, &kscimacnal_api);
272         if (rc != PTL_OK) {
273                 CERROR("Can't register SCIMACNAL: %d\n", rc);
274                 return (-ENODEV);
275         }
276         
277         return 0;
278 }
279
280
281 MODULE_AUTHOR("Niklas Edmundsson <nikke@hpc2n.umu.se>");
282 MODULE_DESCRIPTION("Kernel Scali ScaMAC SCI NAL v0.1");
283 MODULE_LICENSE("GPL");
284
285 module_init (kscimacnal_initialize);
286 module_exit (kscimacnal_finalize);
287
288 EXPORT_SYMBOL(kscimacnal_ni);