856c69cdda8ba53261158cc58cd66e2791351ae9
[mirror/winof/.git] / ulp / libibmad / src / register.c
1 /*\r
2  * Copyright (c) 2004,2005 Voltaire Inc.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenFabrics.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  */\r
29 \r
30 #if HAVE_CONFIG_H\r
31 #  include <config.h>\r
32 #endif /* HAVE_CONFIG_H */\r
33 \r
34 #include <stdio.h>\r
35 #include <stdlib.h>\r
36 \r
37 #if defined(_WIN32) || defined(_WIN64)\r
38 #include <windows.h>\r
39 #else\r
40 #include <unistd.h>\r
41 #include <pthread.h>\r
42 #include <sys/time.h>\r
43 #include <string.h>\r
44 #include <errno.h>\r
45 #endif\r
46 \r
47 #include <infiniband/umad.h>\r
48 #include "mad.h"\r
49 \r
50 #undef DEBUG\r
51 #define DEBUG   if (ibdebug)    IBWARN\r
52 \r
53 #define MAX_CLASS       256\r
54 #define MAX_AGENTS      256\r
55 \r
56 static int class_agent[MAX_CLASS];\r
57 static int agent_class[MAX_AGENTS];\r
58 \r
59 static int\r
60 register_agent(int agent, int mclass)\r
61 {\r
62         static int initialized;\r
63 \r
64         if (!initialized) {\r
65                 initialized++;\r
66                 memset(class_agent, 0xff, sizeof class_agent);\r
67                 memset(agent_class, 0xff, sizeof agent_class);\r
68         }\r
69 \r
70         if (mclass < 0 || mclass >= MAX_CLASS ||\r
71             agent < 0 || agent >= MAX_AGENTS) {\r
72                 DEBUG("bad mgmt class %d or agent %d", mclass, agent);\r
73                 return -1;\r
74         }\r
75 \r
76         class_agent[mclass] = agent;\r
77         agent_class[agent] = mclass;\r
78 \r
79         return 0;\r
80 }\r
81 \r
82 static int\r
83 mgmt_class_vers(int mgmt_class)\r
84 {\r
85         if ((mgmt_class >= IB_VENDOR_RANGE1_START_CLASS &&\r
86              mgmt_class <= IB_VENDOR_RANGE1_END_CLASS) ||\r
87             (mgmt_class >= IB_VENDOR_RANGE2_START_CLASS &&\r
88              mgmt_class <= IB_VENDOR_RANGE2_END_CLASS))\r
89                 return 1;\r
90 \r
91         switch(mgmt_class) {\r
92                 case IB_SMI_CLASS:\r
93                 case IB_SMI_DIRECT_CLASS:\r
94                         return 1;\r
95                 case IB_SA_CLASS:\r
96                         return 2;\r
97                 case IB_PERFORMANCE_CLASS:\r
98                         return 1;\r
99                 case IB_DEVICE_MGMT_CLASS:\r
100                         return 1;\r
101                 case IB_CC_CLASS:\r
102                         return 2;\r
103         }\r
104 \r
105         return 0;\r
106 }\r
107 \r
108 MAD_EXPORT int\r
109 mad_class_agent(int mgmt)\r
110 {\r
111         if (mgmt < 1 || mgmt > MAX_CLASS)\r
112                 return -1;\r
113         return class_agent[mgmt];\r
114 }\r
115 \r
116 MAD_EXPORT int\r
117 mad_agent_class(int agent)\r
118 {\r
119         if (agent < 1 || agent > MAX_AGENTS)\r
120                 return -1;\r
121         return agent_class[agent];\r
122 }\r
123 \r
124 MAD_EXPORT int\r
125 mad_register_port_client(int port_id, int mgmt, uint8_t rmpp_version)\r
126 {\r
127         int vers, agent;\r
128 \r
129         if ((vers = mgmt_class_vers(mgmt)) <= 0) {\r
130                 DEBUG("Unknown class %d mgmt_class", mgmt);\r
131                 return -1;\r
132         }\r
133         if ((agent = umad_register(port_id, mgmt,\r
134                                    vers, rmpp_version, 0)) < 0) {\r
135                 DEBUG("Can't register agent for class %d", mgmt);\r
136                 return -1;\r
137         }\r
138 \r
139         if (mgmt < 0 || mgmt >= MAX_CLASS || agent >= MAX_AGENTS) {\r
140                 DEBUG("bad mgmt class %d or agent %d", mgmt, agent);\r
141                 return -1;\r
142         }\r
143 \r
144         return agent;\r
145 }\r
146 \r
147 MAD_EXPORT int\r
148 mad_register_client(int mgmt, uint8_t rmpp_version)\r
149 {\r
150         int agent;\r
151 \r
152         agent = mad_register_port_client(madrpc_portid(), mgmt, rmpp_version);\r
153         if (agent < 0)\r
154                 return agent;\r
155 \r
156         return register_agent(agent, mgmt);\r
157 }\r
158 \r
159 MAD_EXPORT int\r
160 mad_register_server(int mgmt, uint8_t rmpp_version,\r
161                     long method_mask[], uint32_t class_oui)\r
162 {\r
163         long class_method_mask[16/sizeof(long)];\r
164         uint8_t oui[3];\r
165         int agent, vers, mad_portid;\r
166 \r
167         if (method_mask)\r
168                 memcpy(class_method_mask, method_mask, sizeof class_method_mask);\r
169         else\r
170                 memset(class_method_mask, 0xff, sizeof(class_method_mask));\r
171 \r
172         if ((mad_portid = madrpc_portid()) < 0)\r
173                 return -1;\r
174 \r
175         if (class_agent[mgmt] >= 0) {\r
176                 DEBUG("Class 0x%x already registered", mgmt);\r
177                 return -1;\r
178         }\r
179         if ((vers = mgmt_class_vers(mgmt)) <= 0) {\r
180                 DEBUG("Unknown class 0x%x mgmt_class", mgmt);\r
181                 return -1;\r
182         }\r
183         if (mgmt >= IB_VENDOR_RANGE2_START_CLASS &&\r
184             mgmt <= IB_VENDOR_RANGE2_END_CLASS) {\r
185                 oui[0] = (class_oui >> 16) & 0xff;\r
186                 oui[1] = (class_oui >> 8) & 0xff;\r
187                 oui[2] = class_oui & 0xff;\r
188                 if ((agent = umad_register_oui(mad_portid, mgmt, rmpp_version,\r
189                                                oui, class_method_mask)) < 0) {\r
190                         DEBUG("Can't register agent for class %d", mgmt);\r
191                         return -1;\r
192                 }\r
193         } else if ((agent = umad_register(mad_portid, mgmt, vers, rmpp_version,\r
194                                           class_method_mask)) < 0) {\r
195                 DEBUG("Can't register agent for class %d", mgmt);\r
196                 return -1;\r
197         }\r
198 \r
199         if (register_agent(agent, mgmt) < 0)\r
200                 return -1;\r
201 \r
202         return agent;\r
203 }\r