winverbs: delete critical sections when no longer needed
[mirror/winof/.git] / ulp / libibumad / src / umad.cpp
1 /*\r
2  * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.\r
3  * Copyright (c) 2008 Intel Corp., Inc.  All rights reserved.\r
4  *\r
5  * This software is available to you under a choice of one of two\r
6  * licenses.  You may choose to be licensed under the terms of the GNU\r
7  * General Public License (GPL) Version 2, available from the file\r
8  * COPYING in the main directory of this source tree, or the\r
9  * OpenIB.org BSD license below:\r
10  *\r
11  *     Redistribution and use in source and binary forms, with or\r
12  *     without modification, are permitted provided that the following\r
13  *     conditions are met:\r
14  *\r
15  *      - Redistributions of source code must retain the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer.\r
18  *\r
19  *      - Redistributions in binary form must reproduce the above\r
20  *        copyright notice, this list of conditions and the following\r
21  *        disclaimer in the documentation and/or other materials\r
22  *        provided with the distribution.\r
23  *\r
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
31  * SOFTWARE.\r
32  *\r
33  */\r
34 \r
35 #include <windows.h>\r
36 #include <stdio.h>\r
37 \r
38 #include <infiniband/umad.h>\r
39 #include <infiniband/verbs.h>\r
40 #include <rdma/wvstatus.h>\r
41 #include "ibumad.h"\r
42 \r
43 #define IB_OPENIB_OUI                 (0x001405)\r
44 \r
45 #define UMAD_MAX_PKEYS  16\r
46 \r
47 typedef struct um_port\r
48 {\r
49         IWMProvider *prov;\r
50         NET64           dev_guid;\r
51         OVERLAPPED      overlap;\r
52         BOOL            pending;\r
53         UINT8           port_num;\r
54 \r
55 }       um_port_t;\r
56 \r
57 CRITICAL_SECTION crit_sec;\r
58 um_port_t ports[UMAD_MAX_PORTS];\r
59 \r
60 \r
61 __declspec(dllexport)\r
62 int umad_init(void)\r
63 {\r
64         InitializeCriticalSection(&crit_sec);\r
65         return 0;\r
66 }\r
67 \r
68 __declspec(dllexport)\r
69 int umad_done(void)\r
70 {\r
71         DeleteCriticalSection(&crit_sec);\r
72         return 0;\r
73 }\r
74 \r
75 __declspec(dllexport)\r
76 int umad_get_cas_names(char cas[][UMAD_CA_NAME_LEN], int max)\r
77 {\r
78         struct ibv_device       **list;\r
79         int                                     cnt, i;\r
80 \r
81         list = ibv_get_device_list(&cnt);\r
82         if (list == NULL) {\r
83                 return 0;\r
84         }\r
85 \r
86         for (i = 0; i < min(cnt, max); i++) {\r
87                 strcpy(cas[i], ibv_get_device_name(list[i]));\r
88         }\r
89 \r
90         ibv_free_device_list(list);\r
91         return i;\r
92 }\r
93 \r
94 __declspec(dllexport)\r
95 int umad_get_ca_portguids(char *ca_name, uint64_t *portguids, int max)\r
96 {\r
97         umad_ca_t       ca;\r
98         int                     ports = 0, i;\r
99 \r
100         if (umad_get_ca(ca_name, &ca) < 0)\r
101                 return -1;\r
102 \r
103         if (ca.numports + 1 > max) {\r
104                 umad_release_ca(&ca);\r
105                 return -ENOMEM;\r
106         }\r
107 \r
108         portguids[ports++] = 0;\r
109         for (i = 1; i <= ca.numports; i++)\r
110                 portguids[ports++] = ca.ports[i]->port_guid;\r
111 \r
112         umad_release_ca(&ca);\r
113         return ports;\r
114 }\r
115 \r
116 static void umad_convert_ca_attr(umad_ca_t *ca, ibv_device_attr *attr)\r
117 {\r
118         ca->node_type = 1;      // HCA\r
119         ca->numports = attr->phys_port_cnt;\r
120         strncpy(ca->fw_ver, attr->fw_ver, 20);\r
121         memset(ca->ca_type, 0, 40);             // TODO: determine what this should be\r
122         sprintf(ca->hw_ver, "0x%x", attr->hw_ver);\r
123         ca->node_guid = attr->node_guid;\r
124         ca->system_guid = attr->sys_image_guid;\r
125 }\r
126 \r
127 static int umad_query_port(struct ibv_context *context, umad_port_t *port)\r
128 {\r
129         ibv_port_attr   attr;\r
130         ibv_gid                 gid;\r
131         int                             i, ret;\r
132 \r
133         ret = ibv_query_port(context, (uint8_t) port->portnum, &attr);\r
134         if (ret != 0) {\r
135                 return ret;\r
136         }\r
137 \r
138         port->base_lid = attr.lid;\r
139         port->lmc = attr.lmc;\r
140         port->sm_lid = attr.sm_lid;\r
141         port->sm_sl = attr.sm_sl;\r
142         port->state = attr.state;\r
143         port->phys_state = attr.phys_state;\r
144         port->rate = attr.active_speed;\r
145         port->capmask = attr.port_cap_flags;\r
146 \r
147         // Assume GID 0 contains port GUID and gid prefix\r
148         ret = ibv_query_gid(context, (uint8_t) port->portnum, 0, &gid);\r
149         if (ret != 0) {\r
150                 return ret;\r
151         }\r
152 \r
153         port->gid_prefix = gid.global.subnet_prefix;\r
154         port->port_guid = gid.global.interface_id;\r
155 \r
156         port->pkeys_size = min(UMAD_MAX_PKEYS, attr.pkey_tbl_len);\r
157         for (i = 0; i < (int) port->pkeys_size; i++) {\r
158                 ret = ibv_query_pkey(context,(uint8_t)  port->portnum, i, &port->pkeys[i]);\r
159                 if (ret != 0) {\r
160                         return ret;\r
161                 }\r
162         }\r
163 \r
164         return 0;\r
165 }\r
166 \r
167 __declspec(dllexport)\r
168 int umad_get_ca(char *ca_name, umad_ca_t *ca)\r
169 {\r
170         struct ibv_device       **list;\r
171         struct ibv_context      *context;\r
172         ibv_device_attr         dev_attr;\r
173         int                                     cnt, i, ret = 0;\r
174         uint8_t                         *ports;\r
175         size_t                          port_size;\r
176 \r
177         list = ibv_get_device_list(&cnt);\r
178         if (list == NULL) {\r
179                 return -ENOMEM;\r
180         }\r
181 \r
182         for (i = 0; i < cnt; i++) {\r
183                 if (!strcmp(ca_name, ibv_get_device_name(list[i]))) {\r
184                         break;\r
185                 }\r
186         }\r
187 \r
188         if (i == cnt) {\r
189                 ret = -EINVAL;\r
190                 goto free;\r
191         }\r
192 \r
193         context = ibv_open_device(list[i]);\r
194         if (context == NULL) {\r
195                 ret = -ENOMEM;\r
196                 goto free;\r
197         }\r
198 \r
199         ret = ibv_query_device(context, &dev_attr);\r
200         if (ret != 0) {\r
201                 goto close;\r
202         }\r
203 \r
204         port_size = sizeof(umad_port_t) + sizeof(uint16_t) * UMAD_MAX_PKEYS;\r
205         ports = new uint8_t[port_size * dev_attr.phys_port_cnt];\r
206         if (ports == NULL) {\r
207                 ret = -ENOMEM;\r
208                 goto close;\r
209         }\r
210 \r
211         strcpy(ca->ca_name, ca_name);\r
212         umad_convert_ca_attr(ca, &dev_attr);\r
213         memset(ca->ports, 0, sizeof(ca->ports));\r
214 \r
215         for (i = 1; i <= dev_attr.phys_port_cnt; i++, ports += port_size) {\r
216 \r
217                 ca->ports[i] = (umad_port_t *) ports;\r
218                 strcpy(ca->ports[i]->ca_name, ca_name);\r
219                 ca->ports[i]->portnum = i;\r
220                 ca->ports[i]->pkeys = (uint16_t *) (ports + sizeof(umad_port_t));\r
221 \r
222                 ret = umad_query_port(context, ca->ports[i]);\r
223                 if (ret != 0) {\r
224                         goto close;\r
225                 }\r
226         }\r
227 \r
228 close:\r
229         ibv_close_device(context);\r
230 free:\r
231         ibv_free_device_list(list);\r
232         if (ret != 0) {\r
233                 delete ca;\r
234         }\r
235         return ret;\r
236 }\r
237 \r
238 __declspec(dllexport)\r
239 int umad_release_ca(umad_ca_t *ca)\r
240 {\r
241         delete ca->ports[0];\r
242         return 0;\r
243 }\r
244 \r
245 static uint64_t umad_get_ca_guid(char *ca_name)\r
246 {\r
247         umad_ca_t       ca;\r
248         uint64_t        guid;\r
249         int                     ret;\r
250 \r
251         ret = umad_get_ca(ca_name, &ca);\r
252         if (ret != 0) {\r
253                 return 0;\r
254         }\r
255 \r
256         guid = ca.node_guid;\r
257         umad_release_ca(&ca);\r
258         return guid;\r
259 }\r
260 \r
261 __declspec(dllexport)\r
262 int umad_get_port(char *ca_name, int portnum, umad_port_t *port)\r
263 {\r
264         umad_ca_t       ca;\r
265         int                     ret;\r
266 \r
267         ret = umad_get_ca(ca_name, &ca);\r
268         if (ret != 0) {\r
269                 return ret;\r
270         }\r
271 \r
272         memcpy(port, ca.ports[portnum], sizeof(umad_port_t));\r
273 \r
274         port->pkeys = new uint16_t[ca.ports[portnum]->pkeys_size];\r
275         if (port->pkeys == NULL) {\r
276                 ret = -ENOMEM;\r
277                 goto out;\r
278         }\r
279 \r
280         memcpy(port->pkeys, ca.ports[portnum]->pkeys,\r
281                    sizeof(uint16_t) * ca.ports[portnum]->pkeys_size);\r
282 out:\r
283         umad_release_ca(&ca);\r
284         return ret;\r
285 }\r
286 \r
287 __declspec(dllexport)\r
288 int umad_release_port(umad_port_t *port)\r
289 {\r
290         delete port->pkeys;\r
291         return 0;\r
292 }\r
293 \r
294 __declspec(dllexport)\r
295 int umad_get_issm_path(char *ca_name, int portnum, char path[], int max)\r
296 {\r
297         return -EINVAL;\r
298 }\r
299 \r
300 static uint8_t umad_find_port(char *ca_name, enum ibv_port_state state)\r
301 {\r
302         umad_ca_t       ca;\r
303         int                     i, ret;\r
304 \r
305         ret = umad_get_ca(ca_name, &ca);\r
306         if (ret != 0) {\r
307                 return 0;\r
308         }\r
309 \r
310         for (i = 1; i <= ca.numports; i++) {\r
311                 if (ca.ports[i]->state == state) {\r
312                         i = ca.ports[i]->portnum;\r
313                         umad_release_ca(&ca);\r
314                         return (uint8_t) i;\r
315                 }\r
316         }\r
317 \r
318         umad_release_ca(&ca);\r
319         return 0;\r
320 }\r
321 \r
322 static int umad_find_ca_port(enum ibv_port_state state, char *ca_name, uint8_t *port)\r
323 {\r
324         char            names[8][UMAD_CA_NAME_LEN];\r
325         int                     cnt, i;\r
326 \r
327         cnt = umad_get_cas_names(names, 8);\r
328 \r
329         for (i = 0; i < cnt; i++) {\r
330                 *port = umad_find_port(names[i], state);\r
331                 if (*port != 0) {\r
332                         strcpy(ca_name, names[i]);\r
333                         return 0;\r
334                 }\r
335         }\r
336         return -1;\r
337 }\r
338 \r
339 static int umad_resolve_ca_port(char *ca_name, uint8_t *port)\r
340 {\r
341         int ret;\r
342 \r
343         if (ca_name[0] != NULL) {\r
344                 if (*port != 0) {\r
345                         return 0;\r
346                 }\r
347 \r
348                 *port = umad_find_port(ca_name, IBV_PORT_ACTIVE);\r
349                 if (*port != 0) {\r
350                         return 0;\r
351                 }\r
352                 *port = umad_find_port(ca_name, IBV_PORT_INIT);\r
353                 if (*port != 0) {\r
354                         return 0;\r
355                 }\r
356                 *port = umad_find_port(ca_name, IBV_PORT_DOWN);\r
357                 return (*port == 0);\r
358         }\r
359 \r
360         ret = umad_find_ca_port(IBV_PORT_ACTIVE, ca_name, port);\r
361         if (ret == 0) {\r
362                 return 0;\r
363         }\r
364         ret = umad_find_ca_port(IBV_PORT_INIT, ca_name, port);\r
365         if (ret == 0) {\r
366                 return 0;\r
367         }\r
368         ret = umad_find_ca_port(IBV_PORT_DOWN, ca_name, port);\r
369         return ret;\r
370 }\r
371 \r
372 __declspec(dllexport)\r
373 int umad_open_port(char *ca_name, int portnum)\r
374 {\r
375         char    name[UMAD_CA_NAME_LEN];\r
376         uint8_t port;\r
377         HRESULT hr;\r
378         int             portid;\r
379 \r
380         if (ca_name != NULL) {\r
381                 strcpy(name, ca_name);\r
382                 port = (uint8_t) portnum;\r
383         } else {\r
384                 name[0] = NULL;\r
385                 port = 0;\r
386         }\r
387 \r
388         hr = umad_resolve_ca_port(name, &port);\r
389         if (FAILED(hr)) {\r
390                 return hr;\r
391         }\r
392 \r
393         EnterCriticalSection(&crit_sec);\r
394         for (portid = 0; portid < UMAD_MAX_PORTS; portid++) {\r
395                 if (ports[portid].prov == NULL) {\r
396                         break;\r
397                 }\r
398         }\r
399 \r
400         if (portid == UMAD_MAX_PORTS) {\r
401                 portid = -ENOMEM;\r
402                 goto out;\r
403         }\r
404 \r
405         ports[portid].overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
406         if (ports[portid].overlap.hEvent == NULL) {\r
407                 portid = -ENOMEM;\r
408                 goto out;\r
409         }\r
410 \r
411         hr = WmGetObject(IID_IWMProvider, (LPVOID*) &ports[portid].prov);\r
412         if (FAILED(hr)) {\r
413                 CloseHandle(ports[portid].overlap.hEvent);\r
414                 portid = GetLastError() & 0x80000000;\r
415                 goto out;\r
416         }\r
417 \r
418         ports[portid].dev_guid = umad_get_ca_guid(name);\r
419         ports[portid].port_num = port;\r
420 \r
421 out:\r
422         LeaveCriticalSection(&crit_sec);\r
423         return portid;\r
424 }\r
425 \r
426 __declspec(dllexport)\r
427 int umad_close_port(int portid)\r
428 {\r
429         CloseHandle(ports[portid].overlap.hEvent);\r
430         ports[portid].prov->Release();\r
431 \r
432         EnterCriticalSection(&crit_sec);\r
433         ports[portid].prov = NULL;\r
434         LeaveCriticalSection(&crit_sec);\r
435 \r
436         return 0;\r
437 }\r
438 \r
439 __declspec(dllexport)\r
440 int umad_set_grh_net(void *umad, void *mad_addr)\r
441 {\r
442         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
443         struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
444 \r
445         if (mad_addr) {\r
446                 mad->addr.grh_present = 1;\r
447                 memcpy(mad->addr.gid, addr->gid, 16);\r
448                 mad->addr.flow_label = addr->flow_label;\r
449                 mad->addr.hop_limit = addr->hop_limit;\r
450                 mad->addr.traffic_class = addr->traffic_class;\r
451         } else\r
452                 mad->addr.grh_present = 0;\r
453         return 0;\r
454 }\r
455 \r
456 __declspec(dllexport)\r
457 int umad_set_grh(void *umad, void *mad_addr)\r
458 {\r
459         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
460         struct ib_mad_addr *addr = (struct ib_mad_addr *) mad_addr;\r
461 \r
462         if (mad_addr) {\r
463                 mad->addr.grh_present = 1;\r
464                 memcpy(mad->addr.gid, addr->gid, 16);\r
465                 mad->addr.flow_label = htonl(addr->flow_label);\r
466                 mad->addr.hop_limit = addr->hop_limit;\r
467                 mad->addr.traffic_class = addr->traffic_class;\r
468         } else\r
469                 mad->addr.grh_present = 0;\r
470         return 0;\r
471 }\r
472 \r
473 __declspec(dllexport)\r
474 int umad_set_pkey(void *umad, int pkey_index)\r
475 {\r
476         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
477 \r
478         mad->addr.pkey_index = (uint16_t) pkey_index;\r
479         return 0;\r
480 }\r
481 \r
482 __declspec(dllexport)\r
483 int umad_get_pkey(void *umad)\r
484 {\r
485         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
486 \r
487         return mad->addr.pkey_index;\r
488 }\r
489 \r
490 __declspec(dllexport)\r
491 int umad_set_addr(void *umad, int dlid, int dqp, int sl, int qkey)\r
492 {\r
493         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
494 \r
495         mad->addr.qpn = htonl(dqp);\r
496         mad->addr.lid = htons((uint16_t) dlid);\r
497         mad->addr.qkey = htonl(qkey);\r
498         mad->addr.sl = (uint8_t) sl;\r
499         return 0;\r
500 }\r
501 \r
502 __declspec(dllexport)\r
503 int umad_set_addr_net(void *umad, int dlid, int dqp, int sl, int qkey)\r
504 {\r
505         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
506 \r
507         mad->addr.qpn = dqp;\r
508         mad->addr.lid = (uint16_t) dlid;\r
509         mad->addr.qkey = qkey;\r
510         mad->addr.sl = (uint8_t) sl;\r
511 \r
512         return 0;\r
513 }\r
514 \r
515 __declspec(dllexport)\r
516 int umad_status(void *umad)\r
517 {\r
518         return ((struct ib_user_mad *) umad)->status;\r
519 }\r
520 \r
521 __declspec(dllexport)\r
522 ib_mad_addr_t *umad_get_mad_addr(void *umad)\r
523 {\r
524         return &((struct ib_user_mad *) umad)->addr;\r
525 }\r
526 \r
527 __declspec(dllexport)\r
528 void *umad_get_mad(void *umad)\r
529 {\r
530         return ((struct ib_user_mad *)umad)->data;\r
531 }\r
532 \r
533 __declspec(dllexport)\r
534 void *umad_alloc(int num, size_t size)\r
535 {\r
536         return new uint8_t[num * size];\r
537 }\r
538 \r
539 __declspec(dllexport)\r
540 void umad_free(void *umad)\r
541 {\r
542         delete umad;\r
543 }\r
544 \r
545 __declspec(dllexport)\r
546 size_t umad_size(void)\r
547 {\r
548         return sizeof(struct ib_user_mad);\r
549 }\r
550 \r
551 __declspec(dllexport)\r
552 int umad_send(int portid, int agentid, void *umad, int length,\r
553                           int timeout_ms, int retries)\r
554 {\r
555         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
556         HRESULT hr;\r
557 \r
558         mad->agent_id = agentid;\r
559         mad->reserved_id = 0;\r
560 \r
561         mad->timeout_ms = (uint32_t) timeout_ms;\r
562         mad->retries    = (uint32_t) retries;\r
563         mad->length             = (uint32_t) length;\r
564 \r
565         hr = ports[portid].prov->Send((WM_MAD *) mad, NULL);\r
566         if (FAILED(hr)) {\r
567                 return GetLastError();\r
568         }\r
569 \r
570         return 0;\r
571 }\r
572 \r
573 __declspec(dllexport)\r
574 int umad_recv(int portid, void *umad, int *length, int timeout_ms)\r
575 {\r
576         WM_MAD          *mad = (WM_MAD *) umad;\r
577         um_port_t       *port;\r
578         HRESULT         hr;\r
579 \r
580         port = &ports[portid];\r
581         hr = port->prov->Receive(mad, sizeof(WM_MAD) + (size_t) *length, &port->overlap);\r
582 \r
583         if (hr == WV_IO_PENDING) {\r
584                 if (port->pending && timeout_ms == 0) {\r
585                         do {\r
586                                 hr = WaitForSingleObject(port->overlap.hEvent, 250);\r
587                         } while (hr == WAIT_TIMEOUT && port->pending);\r
588                 } else {\r
589                         hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
590                         if (hr == WAIT_TIMEOUT) {\r
591                                 return -EWOULDBLOCK;\r
592                         }\r
593                 }\r
594         }\r
595 \r
596         if (FAILED(hr)) {\r
597                 return -EIO;\r
598         }\r
599 \r
600         if (mad->Length <= (UINT32) *length) {\r
601                 port->pending = FALSE;\r
602                 hr = (HRESULT) mad->Id;\r
603         } else {\r
604                 errno = ENOSPC;\r
605                 hr = -ENOSPC;\r
606         }\r
607 \r
608         *length = mad->Length;\r
609         return hr;\r
610 }\r
611 \r
612 __declspec(dllexport)\r
613 int umad_poll(int portid, int timeout_ms)\r
614 {\r
615         WM_MAD          mad;\r
616         um_port_t       *port;\r
617         HRESULT         hr;\r
618 \r
619         port = &ports[portid];\r
620         hr = port->prov->Receive(&mad, sizeof mad, &port->overlap);\r
621 \r
622         if (hr == WV_IO_PENDING) {\r
623                 hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
624                 if (hr == WAIT_TIMEOUT) {\r
625                         return -ETIMEDOUT;\r
626                 }\r
627         }\r
628 \r
629         if (FAILED(hr) && hr != ERROR_MORE_DATA) {\r
630                 return -EIO;\r
631         }\r
632 \r
633         port->pending = TRUE;\r
634         return 0;\r
635 }\r
636 \r
637 __declspec(dllexport)\r
638 int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version,\r
639                                           uint8_t oui[3], long method_mask[16/sizeof(long)])\r
640 {\r
641         WM_REGISTER reg;\r
642         UINT64          id = 0;\r
643 \r
644         UNREFERENCED_PARAMETER(rmpp_version);\r
645 \r
646         reg.Guid = ports[portid].dev_guid;\r
647         reg.Qpn = (mgmt_class == 0x01 || mgmt_class == 0x81) ? 0 : htonl(1);\r
648         reg.Port = ports[portid].port_num;\r
649         reg.Class = (uint8_t) mgmt_class;\r
650         reg.Version = 1;\r
651         memset(reg.Reserved, 0, sizeof(reg.Reserved));\r
652         memcpy(reg.Oui, oui, sizeof(oui));\r
653         if (method_mask != NULL) {\r
654                 memcpy(reg.Methods, method_mask, sizeof(reg.Methods));\r
655         } else {\r
656                 memset(reg.Methods, 0, sizeof(reg.Methods));\r
657         }\r
658         ports[portid].prov->Register(&reg, &id);\r
659 \r
660         return (int) id;\r
661 }\r
662 \r
663 __declspec(dllexport)\r
664 int umad_register(int portid, int mgmt_class, int mgmt_version,\r
665                                   uint8_t rmpp_version, long method_mask[16/sizeof(long)])\r
666 {\r
667         uint8_t oui[3];\r
668 \r
669         memset(oui, 0, 3);\r
670         return umad_register_oui(portid, mgmt_class, rmpp_version, oui, method_mask);\r
671 }\r
672 \r
673 __declspec(dllexport)\r
674 int umad_unregister(int portid, int agentid)\r
675 {\r
676         ports[portid].pending = FALSE;\r
677         return ports[portid].prov->Deregister((UINT64) agentid);\r
678 }\r
679 \r
680 HANDLE umad_get_fd(int portid)\r
681 {\r
682         return ports[portid].prov->GetFileHandle();\r
683 }\r
684 \r
685 __declspec(dllexport)\r
686 int umad_debug(int level)\r
687 {\r
688         UNREFERENCED_PARAMETER(level);\r
689         return 0;\r
690 }\r
691 \r
692 __declspec(dllexport)\r
693 void umad_addr_dump(ib_mad_addr_t *addr)\r
694 {\r
695         printf("umad_addr:\n");\r
696         printf("\tqpn           0x%x\n", addr->qpn);\r
697         printf("\tqkey          0x%x\n", addr->qkey);\r
698         printf("\tsl            0x%x\n", addr->sl);\r
699         printf("\tlid           0x%x\n", addr->lid);\r
700         printf("\tpkey_index    0x%x\n", addr->pkey_index);\r
701         printf("\tpath_bits     0x%x\n", addr->path_bits);\r
702         printf("\trate          0x%x\n", addr->reserved_rate);\r
703 \r
704         printf("\tgrh_present   0x%x\n", addr->grh_present);\r
705         if (addr->grh_present) {\r
706                 printf("\tgid_index     0x%x\n", addr->gid_index);\r
707                 printf("\tgid           0x%x %x\n",\r
708                         (uint64_t) addr->gid, (uint64_t) (addr->gid + 8));\r
709                 printf("\tflow_lable    0x%x\n", addr->flow_label);\r
710                 printf("\thop_limit     0x%x\n", addr->hop_limit);\r
711                 printf("\ttraffic_class 0x%x\n", addr->qpn);\r
712         }\r
713 }\r
714 \r
715 __declspec(dllexport)\r
716 void umad_dump(void *umad)\r
717 {\r
718         struct ib_user_mad *mad = (struct ib_user_mad *) umad;\r
719         int i;\r
720 \r
721         umad_addr_dump(&mad->addr);\r
722         printf("umad_data\n");\r
723         printf("offset: hex data\n");\r
724         for (i = 0; i < 256; i += 4) {\r
725                 printf("%03d: ", i);\r
726                 printf("%02x %02x %02x %02x\n", mad->data[i], mad->data[i + 1],\r
727                         mad->data[i + 2], mad->data[i + 3]);\r
728         }\r
729 }\r