Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/clients/eoib/enx_main.c
+++ new/usr/src/uts/common/io/ib/clients/eoib/enx_main.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * The Ethernet Over Infiniband Nexus driver is a bus nexus driver
28 28 * that enumerates all the EoIB nodes.
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/conf.h>
33 33 #include <sys/devops.h>
34 34 #include <sys/kmem.h>
35 35 #include <sys/ksynch.h>
36 36 #include <sys/modctl.h>
37 37 #include <sys/stat.h>
38 38 #include <sys/ddi.h>
39 39 #include <sys/sunddi.h>
40 40 #include <sys/sunndi.h>
41 41
42 42 #include <sys/ib/clients/eoib/enx_impl.h>
43 43
44 44 /*
45 45 * Global per-instance EoIB Nexus data. Only one instance
46 46 * of EoIB Nexus is supported
47 47 */
48 48 eibnx_t *enx_global_ss = NULL;
49 49
50 50 /*
51 51 * Static function declarations
52 52 */
53 53 static int eibnx_attach(dev_info_t *, ddi_attach_cmd_t);
54 54 static int eibnx_detach(dev_info_t *, ddi_detach_cmd_t);
55 55 static int eibnx_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
56 56 static int eibnx_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
57 57 void *, void *);
58 58
59 59 static int eibnx_get_eventcookie(dev_info_t *, dev_info_t *, char *,
60 60 ddi_eventcookie_t *);
61 61 static int eibnx_add_eventcall(dev_info_t *, dev_info_t *, ddi_eventcookie_t,
62 62 void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *),
63 63 void *, ddi_callback_id_t *);
64 64 static int eibnx_remove_eventcall(dev_info_t *, ddi_callback_id_t);
65 65 static int eibnx_post_event(dev_info_t *, dev_info_t *,
66 66 ddi_eventcookie_t, void *);
67 67
68 68 static int eibnx_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t,
69 69 void *, dev_info_t **);
70 70 static int eibnx_bus_unconfig(dev_info_t *, uint_t, ddi_bus_config_op_t,
71 71 void *);
72 72 static int eibnx_config_all_children(dev_info_t *);
73 73 static void eibnx_unconfig_all_children(dev_info_t *);
74 74 static int eibnx_config_child(char *, dev_info_t **);
75 75 static int eibnx_unconfig_child(char *);
76 76
77 77 /*
78 78 * Cbops
79 79 */
80 80 static struct cb_ops enx_cb_ops = {
81 81 eibnx_devctl_open, /* cb_open */
82 82 eibnx_devctl_close, /* cb_close */
83 83 nodev, /* cb_strategy */
84 84 nodev, /* cb_print */
85 85 nodev, /* cb_dump */
86 86 nodev, /* cb_read */
87 87 nodev, /* cb_write */
88 88 eibnx_devctl_ioctl, /* cb_ioctl */
89 89 nodev, /* cb_devmap */
90 90 nodev, /* cb_mmap */
91 91 nodev, /* cb_segmap */
92 92 nochpoll, /* cb_chpoll */
93 93 ddi_prop_op, /* cb_prop_op */
94 94 NULL, /* cb_str */
95 95 D_MP, /* cb_flag */
96 96 CB_REV, /* cb_rev */
97 97 nodev, /* cb_aread */
98 98 nodev /* cb_awrite */
99 99 };
100 100
101 101 /*
102 102 * Busops
103 103 */
104 104 static struct bus_ops enx_bus_ops = {
105 105 BUSO_REV,
106 106 nullbusmap, /* bus_map */
107 107 NULL, /* bus_get_intrspec */
108 108 NULL, /* bus_add_intrspec */
109 109 NULL, /* bus_remove_intrspec */
110 110 i_ddi_map_fault, /* bus_map_fault */
111 111 ddi_no_dma_map, /* bus_dma_map */
112 112 NULL, /* bus_dma_allochdl */
113 113 NULL, /* bus_dma_freehdl */
114 114 NULL, /* bus_dma_bindhdl */
115 115 NULL, /* bus_dma_unbindhdl */
116 116 NULL, /* bus_dma_flush */
117 117 NULL, /* bus_dma_win */
118 118 NULL, /* bus_dma_ctl */
119 119 eibnx_bus_ctl, /* bus_ctl */
120 120 ddi_bus_prop_op, /* bus_prop_op */
121 121 eibnx_get_eventcookie, /* bus_get_eventcookie */
122 122 eibnx_add_eventcall, /* bus_add_eventcall */
123 123 eibnx_remove_eventcall, /* bus_remove_eventcall */
124 124 eibnx_post_event, /* bus_post_event */
125 125 NULL, /* bus_intr_ctl */
126 126 eibnx_bus_config, /* bus_config */
127 127 eibnx_bus_unconfig, /* bus_unconfig */
128 128 };
129 129
130 130 /*
131 131 * Nexus ops
132 132 */
133 133 static struct dev_ops enx_ops = {
134 134 DEVO_REV, /* devo_rev, */
135 135 0, /* devo_refcnt */
136 136 eibnx_getinfo, /* devo_info */
137 137 nulldev, /* devo_identify */
138 138 nulldev, /* devo_probe */
139 139 eibnx_attach, /* devo_attach */
140 140 eibnx_detach, /* devo_detach */
141 141 nodev, /* devo_reset */
142 142 &enx_cb_ops, /* devo_cb_ops */
143 143 &enx_bus_ops, /* devo_bus_ops */
144 144 nulldev, /* devo_power */
145 145 ddi_quiesce_not_needed /* devo_quiesce */
146 146 };
147 147
↓ open down ↓ |
147 lines elided |
↑ open up ↑ |
148 148 /*
149 149 * Module linkage information for the kernel
150 150 */
151 151 static struct modldrv enx_modldrv = {
152 152 &mod_driverops, /* Driver module */
153 153 "EoIB Nexus", /* Driver name and version */
154 154 &enx_ops, /* Driver ops */
155 155 };
156 156
157 157 static struct modlinkage enx_modlinkage = {
158 - MODREV_1, (void *)&enx_modldrv, NULL
158 + MODREV_1, { (void *)&enx_modldrv, NULL }
159 159 };
160 160
161 161 /*
162 162 * EoIB NDI events
163 163 */
164 164 static ndi_event_definition_t enx_ndi_event_defs[] = {
165 165 { ENX_EVENT_TAG_GW_INFO_UPDATE, EIB_NDI_EVENT_GW_INFO_UPDATE,
166 166 EPL_KERNEL, NDI_EVENT_POST_TO_TGT },
167 167 { ENX_EVENT_TAG_GW_AVAILABLE, EIB_NDI_EVENT_GW_AVAILABLE,
168 168 EPL_KERNEL, NDI_EVENT_POST_TO_TGT },
169 169 { ENX_EVENT_TAG_LOGIN_ACK, EIB_NDI_EVENT_LOGIN_ACK,
170 170 EPL_KERNEL, NDI_EVENT_POST_TO_TGT }
171 171 };
172 172 #define ENX_NUM_NDI_EVENTS \
173 173 (sizeof (enx_ndi_event_defs) / sizeof (enx_ndi_event_defs[0]))
174 174
175 175 static ndi_event_set_t enx_ndi_events = {
176 176 NDI_EVENTS_REV1,
177 177 ENX_NUM_NDI_EVENTS,
178 178 enx_ndi_event_defs
179 179 };
180 180 ndi_event_hdl_t enx_ndi_event_hdl;
181 181
182 182
183 183 /*
184 184 * Common loadable module entry points _init, _fini, _info
185 185 */
186 186
187 187 int
188 188 _init(void)
189 189 {
190 190 int ret;
191 191
192 192 if ((ret = mod_install(&enx_modlinkage)) == 0)
193 193 eibnx_debug_init();
194 194
195 195 return (ret);
196 196 }
197 197
198 198 int
199 199 _fini(void)
200 200 {
201 201 int ret;
202 202
203 203 if ((ret = mod_remove(&enx_modlinkage)) == 0)
204 204 eibnx_debug_fini();
205 205
206 206 return (ret);
207 207 }
208 208
209 209 int
210 210 _info(struct modinfo *modinfop)
211 211 {
212 212 return (mod_info(&enx_modlinkage, modinfop));
213 213 }
214 214
215 215 /*
216 216 * Autoconfiguration entry points: attach, detach, getinfo
217 217 */
218 218
219 219 static int
220 220 eibnx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
221 221 {
222 222 eibnx_t *ss;
223 223 int instance;
224 224
225 225 if (cmd == DDI_RESUME)
226 226 return (DDI_SUCCESS);
227 227 else if (cmd != DDI_ATTACH)
228 228 return (DDI_FAILURE);
229 229
230 230 /*
231 231 * Don't allow more than one instance to attach
232 232 */
233 233 if (enx_global_ss)
234 234 return (DDI_FAILURE);
235 235
236 236 /*
237 237 * Alloc this instance's softstate
238 238 */
239 239 ss = kmem_zalloc(sizeof (eibnx_t), KM_SLEEP);
240 240 ss->nx_dip = dip;
241 241
242 242 enx_global_ss = ss;
243 243
244 244 /*
245 245 * Allocate our NDI event handle and bind our event set
246 246 */
247 247 if (ndi_event_alloc_hdl(dip, 0, &enx_ndi_event_hdl,
248 248 NDI_SLEEP) != NDI_SUCCESS) {
249 249 ENX_DPRINTF_ERR("ndi_event_alloc_hdl(dip=0x%llx) "
250 250 "failed", dip);
251 251
252 252 kmem_free(enx_global_ss, sizeof (eibnx_t));
253 253 enx_global_ss = NULL;
254 254 return (DDI_FAILURE);
255 255 }
256 256 if (ndi_event_bind_set(enx_ndi_event_hdl, &enx_ndi_events,
257 257 NDI_SLEEP) != NDI_SUCCESS) {
258 258 ENX_DPRINTF_ERR("ndi_event_bind_set(ndi_event_hdl=0x%llx) "
259 259 "failed", enx_ndi_event_hdl);
260 260
261 261 (void) ndi_event_free_hdl(enx_ndi_event_hdl);
262 262 enx_ndi_event_hdl = NULL;
263 263 kmem_free(enx_global_ss, sizeof (eibnx_t));
264 264 enx_global_ss = NULL;
265 265 return (DDI_FAILURE);
266 266 }
267 267
268 268 /*
269 269 * Create "devctl" minor node for general ioctl interface to the
270 270 * eoib nexus. If we cannot, it isn't fatal - we'll operate without
271 271 * the support for devctl (but issue a warning).
272 272 */
273 273 instance = ddi_get_instance(dip);
274 274 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
275 275 DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
276 276 ENX_DPRINTF_WARN("could not create devctl minor node "
277 277 "for instance %d", instance);
278 278 }
279 279
280 280 /*
281 281 * Do IBTF related initializations. If we fail, we cannot operate,
282 282 * so fail the attach.
283 283 */
284 284 if (eibnx_ibt_init(ss) != ENX_E_SUCCESS) {
285 285 (void) ddi_remove_minor_node(dip, NULL);
286 286 (void) ndi_event_unbind_set(enx_ndi_event_hdl,
287 287 &enx_ndi_events, NDI_SLEEP);
288 288 (void) ndi_event_free_hdl(enx_ndi_event_hdl);
289 289 enx_ndi_event_hdl = NULL;
290 290 kmem_free(enx_global_ss, sizeof (eibnx_t));
291 291 enx_global_ss = NULL;
292 292 return (DDI_FAILURE);
293 293 }
294 294
295 295 return (DDI_SUCCESS);
296 296 }
297 297
298 298 static int
299 299 eibnx_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
300 300 {
301 301 eibnx_t *ss = enx_global_ss;
302 302
303 303 if (cmd == DDI_SUSPEND)
304 304 return (DDI_SUCCESS);
305 305 else if (cmd != DDI_DETACH)
306 306 return (DDI_FAILURE);
307 307
308 308 /*
309 309 * If there's no instance of eibnx attached, fail
310 310 */
311 311 if (ss == NULL)
312 312 return (DDI_FAILURE);
313 313
314 314 /*
315 315 * Before we do anything, we need to stop the port monitors
316 316 * we may have started earlier.
317 317 */
318 318 eibnx_terminate_monitors();
319 319
320 320 /*
321 321 * If eibnx_ibt_fini() fails, it could be because one of the
322 322 * HCA's pd could not be freed, the hca could not be closed
323 323 * or the IBTF detach wasn't successful. If this is the case,
324 324 * we have to return failure, but cannot do much about the
325 325 * port monitors we've already terminated.
326 326 */
327 327 if (eibnx_ibt_fini(ss) == ENX_E_FAILURE)
328 328 return (DDI_FAILURE);
329 329
330 330 /*
331 331 * Cleanup any devctl minor node we may have created, unbind and
332 332 * free ndi event handle and free the instance softstate.
333 333 */
334 334 (void) ddi_remove_minor_node(dip, NULL);
335 335 (void) ndi_event_unbind_set(enx_ndi_event_hdl,
336 336 &enx_ndi_events, NDI_SLEEP);
337 337 (void) ndi_event_free_hdl(enx_ndi_event_hdl);
338 338 enx_ndi_event_hdl = NULL;
339 339 kmem_free(enx_global_ss, sizeof (eibnx_t));
340 340 enx_global_ss = NULL;
341 341
342 342 return (DDI_SUCCESS);
343 343 }
344 344
345 345 /*ARGSUSED*/
346 346 static int
347 347 eibnx_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
348 348 {
349 349 eibnx_t *ss = enx_global_ss;
350 350 int ret;
351 351
352 352 if (cmd == DDI_INFO_DEVT2DEVINFO) {
353 353 *resultp = (ss) ? ss->nx_dip : NULL;
354 354 ret = (ss) ? DDI_SUCCESS : DDI_FAILURE;
355 355 } else if (cmd == DDI_INFO_DEVT2INSTANCE) {
356 356 *resultp = 0;
357 357 ret = DDI_SUCCESS;
358 358 } else {
359 359 ret = DDI_FAILURE;
360 360 }
361 361
362 362 return (ret);
363 363 }
364 364
365 365 /*
366 366 * Busops: bus_ctl, bus_config, bus_unconfig
367 367 */
368 368
369 369 /*ARGSUSED*/
370 370 static int
371 371 eibnx_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
372 372 void *arg, void *result)
373 373 {
374 374 dev_info_t *child = arg;
375 375 int ret;
376 376 char name[MAXNAMELEN];
377 377
378 378 switch (ctlop) {
379 379 case DDI_CTLOPS_REPORTDEV:
380 380 ENX_DPRINTF_DEBUG("EoIB device: %s@%s, %s%d",
381 381 ddi_node_name(rdip), ddi_get_name_addr(rdip),
382 382 ddi_driver_name(rdip), ddi_get_instance(rdip));
383 383 /*FALLTHROUGH*/
384 384
385 385 case DDI_CTLOPS_ATTACH:
386 386 case DDI_CTLOPS_DETACH:
387 387 case DDI_CTLOPS_POWER:
388 388 case DDI_CTLOPS_SIDDEV:
389 389 case DDI_CTLOPS_IOMIN:
390 390 ret = DDI_SUCCESS;
391 391 break;
392 392
393 393 case DDI_CTLOPS_INITCHILD:
394 394 if ((ret = eibnx_name_child(child, name,
395 395 sizeof (name))) == DDI_SUCCESS) {
396 396 ddi_set_name_addr(child, name);
397 397 }
398 398 break;
399 399
400 400 case DDI_CTLOPS_UNINITCHILD:
401 401 ddi_set_name_addr(child, NULL);
402 402 ret = DDI_SUCCESS;
403 403 break;
404 404
405 405 default:
406 406 ret = ddi_ctlops(dip, rdip, ctlop, arg, result);
407 407 break;
408 408 }
409 409
410 410 return (ret);
411 411 }
412 412
413 413 /*ARGSUSED*/
414 414 static int
415 415 eibnx_bus_config(dev_info_t *parent, uint_t flags,
416 416 ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
417 417 {
418 418 eibnx_t *ss = enx_global_ss;
419 419 int ret = NDI_SUCCESS;
420 420
421 421 switch (op) {
422 422 case BUS_CONFIG_ONE:
423 423 eibnx_busop_inprog_enter(ss);
424 424 ret = eibnx_config_child(arg, childp);
425 425 eibnx_busop_inprog_exit(ss);
426 426 break;
427 427
428 428 case BUS_CONFIG_ALL:
429 429 case BUS_CONFIG_DRIVER:
430 430 eibnx_busop_inprog_enter(ss);
431 431 if ((ss->nx_busop_flags & NX_FL_BUSCFG_COMPLETE) == 0) {
432 432 ret = eibnx_config_all_children(parent);
433 433 if (ret == NDI_SUCCESS)
434 434 ss->nx_busop_flags |= NX_FL_BUSCFG_COMPLETE;
435 435 }
436 436 eibnx_busop_inprog_exit(ss);
437 437 break;
438 438
439 439 default:
440 440 ret = NDI_FAILURE;
441 441 }
442 442
443 443 if (ret == NDI_SUCCESS)
444 444 ret = ndi_busop_bus_config(parent, flags, op, arg, childp, 0);
445 445
446 446 return (ret);
447 447 }
448 448
449 449 static int
450 450 eibnx_bus_unconfig(dev_info_t *parent, uint_t flags,
451 451 ddi_bus_config_op_t op, void *arg)
452 452 {
453 453 eibnx_t *ss = enx_global_ss;
454 454 int ret;
455 455
456 456 ret = ndi_busop_bus_unconfig(parent, flags, op, arg);
457 457 if (ret != NDI_SUCCESS)
458 458 return (ret);
459 459
460 460 switch (op) {
461 461 case BUS_UNCONFIG_ONE:
462 462 if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) {
463 463 eibnx_busop_inprog_enter(ss);
464 464
465 465 if ((ret = eibnx_unconfig_child(arg)) == ENX_E_SUCCESS)
466 466 ss->nx_busop_flags &= (~NX_FL_BUSCFG_COMPLETE);
467 467 else {
468 468 ENX_DPRINTF_DEBUG("eibnx_bus_config: "
469 469 "unconfig child %s failed", (char *)arg);
470 470 }
471 471
472 472 eibnx_busop_inprog_exit(ss);
473 473 }
474 474 break;
475 475
476 476 case BUS_UNCONFIG_ALL:
477 477 case BUS_UNCONFIG_DRIVER:
478 478 if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) {
479 479 eibnx_busop_inprog_enter(ss);
480 480
481 481 eibnx_unconfig_all_children(parent);
482 482 ss->nx_busop_flags &= (~NX_FL_BUSCFG_COMPLETE);
483 483
484 484 eibnx_busop_inprog_exit(ss);
485 485 }
486 486 break;
487 487
488 488 default:
489 489 break;
490 490 }
491 491
492 492 return (ret);
493 493 }
494 494
495 495 /*
496 496 * Event Handling: bus_get_eventcookie, bus_add_eventcall, bus_remove_eventcall
497 497 * and bus_post_event
498 498 */
499 499
500 500 /*ARGSUSED*/
501 501 static int
502 502 eibnx_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
503 503 char *name, ddi_eventcookie_t *cookiep)
504 504 {
505 505 return (ndi_event_retrieve_cookie(enx_ndi_event_hdl, rdip, name,
506 506 cookiep, NDI_EVENT_NOPASS));
507 507 }
508 508
509 509 /*ARGSUSED*/
510 510 static int
511 511 eibnx_add_eventcall(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t cookie,
512 512 void (*callback)(dev_info_t *cb_dip, ddi_eventcookie_t cb_cookie,
513 513 void *cb_arg, void *cb_impl_data),
514 514 void *arg, ddi_callback_id_t *cb_id)
515 515 {
516 516 return (ndi_event_add_callback(enx_ndi_event_hdl, rdip, cookie,
517 517 callback, arg, NDI_SLEEP, cb_id));
518 518 }
519 519
520 520 /*ARGSUSED*/
521 521 static int
522 522 eibnx_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id)
523 523 {
524 524 return (ndi_event_remove_callback(enx_ndi_event_hdl, cb_id));
525 525 }
526 526
527 527 /*ARGSUSED*/
528 528 static int
529 529 eibnx_post_event(dev_info_t *dip, dev_info_t *rdip,
530 530 ddi_eventcookie_t cookie, void *impl_data)
531 531 {
532 532 return (ndi_event_run_callbacks(enx_ndi_event_hdl, rdip, cookie,
533 533 impl_data));
534 534 }
535 535
536 536 /*
537 537 * Routines to configure/unconfigure EoIB node(s) on a system.
538 538 */
539 539
540 540 /*ARGSUSED*/
541 541 static int
542 542 eibnx_config_all_children(dev_info_t *parent)
543 543 {
544 544 eibnx_t *ss = enx_global_ss;
545 545 eibnx_hca_t *hca;
546 546 eibnx_port_t *port;
547 547 eibnx_thr_info_t *ti;
548 548 eibnx_thr_info_t *ti_tail;
549 549 eibnx_gw_info_t *gwi;
550 550
551 551 /*
552 552 * Go through each port of each hca and create a thread to solicit,
553 553 * monitor, receive advertisements, create eoib nodes and attach eoib
554 554 * driver instances.
555 555 */
556 556 mutex_enter(&ss->nx_lock);
557 557 if (!ss->nx_monitors_up) {
558 558 ss->nx_thr_info = ti_tail = NULL;
559 559 for (hca = ss->nx_hca; hca; hca = hca->hc_next) {
560 560 for (port = hca->hc_port; port; port = port->po_next) {
561 561 ti = eibnx_start_port_monitor(hca, port);
562 562 if (ti_tail) {
563 563 ti_tail->ti_next = ti;
564 564 } else {
565 565 ss->nx_thr_info = ti;
566 566 }
567 567 ti_tail = ti;
568 568 }
569 569 }
570 570
571 571 ss->nx_monitors_up = B_TRUE;
572 572 mutex_exit(&ss->nx_lock);
573 573
574 574 return (NDI_SUCCESS);
575 575 }
576 576 mutex_exit(&ss->nx_lock);
577 577
578 578 while (eibnx_locate_unconfigured_node(&ti, &gwi) == ENX_E_SUCCESS)
579 579 (void) eibnx_configure_node(ti, gwi, NULL);
580 580
581 581 return (NDI_SUCCESS);
582 582 }
583 583
584 584 /*
585 585 * Routine to unconfigure all the EoIB nodes on a system. This terminates
586 586 * all the per-port monitor threads and releases any resources allocated.
587 587 */
588 588
589 589 /*ARGSUSED*/
590 590 static void
591 591 eibnx_unconfig_all_children(dev_info_t *parent)
592 592 {
593 593 eibnx_t *ss = enx_global_ss;
594 594 eibnx_thr_info_t *ti;
595 595 eibnx_child_t *ch;
596 596
597 597 mutex_enter(&ss->nx_lock);
598 598 for (ti = ss->nx_thr_info; ti; ti = ti->ti_next) {
599 599 mutex_enter(&ti->ti_child_lock);
600 600 for (ch = ti->ti_child; ch; ch = ch->ch_next) {
601 601 ch->ch_dip = NULL;
602 602 }
603 603 mutex_exit(&ti->ti_child_lock);
604 604 }
605 605 mutex_exit(&ss->nx_lock);
606 606 }
607 607
608 608 /*ARGSUSED*/
609 609 static int
610 610 eibnx_config_child(char *devname, dev_info_t **childp)
611 611 {
612 612 eibnx_thr_info_t *ti;
613 613 eibnx_gw_info_t *gwi;
614 614
615 615 if (eibnx_locate_node_name(devname, &ti, &gwi) == ENX_E_FAILURE) {
616 616 ENX_DPRINTF_DEBUG("eibnx_config_child: invalid eoib "
617 617 "nodename %s, no such address", devname);
618 618 return (ENX_E_FAILURE);
619 619 }
620 620
621 621 return (eibnx_configure_node(ti, gwi, childp));
622 622 }
623 623
624 624 /*ARGSUSED*/
625 625 static int
626 626 eibnx_unconfig_child(char *devname)
627 627 {
628 628 eibnx_thr_info_t *ti;
629 629 eibnx_gw_info_t *gwi;
630 630
631 631 if (eibnx_locate_node_name(devname, &ti, &gwi) == ENX_E_FAILURE) {
632 632 ENX_DPRINTF_DEBUG("eibnx_unconfig_child: invalid eoib "
633 633 "nodename %s, no such address", devname);
634 634 return (ENX_E_FAILURE);
635 635 }
636 636
637 637 return (eibnx_unconfigure_node(ti, gwi));
638 638 }
↓ open down ↓ |
470 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX