Whamcloud - gitweb
ab3244475cda6a15bb525cebd554508f1ad7de15
[fs/lustre-release.git] / lnet / klnds / gmlnd / gmlnd_utils.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4    Copyright (c) 2003 Los Alamos National Laboratory (LANL)
5  * Copyright (C) 2005 Cluster File Systems, Inc. All rights reserved.
6  *
7  *   This file is part of Lustre, http://www.lustre.org/
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "gmlnd.h"
24
25 void
26 gmnal_free_netbuf_pages (gmnal_netbuf_t *nb, int npages) 
27 {
28         int     i;
29         
30         for (i = 0; i < npages; i++)
31                 __free_page(nb->nb_kiov[i].kiov_page);
32 }
33
34 int
35 gmnal_alloc_netbuf_pages (gmnal_ni_t *gmni, gmnal_netbuf_t *nb, int npages)
36 {
37         int          i;
38         gm_status_t  gmrc;
39
40         LASSERT (npages > 0);
41
42         for (i = 0; i < npages; i++) {
43                 
44                 nb->nb_kiov[i].kiov_page = alloc_page(GFP_KERNEL);
45                 nb->nb_kiov[i].kiov_offset = 0;
46                 nb->nb_kiov[i].kiov_len = PAGE_SIZE;
47
48                 if (nb->nb_kiov[i].kiov_page == NULL) {
49                         CERROR("Can't allocate page\n");
50                         gmnal_free_netbuf_pages(nb, i);
51                         return -ENOMEM;
52                 }
53
54                 CDEBUG(D_NET,"[%3d] page %p, phys "LPX64", @ "LPX64"\n",
55                        i, nb->nb_kiov[i].kiov_page, 
56                        lnet_page2phys(nb->nb_kiov[i].kiov_page),
57                        gmni->gmni_netaddr_base);
58
59                 gmrc = gm_register_memory_ex_phys(
60                         gmni->gmni_port,
61                         lnet_page2phys(nb->nb_kiov[i].kiov_page),
62                         PAGE_SIZE,
63                         gmni->gmni_netaddr_base);
64                 CDEBUG(D_NET,"[%3d] page %p: %d\n", 
65                        i, nb->nb_kiov[i].kiov_page, gmrc);
66
67                 if (gmrc != GM_SUCCESS) {
68                         CERROR("Can't map page: %d(%s)\n", gmrc,
69                                gmnal_gmstatus2str(gmrc));
70                         gmnal_free_netbuf_pages(nb, i+1);
71                         return -ENOMEM;
72                 }
73                 
74                 if (i == 0) 
75                         nb->nb_netaddr = gmni->gmni_netaddr_base;
76                 
77                 gmni->gmni_netaddr_base += PAGE_SIZE;
78         }
79         
80         return 0;
81 }
82
83 void
84 gmnal_free_ltxbuf (gmnal_ni_t *gmni, gmnal_txbuf_t *txb)
85 {
86         int            npages = gmni->gmni_large_pages;
87
88         LASSERT (gmni->gmni_port == NULL);
89         /* No unmapping; the port has been closed */
90
91         gmnal_free_netbuf_pages(&txb->txb_buf, gmni->gmni_large_pages);
92         LIBCFS_FREE(txb, offsetof(gmnal_txbuf_t, txb_buf.nb_kiov[npages]));
93 }
94
95 int
96 gmnal_alloc_ltxbuf (gmnal_ni_t *gmni)
97 {
98         int            npages = gmni->gmni_large_pages;
99         int            sz = offsetof(gmnal_txbuf_t, txb_buf.nb_kiov[npages]);
100         gmnal_txbuf_t *txb;
101         int            rc;
102         
103         LIBCFS_ALLOC(txb, sz);
104         if (txb == NULL) {
105                 CERROR("Can't allocate large txbuffer\n");
106                 return -ENOMEM;
107         }
108
109         rc = gmnal_alloc_netbuf_pages(gmni, &txb->txb_buf, npages);
110         if (rc != 0) {
111                 LIBCFS_FREE(txb, sz);
112                 return rc;
113         }
114
115         list_add_tail(&txb->txb_list, &gmni->gmni_idle_ltxbs);
116
117         txb->txb_next = gmni->gmni_ltxbs;
118         gmni->gmni_ltxbs = txb;
119
120         return 0;
121 }
122
123 void
124 gmnal_free_tx (gmnal_tx_t *tx)
125 {
126         LASSERT (tx->tx_gmni->gmni_port == NULL);
127
128         gmnal_free_netbuf_pages(&tx->tx_buf, 1);
129         LIBCFS_FREE(tx, sizeof(*tx));
130 }
131
132 int
133 gmnal_alloc_tx (gmnal_ni_t *gmni) 
134 {
135         gmnal_tx_t  *tx;
136         int          rc;
137         
138         LIBCFS_ALLOC(tx, sizeof(*tx));
139         if (tx == NULL) {
140                 CERROR("Failed to allocate tx\n");
141                 return -ENOMEM;
142         }
143         
144         memset(tx, 0, sizeof(*tx));
145
146         rc = gmnal_alloc_netbuf_pages(gmni, &tx->tx_buf, 1);
147         if (rc != 0) {
148                 LIBCFS_FREE(tx, sizeof(*tx));
149                 return -ENOMEM;
150         }
151
152         tx->tx_gmni = gmni;
153         
154         list_add_tail(&tx->tx_list, &gmni->gmni_idle_txs);
155
156         tx->tx_next = gmni->gmni_txs;
157         gmni->gmni_txs = tx;
158                 
159         return 0;
160 }
161
162 void
163 gmnal_free_rx(gmnal_ni_t *gmni, gmnal_rx_t *rx)
164 {
165         int   npages = rx->rx_islarge ? gmni->gmni_large_pages : 1;
166         
167         LASSERT (gmni->gmni_port == NULL);
168
169         gmnal_free_netbuf_pages(&rx->rx_buf, npages);
170         LIBCFS_FREE(rx, offsetof(gmnal_rx_t, rx_buf.nb_kiov[npages]));
171 }
172
173 int
174 gmnal_alloc_rx (gmnal_ni_t *gmni, int islarge)
175 {
176         int         npages = islarge ? gmni->gmni_large_pages : 1;
177         int         sz = offsetof(gmnal_rx_t, rx_buf.nb_kiov[npages]);
178         int         rc;
179         gmnal_rx_t *rx;
180         gm_status_t gmrc;
181         
182         LIBCFS_ALLOC(rx, sz);
183         if (rx == NULL) {
184                 CERROR("Failed to allocate rx\n");
185                 return -ENOMEM;
186         }
187         
188         memset(rx, 0, sizeof(*rx));
189
190         rc = gmnal_alloc_netbuf_pages(gmni, &rx->rx_buf, npages);
191         if (rc != 0) {
192                 LIBCFS_FREE(rx, sz);
193                 return rc;
194         }
195         
196         rx->rx_islarge = islarge;
197         rx->rx_next = gmni->gmni_rxs;
198         gmni->gmni_rxs = rx;
199
200         gmrc = gm_hash_insert(gmni->gmni_rx_hash, 
201                               GMNAL_NETBUF_LOCAL_NETADDR(&rx->rx_buf), rx);
202         if (gmrc != GM_SUCCESS) {
203                 CERROR("Couldn't add rx to hash table: %d\n", gmrc);
204                 return -ENOMEM;
205         }
206         
207         return 0;
208 }
209
210 void
211 gmnal_free_ltxbufs (gmnal_ni_t *gmni)
212 {
213         gmnal_txbuf_t *txb;
214         
215         while ((txb = gmni->gmni_ltxbs) != NULL) {
216                 gmni->gmni_ltxbs = txb->txb_next;
217                 gmnal_free_ltxbuf(gmni, txb);
218         }
219 }
220
221 int
222 gmnal_alloc_ltxbufs (gmnal_ni_t *gmni)
223 {
224         int     nlarge_tx_bufs = *gmnal_tunables.gm_nlarge_tx_bufs;
225         int     i;
226         int     rc;
227
228         for (i = 0; i < nlarge_tx_bufs; i++) {
229                 rc = gmnal_alloc_ltxbuf(gmni);
230                 
231                 if (rc != 0)
232                         return rc;
233         }
234
235         return 0;
236 }
237
238 void
239 gmnal_free_txs(gmnal_ni_t *gmni)
240 {
241         gmnal_tx_t *tx;
242
243         while ((tx = gmni->gmni_txs) != NULL) {
244                 gmni->gmni_txs = tx->tx_next;
245                 gmnal_free_tx (tx);
246         }
247 }
248
249 int
250 gmnal_alloc_txs(gmnal_ni_t *gmni)
251 {
252         int           ntxcred = gm_num_send_tokens(gmni->gmni_port);
253         int           ntx = *gmnal_tunables.gm_ntx;
254         int           i;
255         int           rc;
256
257         CDEBUG(D_NET, "ntxcred: %d\n", ntxcred);
258         gmni->gmni_tx_credits = ntxcred;
259
260         for (i = 0; i < ntx; i++) {
261                 rc = gmnal_alloc_tx(gmni);
262                 if (rc != 0)
263                         return rc;
264         }
265
266         return 0;
267 }
268
269 void
270 gmnal_free_rxs(gmnal_ni_t *gmni)
271 {
272         gmnal_rx_t *rx;
273
274         while ((rx = gmni->gmni_rxs) != NULL) {
275                 gmni->gmni_rxs = rx->rx_next;
276
277                 gmnal_free_rx(gmni, rx);
278         }
279
280         LASSERT (gmni->gmni_port == NULL);
281 #if 0
282         /* GM releases all resources allocated to a port when it closes */
283         if (gmni->gmni_rx_hash != NULL)
284                 gm_destroy_hash(gmni->gmni_rx_hash);
285 #endif
286 }
287
288 int
289 gmnal_alloc_rxs (gmnal_ni_t *gmni)
290 {
291         int          nrxcred = gm_num_receive_tokens(gmni->gmni_port);
292         int          nrx_small = *gmnal_tunables.gm_nrx_small;
293         int          nrx_large = *gmnal_tunables.gm_nrx_large;
294         int          nrx = nrx_large + nrx_small;
295         int          rc;
296         int          i;
297
298         CDEBUG(D_NET, "nrxcred: %d(%dL+%dS)\n", nrxcred, nrx_large, nrx_small);
299
300         if (nrx > nrxcred) {
301                 int nlarge = (nrx_large * nrxcred)/nrx;
302                 int nsmall = nrxcred - nlarge;
303                 
304                 CWARN("Only %d rx credits: "
305                       "reducing large %d->%d, small %d->%d\n", nrxcred,
306                       nrx_large, nlarge, nrx_small, nsmall);
307                 
308                 *gmnal_tunables.gm_nrx_large = nrx_large = nlarge;
309                 *gmnal_tunables.gm_nrx_small = nrx_small = nsmall;
310                 nrx = nlarge + nsmall;
311         }
312         
313         gmni->gmni_rx_hash = gm_create_hash(gm_hash_compare_ptrs, 
314                                             gm_hash_hash_ptr, 0, 0, nrx, 0);
315         if (gmni->gmni_rx_hash == NULL) {
316                 CERROR("Failed to create hash table\n");
317                 return -ENOMEM;
318         }
319
320         for (i = 0; i < nrx; i++ ) {
321                 rc = gmnal_alloc_rx(gmni, i < nrx_large);
322                 if (rc != 0)
323                         return rc;
324         }
325
326         return 0;
327 }
328
329 char * 
330 gmnal_gmstatus2str(gm_status_t status)
331 {
332         return(gm_strerror(status));
333
334         switch(status) {
335         case(GM_SUCCESS):
336                 return("SUCCESS");
337         case(GM_FAILURE):
338                 return("FAILURE");
339         case(GM_INPUT_BUFFER_TOO_SMALL):
340                 return("INPUT_BUFFER_TOO_SMALL");
341         case(GM_OUTPUT_BUFFER_TOO_SMALL):
342                 return("OUTPUT_BUFFER_TOO_SMALL");
343         case(GM_TRY_AGAIN ):
344                 return("TRY_AGAIN");
345         case(GM_BUSY):
346                 return("BUSY");
347         case(GM_MEMORY_FAULT):
348                 return("MEMORY_FAULT");
349         case(GM_INTERRUPTED):
350                 return("INTERRUPTED");
351         case(GM_INVALID_PARAMETER):
352                 return("INVALID_PARAMETER");
353         case(GM_OUT_OF_MEMORY):
354                 return("OUT_OF_MEMORY");
355         case(GM_INVALID_COMMAND):
356                 return("INVALID_COMMAND");
357         case(GM_PERMISSION_DENIED):
358                 return("PERMISSION_DENIED");
359         case(GM_INTERNAL_ERROR):
360                 return("INTERNAL_ERROR");
361         case(GM_UNATTACHED):
362                 return("UNATTACHED");
363         case(GM_UNSUPPORTED_DEVICE):
364                 return("UNSUPPORTED_DEVICE");
365         case(GM_SEND_TIMED_OUT):
366                 return("GM_SEND_TIMEDOUT");
367         case(GM_SEND_REJECTED):
368                 return("GM_SEND_REJECTED");
369         case(GM_SEND_TARGET_PORT_CLOSED):
370                 return("GM_SEND_TARGET_PORT_CLOSED");
371         case(GM_SEND_TARGET_NODE_UNREACHABLE):
372                 return("GM_SEND_TARGET_NODE_UNREACHABLE");
373         case(GM_SEND_DROPPED):
374                 return("GM_SEND_DROPPED");
375         case(GM_SEND_PORT_CLOSED):
376                 return("GM_SEND_PORT_CLOSED");
377         case(GM_NODE_ID_NOT_YET_SET):
378                 return("GM_NODE_ID_NOT_YET_SET");
379         case(GM_STILL_SHUTTING_DOWN):
380                 return("GM_STILL_SHUTTING_DOWN");
381         case(GM_CLONE_BUSY):
382                 return("GM_CLONE_BUSY");
383         case(GM_NO_SUCH_DEVICE):
384                 return("GM_NO_SUCH_DEVICE");
385         case(GM_ABORTED):
386                 return("GM_ABORTED");
387         case(GM_INCOMPATIBLE_LIB_AND_DRIVER):
388                 return("GM_INCOMPATIBLE_LIB_AND_DRIVER");
389         case(GM_UNTRANSLATED_SYSTEM_ERROR):
390                 return("GM_UNTRANSLATED_SYSTEM_ERROR");
391         case(GM_ACCESS_DENIED):
392                 return("GM_ACCESS_DENIED");
393
394         
395         /*
396          *      These ones are in the docs but aren't in the header file 
397          case(GM_DEV_NOT_FOUND):
398          return("GM_DEV_NOT_FOUND");
399          case(GM_INVALID_PORT_NUMBER):
400          return("GM_INVALID_PORT_NUMBER");
401          case(GM_UC_ERROR):
402          return("GM_US_ERROR");
403          case(GM_PAGE_TABLE_FULL):
404          return("GM_PAGE_TABLE_FULL");
405          case(GM_MINOR_OVERFLOW):
406          return("GM_MINOR_OVERFLOW");
407          case(GM_SEND_ORPHANED):
408          return("GM_SEND_ORPHANED");
409          case(GM_HARDWARE_FAULT):
410          return("GM_HARDWARE_FAULT");
411          case(GM_DATA_CORRUPTED):
412          return("GM_DATA_CORRUPTED");
413          case(GM_TIMED_OUT):
414          return("GM_TIMED_OUT");
415          case(GM_USER_ERROR):
416          return("GM_USER_ERROR");
417          case(GM_NO_MATCH):
418          return("GM_NOMATCH");
419          case(GM_NOT_SUPPORTED_IN_KERNEL):
420          return("GM_NOT_SUPPORTED_IN_KERNEL");
421          case(GM_NOT_SUPPORTED_ON_ARCH):
422          return("GM_NOT_SUPPORTED_ON_ARCH");
423          case(GM_PTE_REF_CNT_OVERFLOW):
424          return("GM_PTR_REF_CNT_OVERFLOW");
425          case(GM_NO_DRIVER_SUPPORT):
426          return("GM_NO_DRIVER_SUPPORT");
427          case(GM_FIRMWARE_NOT_RUNNING):
428          return("GM_FIRMWARE_NOT_RUNNING");
429          *      These ones are in the docs but aren't in the header file 
430          */
431
432         default:
433                 return("UNKNOWN GM ERROR CODE");
434         }
435 }
436
437
438 char *
439 gmnal_rxevent2str(gm_recv_event_t *ev)
440 {
441         short   event;
442         event = GM_RECV_EVENT_TYPE(ev);
443         switch(event) {
444         case(GM_NO_RECV_EVENT):
445                 return("GM_NO_RECV_EVENT");
446         case(GM_SENDS_FAILED_EVENT):
447                 return("GM_SEND_FAILED_EVENT");
448         case(GM_ALARM_EVENT):
449                 return("GM_ALARM_EVENT");
450         case(GM_SENT_EVENT):
451                 return("GM_SENT_EVENT");
452         case(_GM_SLEEP_EVENT):
453                 return("_GM_SLEEP_EVENT");
454         case(GM_RAW_RECV_EVENT):
455                 return("GM_RAW_RECV_EVENT");
456         case(GM_BAD_SEND_DETECTED_EVENT):
457                 return("GM_BAD_SEND_DETECTED_EVENT");
458         case(GM_SEND_TOKEN_VIOLATION_EVENT):
459                 return("GM_SEND_TOKEN_VIOLATION_EVENT");
460         case(GM_RECV_TOKEN_VIOLATION_EVENT):
461                 return("GM_RECV_TOKEN_VIOLATION_EVENT");
462         case(GM_BAD_RECV_TOKEN_EVENT):
463                 return("GM_BAD_RECV_TOKEN_EVENT");
464         case(GM_ALARM_VIOLATION_EVENT):
465                 return("GM_ALARM_VIOLATION_EVENT");
466         case(GM_RECV_EVENT):
467                 return("GM_RECV_EVENT");
468         case(GM_HIGH_RECV_EVENT):
469                 return("GM_HIGH_RECV_EVENT");
470         case(GM_PEER_RECV_EVENT):
471                 return("GM_PEER_RECV_EVENT");
472         case(GM_HIGH_PEER_RECV_EVENT):
473                 return("GM_HIGH_PEER_RECV_EVENT");
474         case(GM_FAST_RECV_EVENT):
475                 return("GM_FAST_RECV_EVENT");
476         case(GM_FAST_HIGH_RECV_EVENT):
477                 return("GM_FAST_HIGH_RECV_EVENT");
478         case(GM_FAST_PEER_RECV_EVENT):
479                 return("GM_FAST_PEER_RECV_EVENT");
480         case(GM_FAST_HIGH_PEER_RECV_EVENT):
481                 return("GM_FAST_HIGH_PEER_RECV_EVENT");
482         case(GM_REJECTED_SEND_EVENT):
483                 return("GM_REJECTED_SEND_EVENT");
484         case(GM_ORPHANED_SEND_EVENT):
485                 return("GM_ORPHANED_SEND_EVENT");
486         case(GM_BAD_RESEND_DETECTED_EVENT):
487                 return("GM_BAD_RESEND_DETETED_EVENT");
488         case(GM_DROPPED_SEND_EVENT):
489                 return("GM_DROPPED_SEND_EVENT");
490         case(GM_BAD_SEND_VMA_EVENT):
491                 return("GM_BAD_SEND_VMA_EVENT");
492         case(GM_BAD_RECV_VMA_EVENT):
493                 return("GM_BAD_RECV_VMA_EVENT");
494         case(_GM_FLUSHED_ALARM_EVENT):
495                 return("GM_FLUSHED_ALARM_EVENT");
496         case(GM_SENT_TOKENS_EVENT):
497                 return("GM_SENT_TOKENS_EVENTS");
498         case(GM_IGNORE_RECV_EVENT):
499                 return("GM_IGNORE_RECV_EVENT");
500         case(GM_ETHERNET_RECV_EVENT):
501                 return("GM_ETHERNET_RECV_EVENT");
502         case(GM_NEW_NO_RECV_EVENT):
503                 return("GM_NEW_NO_RECV_EVENT");
504         case(GM_NEW_SENDS_FAILED_EVENT):
505                 return("GM_NEW_SENDS_FAILED_EVENT");
506         case(GM_NEW_ALARM_EVENT):
507                 return("GM_NEW_ALARM_EVENT");
508         case(GM_NEW_SENT_EVENT):
509                 return("GM_NEW_SENT_EVENT");
510         case(_GM_NEW_SLEEP_EVENT):
511                 return("GM_NEW_SLEEP_EVENT");
512         case(GM_NEW_RAW_RECV_EVENT):
513                 return("GM_NEW_RAW_RECV_EVENT");
514         case(GM_NEW_BAD_SEND_DETECTED_EVENT):
515                 return("GM_NEW_BAD_SEND_DETECTED_EVENT");
516         case(GM_NEW_SEND_TOKEN_VIOLATION_EVENT):
517                 return("GM_NEW_SEND_TOKEN_VIOLATION_EVENT");
518         case(GM_NEW_RECV_TOKEN_VIOLATION_EVENT):
519                 return("GM_NEW_RECV_TOKEN_VIOLATION_EVENT");
520         case(GM_NEW_BAD_RECV_TOKEN_EVENT):
521                 return("GM_NEW_BAD_RECV_TOKEN_EVENT");
522         case(GM_NEW_ALARM_VIOLATION_EVENT):
523                 return("GM_NEW_ALARM_VIOLATION_EVENT");
524         case(GM_NEW_RECV_EVENT):
525                 return("GM_NEW_RECV_EVENT");
526         case(GM_NEW_HIGH_RECV_EVENT):
527                 return("GM_NEW_HIGH_RECV_EVENT");
528         case(GM_NEW_PEER_RECV_EVENT):
529                 return("GM_NEW_PEER_RECV_EVENT");
530         case(GM_NEW_HIGH_PEER_RECV_EVENT):
531                 return("GM_NEW_HIGH_PEER_RECV_EVENT");
532         case(GM_NEW_FAST_RECV_EVENT):
533                 return("GM_NEW_FAST_RECV_EVENT");
534         case(GM_NEW_FAST_HIGH_RECV_EVENT):
535                 return("GM_NEW_FAST_HIGH_RECV_EVENT");
536         case(GM_NEW_FAST_PEER_RECV_EVENT):
537                 return("GM_NEW_FAST_PEER_RECV_EVENT");
538         case(GM_NEW_FAST_HIGH_PEER_RECV_EVENT):
539                 return("GM_NEW_FAST_HIGH_PEER_RECV_EVENT");
540         case(GM_NEW_REJECTED_SEND_EVENT):
541                 return("GM_NEW_REJECTED_SEND_EVENT");
542         case(GM_NEW_ORPHANED_SEND_EVENT):
543                 return("GM_NEW_ORPHANED_SEND_EVENT");
544         case(_GM_NEW_PUT_NOTIFICATION_EVENT):
545                 return("_GM_NEW_PUT_NOTIFICATION_EVENT");
546         case(GM_NEW_FREE_SEND_TOKEN_EVENT):
547                 return("GM_NEW_FREE_SEND_TOKEN_EVENT");
548         case(GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT):
549                 return("GM_NEW_FREE_HIGH_SEND_TOKEN_EVENT");
550         case(GM_NEW_BAD_RESEND_DETECTED_EVENT):
551                 return("GM_NEW_BAD_RESEND_DETECTED_EVENT");
552         case(GM_NEW_DROPPED_SEND_EVENT):
553                 return("GM_NEW_DROPPED_SEND_EVENT");
554         case(GM_NEW_BAD_SEND_VMA_EVENT):
555                 return("GM_NEW_BAD_SEND_VMA_EVENT");
556         case(GM_NEW_BAD_RECV_VMA_EVENT):
557                 return("GM_NEW_BAD_RECV_VMA_EVENT");
558         case(_GM_NEW_FLUSHED_ALARM_EVENT):
559                 return("GM_NEW_FLUSHED_ALARM_EVENT");
560         case(GM_NEW_SENT_TOKENS_EVENT):
561                 return("GM_NEW_SENT_TOKENS_EVENT");
562         case(GM_NEW_IGNORE_RECV_EVENT):
563                 return("GM_NEW_IGNORE_RECV_EVENT");
564         case(GM_NEW_ETHERNET_RECV_EVENT):
565                 return("GM_NEW_ETHERNET_RECV_EVENT");
566         default:
567                 return("Unknown Recv event");
568         /* _GM_PUT_NOTIFICATION_EVENT */
569         /* GM_FREE_SEND_TOKEN_EVENT */
570         /* GM_FREE_HIGH_SEND_TOKEN_EVENT */
571         }
572 }
573
574
575 void
576 gmnal_yield(int delay)
577 {
578         set_current_state(TASK_INTERRUPTIBLE);
579         schedule_timeout(delay);
580 }