3 * This program was prepared by the Regents of the University of
4 * California at Los Alamos National Laboratory (the University) under
5 * contract number W-7405-ENG-36 with the U.S. Department of Energy
6 * (DoE). Neither the U.S. Government nor the
7 * University makes any warranty, express or implied, or assumes any
8 * liability or responsibility for the use of this software.
14 * Implements the API NAL functions
19 lgmnal_data_t *global_nal_data = NULL;
22 * This function takes a pack block of arguments from the NAL API
23 * module and passes them to the NAL CB module. The CB module unpacks
24 * the args and calls the appropriate function indicated by index.
25 * Typically this function is used to pass args between kernel and use
27 * As lgmanl exists entirely in kernel, just pass the arg block directly to
28 * the NAL CB, buy passing the args to lib_dispatch
31 * int index the api function that initiated this call
32 * void *args packed block of function args
33 * size_t arg_len length of args block
34 * void *ret A return value for the API NAL
35 * size_t ret_len Size of the return value
40 lgmnal_api_forward(nal_t *nal, int index, void *args, size_t arg_len,
41 void *ret, size_t ret_len)
44 nal_cb_t *nal_cb = NULL;
45 lgmnal_data_t *nal_data = NULL;
50 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_forward: nal [%p], index [%d], args [%p], arglen [%d], ret [%p], retlen [%d]\n", nal, index, args, arg_len, ret, ret_len));
52 if (!nal || !args || (index < 0) || (arg_len < 0)) {
53 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
56 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No nal specified\n"));
58 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("No args specified\n"));
60 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Index is negative[%d]\n", index));
62 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("arg_len is negative [%d]\n", arg_len));
67 if (ret && (ret_len <= 0)) {
68 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Bad args to lgmnal_api_forward\n"));
70 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("ret_len is [%d]\n", ret_len));
77 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal, no nal data\n"));
81 nal_data = nal->nal_data;
82 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_data is [%p]\n", nal_data));
84 if (!nal_data->nal_cb) {
85 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad nal_data, no nal_cb\n"));
89 nal_cb = nal_data->nal_cb;
90 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("nal_cb is [%p]\n", nal_cb));
92 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward calling lib_dispatch\n"));
93 lib_dispatch(nal_cb, NULL, index, args, ret);
94 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("lgmnal_api_forward returns from lib_dispatch\n"));
101 * lgmnal_api_shutdown
102 * Close down this interface and free any resources associated with it
103 * nal_t nal our nal to shutdown
106 lgmnal_api_shutdown(nal_t *nal, int interface)
109 lgmnal_data_t *nal_data = nal->nal_data;
111 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_shutdown: nal_data [%p]\n", nal_data));
114 * TO DO lgmnal_api_shutdown what is to be done?
122 * lgmnal_api_validate
123 * validate a user address for use in communications
124 * There's nothing to be done here
127 lgmnal_api_validate(nal_t *nal, void *base, size_t extent)
130 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_validate : nal [%p], base [%p], extent [%d]\n", nal, base, extent));
139 * Give up the processor
142 lgmnal_api_yield(nal_t *nal)
144 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_yield : nal [%p]\n", nal));
146 set_current_state(TASK_INTERRUPTIBLE);
156 * Take a threadsafe lock
159 lgmnal_api_lock(nal_t *nal, unsigned long *flags)
162 lgmnal_data_t *nal_data;
164 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flagsa [%p] flags[%ul]\n", nal, flags, *flags));
166 nal_data = nal->nal_data;
167 nal_cb = nal_data->nal_cb;
169 nal_cb->cb_cli(nal_cb, flags);
171 LGMNAL_API_LOCK(nal_data);
179 * Release a threadsafe lock
182 lgmnal_api_unlock(nal_t *nal, unsigned long *flags)
184 lgmnal_data_t *nal_data;
186 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_api_lock : nal [%p], flags [%p]\n", nal, flags));
188 nal_data = nal->nal_data;
190 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal, no nal_data\n"));
192 nal_cb = nal_data->nal_cb;
194 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lgmnal_api_unlock bad nal_data, no nal_cb\n"));
197 nal_cb->cb_sti(nal_cb, flags);
199 LGMNAL_API_UNLOCK(nal_data);
207 lgmnal_init(int interface, ptl_pt_index_t ptl_size, ptl_ac_index_t ac_size, ptl_pid_t rpid)
211 nal_cb_t *nal_cb = NULL;
212 lgmnal_data_t *nal_data = NULL;
213 lgmnal_srxd_t *srxd = NULL;
214 gm_status_t gm_status;
215 unsigned int local_nid = 0, global_nid = 0;
216 ptl_nid_t portals_nid;
217 ptl_pid_t portals_pid = 0;
220 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_init : interface [%d], ptl_size [%d], ac_size[%d]\n",
221 interface, ptl_size, ac_size));
223 if ((interface < 0) || (interface > LGMNAL_NUM_IF) || (ptl_size <= 0) || (ac_size <= 0) ) {
224 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("bad args\n"));
227 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("parameters check out ok\n"));
230 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Acquired global lock\n"));
233 PORTAL_ALLOC(nal_data, sizeof(lgmnal_data_t));
235 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't get memory\n"));
238 memset(nal_data, 0, sizeof(lgmnal_data_t));
240 * set the small message buffer size
242 nal_data->refcnt = 1;
244 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_data[%p]\n", nal_data));
245 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("small_msg_size is [%d]\n", nal_data->small_msg_size));
247 PORTAL_ALLOC(nal, sizeof(nal_t));
249 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
252 memset(nal, 0, sizeof(nal_t));
253 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal[%p]\n", nal));
255 PORTAL_ALLOC(nal_cb, sizeof(nal_cb_t));
257 PORTAL_FREE(nal, sizeof(nal_t));
258 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
261 memset(nal_cb, 0, sizeof(nal_cb_t));
262 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Allocd and reset nal_cb[%p]\n", nal_cb));
264 LGMNAL_INIT_NAL(nal);
265 LGMNAL_INIT_NAL_CB(nal_cb);
267 * String them all together
269 nal->nal_data = (void*)nal_data;
270 nal_cb->nal_data = (void*)nal_data;
272 nal_data->nal_cb = nal_cb;
274 LGMNAL_API_LOCK_INIT(nal_data);
275 LGMNAL_CB_LOCK_INIT(nal_data);
276 LGMNAL_GM_LOCK_INIT(nal_data);
280 * initialise the interface,
282 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Calling gm_init\n"));
283 if (gm_init() != GM_SUCCESS) {
284 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("call to gm_init failed\n"));
285 PORTAL_FREE(nal, sizeof(nal_t));
286 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
287 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
292 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Calling gm_open with interface [%d], port [%d], name [%s], version [%d]\n", interface, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION));
294 LGMNAL_GM_LOCK(nal_data);
295 gm_status = gm_open(&nal_data->gm_port, 0, LGMNAL_GM_PORT, "lgmnal", GM_API_VERSION);
296 LGMNAL_GM_UNLOCK(nal_data);
298 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open returned [%d]\n", gm_status));
299 if (gm_status == GM_SUCCESS) {
300 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("gm_open succeeded port[%p]\n", nal_data->gm_port));
303 case(GM_INVALID_PARAMETER):
304 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Invalid Parameter\n"));
307 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. GM Busy\n"));
309 case(GM_NO_SUCH_DEVICE):
310 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. No such device\n"));
312 case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
313 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Incompatile lib and driver\n"));
315 case(GM_OUT_OF_MEMORY):
316 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Out of Memory\n"));
319 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("gm_open Failure. Unknow error code [%d]\n", gm_status));
322 LGMNAL_GM_LOCK(nal_data);
324 LGMNAL_GM_UNLOCK(nal_data);
325 PORTAL_FREE(nal, sizeof(nal_t));
326 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
327 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
332 nal_data->small_msg_size = lgmnal_small_msg_size;
333 nal_data->small_msg_gmsize = gm_min_size_for_length(lgmnal_small_msg_size);
335 if (lgmnal_alloc_srxd(nal_data) != LGMNAL_STATUS_OK) {
336 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small rx descriptors\n"));
337 lgmnal_free_stxd(nal_data);
338 LGMNAL_GM_LOCK(nal_data);
339 gm_close(nal_data->gm_port);
341 LGMNAL_GM_UNLOCK(nal_data);
342 PORTAL_FREE(nal, sizeof(nal_t));
343 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
344 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
350 * Hang out a bunch of small receive buffers
351 * In fact hang them all out
353 while((srxd = lgmnal_get_srxd(nal_data, 0))) {
354 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("giving [%p] to gm_provide_recvive_buffer\n", srxd->buffer));
355 LGMNAL_GM_LOCK(nal_data);
356 gm_provide_receive_buffer_with_tag(nal_data->gm_port, srxd->buffer,
357 srxd->gmsize, GM_LOW_PRIORITY, 0);
358 LGMNAL_GM_UNLOCK(nal_data);
362 * Allocate pools of small tx buffers and descriptors
364 if (lgmnal_alloc_stxd(nal_data) != LGMNAL_STATUS_OK) {
365 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Failed to allocate small tx descriptors\n"));
366 LGMNAL_GM_LOCK(nal_data);
367 gm_close(nal_data->gm_port);
369 LGMNAL_GM_UNLOCK(nal_data);
370 PORTAL_FREE(nal, sizeof(nal_t));
371 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
372 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
377 * Start the recieve thread
378 * Initialise the gm_alarm we will use to wake the thread is
379 * it needs to be stopped
381 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Initializing receive thread alarm and flag\n"));
382 gm_initialize_alarm(&nal_data->rxthread_alarm);
383 nal_data->rxthread_flag = LGMNAL_THREAD_START;
386 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Starting receive thread\n"));
387 nal_data->rxthread_pid = kernel_thread(lgmnal_receive_thread, (void*)nal_data, 0);
388 if (nal_data->rxthread_pid <= 0) {
389 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("Receive thread failed to start\n"));
390 lgmnal_free_stxd(nal_data);
391 lgmnal_free_srxd(nal_data);
392 LGMNAL_GM_LOCK(nal_data);
393 gm_close(nal_data->gm_port);
395 LGMNAL_GM_UNLOCK(nal_data);
396 PORTAL_FREE(nal, sizeof(nal_t));
397 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
398 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
401 while (nal_data->rxthread_flag != LGMNAL_THREAD_STARTED) {
402 set_current_state(TASK_INTERRUPTIBLE);
403 schedule_timeout(1024);
404 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Waiting for receive thread signs of life\n"));
406 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("receive thread seems to have started\n"));
407 nal_data->rxthread_flag = LGMNAL_THREAD_CONTINUE;
412 * Initialise the portals library
414 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("Getting node id\n"));
415 LGMNAL_GM_LOCK(nal_data);
416 gm_status = gm_get_node_id(nal_data->gm_port, &local_nid);
417 LGMNAL_GM_UNLOCK(nal_data);
418 if (gm_status != GM_SUCCESS) {
419 lgmnal_stop_rxthread(nal_data);
420 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("can't determine node id\n"));
421 lgmnal_free_stxd(nal_data);
422 lgmnal_free_srxd(nal_data);
423 LGMNAL_GM_LOCK(nal_data);
424 gm_close(nal_data->gm_port);
426 LGMNAL_GM_UNLOCK(nal_data);
427 PORTAL_FREE(nal, sizeof(nal_t));
428 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
429 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
432 nal_data->gm_local_nid = local_nid;
433 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Local node id is [%u]\n", local_nid));
434 LGMNAL_GM_LOCK(nal_data);
435 gm_status = gm_node_id_to_global_id(nal_data->gm_port, local_nid, &global_nid);
436 LGMNAL_GM_UNLOCK(nal_data);
437 if (gm_status != GM_SUCCESS) {
438 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("failed to obtain global id\n"));
439 lgmnal_stop_rxthread(nal_data);
440 lgmnal_free_stxd(nal_data);
441 lgmnal_free_srxd(nal_data);
442 LGMNAL_GM_LOCK(nal_data);
443 gm_close(nal_data->gm_port);
445 LGMNAL_GM_UNLOCK(nal_data);
446 PORTAL_FREE(nal, sizeof(nal_t));
447 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
448 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
451 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("Global node id is [%u][%x]\n", global_nid));
452 nal_data->gm_global_nid = global_nid;
457 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_pid is [%u]\n", portals_pid));
458 portals_nid = (unsigned long)global_nid;
459 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("portals_nid is [%lu]\n", portals_nid));
461 LGMNAL_PRINT(LGMNAL_DEBUG_V, ("calling lib_init\n"));
462 if (lib_init(nal_cb, portals_nid, portals_pid, 1024, ptl_size, ac_size) != PTL_OK) {
463 LGMNAL_PRINT(LGMNAL_DEBUG_ERR, ("lib_init failed\n"));
464 lgmnal_stop_rxthread(nal_data);
465 lgmnal_free_stxd(nal_data);
466 lgmnal_free_srxd(nal_data);
467 LGMNAL_GM_LOCK(nal_data);
468 gm_close(nal_data->gm_port);
470 LGMNAL_GM_UNLOCK(nal_data);
471 PORTAL_FREE(nal, sizeof(nal_t));
472 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
473 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
478 LGMNAL_PRINT(LGMNAL_DEBUG_VV, ("lgmnal_init finished\n"));
479 global_nal_data = nal->nal_data;
486 * Called when module removed
490 lgmnal_data_t *nal_data = global_nal_data;
491 nal_t *nal = nal_data->nal;
492 nal_cb_t *nal_cb = nal_data->nal_cb;
494 LGMNAL_PRINT(LGMNAL_DEBUG_TRACE, ("lgmnal_fini\n"));
496 PtlNIFini(lgmnal_ni);
499 lgmnal_stop_rxthread(nal_data);
500 lgmnal_free_stxd(nal_data);
501 lgmnal_free_srxd(nal_data);
502 LGMNAL_GM_LOCK(nal_data);
503 gm_close(nal_data->gm_port);
505 LGMNAL_GM_UNLOCK(nal_data);
506 PORTAL_FREE(nal, sizeof(nal_t));
507 PORTAL_FREE(nal_data, sizeof(lgmnal_data_t));
508 PORTAL_FREE(nal_cb, sizeof(nal_cb_t));
511 EXPORT_SYMBOL(lgmnal_init);
512 EXPORT_SYMBOL(lgmnal_fini);
513 EXPORT_SYMBOL(lgmnal_api_forward);
514 EXPORT_SYMBOL(lgmnal_api_validate);
515 EXPORT_SYMBOL(lgmnal_api_yield);
516 EXPORT_SYMBOL(lgmnal_api_lock);
517 EXPORT_SYMBOL(lgmnal_api_unlock);
518 EXPORT_SYMBOL(lgmnal_api_shutdown);