7127 remove -Wno-missing-braces from Makefile.uts
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/conf.h>
29 #include <sys/ddi.h>
30 #include <sys/sunddi.h>
31 #include <sys/modctl.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34
35 #include <sys/ib/clients/iser/iser.h>
36
37 /*
38 * iser.c
39 * DDI and core routines for Solaris iSER implementation.
40 */
41
42 iser_state_t *iser_state = NULL; /* global state */
43 ddi_taskq_t *iser_taskq = NULL; /* global taskq */
44
45 /* set B_TRUE for console logging */
46 boolean_t iser_logging = B_FALSE;
47
48 /* Driver functions */
49 static int iser_attach(dev_info_t *, ddi_attach_cmd_t);
50 static int iser_detach(dev_info_t *, ddi_detach_cmd_t);
51 static int iser_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
52 static int iser_open(dev_t *, int, int, cred_t *);
53 static int iser_close(dev_t, int, int, cred_t *);
54 static int iser_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
55 /* static int iser_close(dev_t, int, int, cred_t *); */
56
57 /* Char/Block operations */
58 static struct cb_ops iser_cb_ops = {
59 iser_open, /* open */
60 iser_close, /* close */
61 nodev, /* strategy */
62 nodev, /* print */
63 nodev, /* dump */
64 nodev, /* read */
65 nodev, /* write */
66 iser_ioctl, /* ioctl */
67 nodev, /* devmap */
68 nodev, /* mmap */
69 nodev, /* segmap */
70 nochpoll, /* poll */
71 ddi_prop_op, /* prop_op */
72 NULL, /* stream */
73 D_MP, /* cb_flag */
74 CB_REV, /* rev */
75 nodev, /* int (*cb_aread)() */
76 nodev, /* int (*cb_awrite)() */
77 };
78
79 /* Device operations */
80 static struct dev_ops iser_ops = {
81 DEVO_REV, /* devo_rev, */
82 0, /* refcnt */
83 iser_getinfo, /* getinfo */
84 nulldev, /* identify */
85 nulldev, /* probe */
86 iser_attach, /* attach */
87 iser_detach, /* detach */
88 nodev, /* reset */
89 &iser_cb_ops, /* cb_ops */
90 NULL, /* bus ops */
91 NULL, /* power */
92 ddi_quiesce_not_needed /* quiesce */
93 };
94
95 /* Module Driver Info */
96 #define ISER_NAME_VERSION "iSCSI Extensions for RDMA"
97 static struct modldrv iser_modldrv = {
98 &mod_driverops,
99 ISER_NAME_VERSION,
100 &iser_ops,
101 };
102
103 /* Module Linkage */
104 static struct modlinkage iser_modlinkage = {
105 MODREV_1,
106 { &iser_modldrv, NULL }
107 };
108
109 /*
110 * _init()
111 */
112 int
113 _init(void)
114 {
115 int status;
116
117 iser_state = kmem_zalloc(sizeof (iser_state_t), KM_SLEEP);
118 status = mod_install(&iser_modlinkage);
119 if (status != DDI_SUCCESS) {
120 kmem_free(iser_state, sizeof (iser_state_t));
121 }
122
123 return (status);
124 }
125
126 /*
127 * _info()
128 */
129 int
130 _info(struct modinfo *modinfop)
131 {
132 return (mod_info(&iser_modlinkage, modinfop));
133 }
134
135 /*
136 * _fini()
137 */
138 int
139 _fini(void)
140 {
141 int status;
142
143 status = mod_remove(&iser_modlinkage);
144 if (status != DDI_SUCCESS) {
145 return (status);
146 }
147 kmem_free(iser_state, sizeof (iser_state_t));
148
149 return (DDI_SUCCESS);
150 }
151
152 /*
153 * iser_attach()
154 */
155 static int
156 iser_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
157 {
158 int instance;
159 int status;
160
161 switch (cmd) {
162 case DDI_ATTACH:
163 ISER_LOG(CE_CONT, "iser_attach: DDI_ATTACH");
164 instance = ddi_get_instance(dip);
165
166 iser_state->is_dip = dip;
167 iser_state->is_instance = instance;
168
169 /* Initialize the open refcnt and it's lock */
170 iser_state->is_open_refcnt = 0;
171 mutex_init(&iser_state->is_refcnt_lock, NULL, MUTEX_DRIVER,
172 NULL);
173
174 iser_taskq = ddi_taskq_create(dip, "iser_taskq",
175 ISER_TASKQ_NTHREADS, TASKQ_DEFAULTPRI, 0);
176
177 if (iser_taskq == NULL) {
178 ISER_LOG(CE_CONT, "%s%d: failed to create taskq",
179 "iser", instance);
180 mutex_destroy(&iser_state->is_refcnt_lock);
181 return (DDI_FAILURE);
182 }
183
184 /* initialize iSER as IB service */
185 status = iser_ib_init();
186 if (status != DDI_SUCCESS) {
187 ddi_taskq_destroy(iser_taskq);
188 mutex_destroy(&iser_state->is_refcnt_lock);
189 ISER_LOG(CE_CONT, "%s%d: failed to initialize IB",
190 "iser", instance);
191 return (DDI_FAILURE);
192 }
193
194 status = ddi_create_minor_node(
195 dip, ddi_get_name(dip), S_IFCHR, instance,
196 DDI_PSEUDO, 0);
197 if (status != DDI_SUCCESS) {
198 (void) iser_ib_fini();
199 ddi_taskq_destroy(iser_taskq);
200 mutex_destroy(&iser_state->is_refcnt_lock);
201 ISER_LOG(CE_CONT, "%s%d: failed ddi_create_minor_node",
202 "iser", instance);
203 return (DDI_FAILURE);
204 }
205
206 ddi_report_dev(dip);
207
208 return (DDI_SUCCESS);
209
210 case DDI_RESUME:
211 ISER_LOG(CE_CONT, "iser_detach: DDI_RESUME unsupported");
212 return (DDI_FAILURE);
213
214 default:
215 ISER_LOG(CE_CONT, "%s%d: unknown cmd in attach (0x%x)", "iser",
216 instance, cmd);
217 return (DDI_FAILURE);
218 }
219 }
220
221 /*
222 * iser_detach()
223 */
224 static int
225 iser_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
226 {
227 mutex_enter(&iser_state->is_refcnt_lock);
228 if (iser_state->is_open_refcnt > 0) {
229 mutex_exit(&iser_state->is_refcnt_lock);
230 return (DDI_FAILURE);
231 }
232 mutex_exit(&iser_state->is_refcnt_lock);
233 mutex_destroy(&iser_state->is_refcnt_lock);
234
235 switch (cmd) {
236 case DDI_DETACH:
237 ISER_LOG(CE_CONT, "iser_detach: DDI_DETACH");
238
239 if (iser_ib_fini() != DDI_SUCCESS) {
240 ISER_LOG(CE_CONT, "iser_ib_fini failed");
241 return (DDI_FAILURE);
242 }
243
244 if (iser_taskq != NULL) {
245 ddi_taskq_destroy(iser_taskq);
246 iser_taskq = NULL;
247 }
248 ddi_remove_minor_node(dip, NULL);
249
250 return (DDI_SUCCESS);
251
252 case DDI_SUSPEND:
253 ISER_LOG(CE_CONT, "iser_detach: DDI_SUSPEND unsupported");
254 return (DDI_FAILURE);
255
256 default:
257 ISER_LOG(CE_CONT, "iser: unknown cmd in detach (0x%x)", cmd);
258 return (DDI_FAILURE);
259 }
260 }
261
262 /*
263 * iser_getinfo()
264 */
265 /* ARGSUSED */
266 static int
267 iser_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
268 {
269 switch (cmd) {
270 case DDI_INFO_DEVT2DEVINFO:
271 *result = (void *)iser_state->is_dip;
272 return (DDI_SUCCESS);
273
274 case DDI_INFO_DEVT2INSTANCE:
275 *result = NULL;
276 return (DDI_SUCCESS);
277
278 default:
279 return (DDI_FAILURE);
280 }
281
282 }
283
284 /*
285 * iser_open()
286 */
287 /* ARGSUSED */
288 static int
289 iser_open(dev_t *devp, int flag, int otyp, cred_t *credp)
290 {
291 minor_t instance;
292 int status;
293
294 instance = getminor(*devp);
295
296 /* Register the transport with IDM */
297 status = iser_idm_register();
298 if (status != DDI_SUCCESS) {
299 ISER_LOG(CE_CONT, "%s%d: failed to register with IDM",
300 "iser", instance);
301 return (ENXIO);
302 }
303
304 /* Increment our open refcnt */
305 mutex_enter(&iser_state->is_refcnt_lock);
306 iser_state->is_open_refcnt++;
307 mutex_exit(&iser_state->is_refcnt_lock);
308
309 return (DDI_SUCCESS);
310 }
311
312 /*
313 * iser_close()
314 */
315 /* ARGSUSED */
316 static int
317 iser_close(dev_t devp, int flag, int otyp, cred_t *credp)
318 {
319 ASSERT(iser_state->is_open_refcnt != 0);
320
321 mutex_enter(&iser_state->is_refcnt_lock);
322 iser_state->is_open_refcnt--;
323 mutex_exit(&iser_state->is_refcnt_lock);
324
325 return (DDI_SUCCESS);
326 }
327
328 iser_status_t
329 iser_register_service(idm_svc_t *idm_svc)
330 {
331
332 return (iser_ib_register_service(idm_svc));
333 }
334
335 iser_status_t
336 iser_bind_service(idm_svc_t *idm_svc)
337 {
338
339 return (iser_ib_bind_service(idm_svc));
340 }
341
342 void
343 iser_unbind_service(idm_svc_t *idm_svc)
344 {
345
346 iser_ib_unbind_service(idm_svc);
347 }
348
349 void
350 iser_deregister_service(idm_svc_t *idm_svc)
351 {
352
353 iser_ib_deregister_service(idm_svc);
354 }
355
356 /*
357 * iser_path_exists
358 * This function takes in a pair of endpoints and determines if an iSER path
359 * exists between the two. The actual path information (required for creating
360 * a RC channel) is not returned, instead a boolean value indicating if a path
361 * exists is returned.
362 *
363 * To use an implicit source, a value of NULL is allowed for laddr.
364 */
365 boolean_t
366 iser_path_exists(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
367 {
368
369 ibt_ip_addr_t remote_ip, local_ip;
370 ibt_path_info_t path;
371 int status;
372
373 iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
374 iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
375
376 status = iser_ib_get_paths(&local_ip, &remote_ip, &path, NULL);
377
378 return ((status == IBT_SUCCESS) ? B_TRUE : B_FALSE);
379 }
380
381 /*
382 * iser_channel_alloc
383 * This function allocates a reliable communication channel between the
384 * given endpoints.
385 */
386 iser_chan_t *
387 iser_channel_alloc(idm_sockaddr_t *laddr, idm_sockaddr_t *raddr)
388 {
389 ibt_ip_addr_t remote_ip, local_ip;
390
391 iser_ib_conv_sockaddr2ibtaddr(raddr, &remote_ip);
392 iser_ib_conv_sockaddr2ibtaddr(laddr, &local_ip);
393
394 return (iser_ib_alloc_channel_pathlookup(&local_ip, &remote_ip));
395 }
396
397 /*
398 * iser_channel_open
399 * This function opens the already allocated communication channel between the
400 * two endpoints.
401 */
402 iser_status_t
403 iser_channel_open(iser_chan_t *chan)
404 {
405 return (iser_ib_open_rc_channel(chan));
406 }
407
408 /*
409 * iser_channel_close
410 * This function closes the already opened communication channel between the
411 * two endpoints.
412 */
413 void
414 iser_channel_close(iser_chan_t *chan)
415 {
416 iser_ib_close_rc_channel(chan);
417 }
418
419 /*
420 * iser_channel_free
421 * This function frees the channel between the given endpoints
422 */
423 void
424 iser_channel_free(iser_chan_t *chan)
425 {
426 iser_ib_free_rc_channel(chan);
427 }
428
429 /* ARGSUSED */
430 static int
431 iser_ioctl(dev_t devp, int cmd, intptr_t arg, int mode, cred_t *credp,
432 int *rvalp)
433 {
434 return (DDI_SUCCESS);
435 }
--- EOF ---