Print this page
fixup .text where possible
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/avs/ncall/ncall.c
+++ new/usr/src/uts/common/avs/ncall/ncall.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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * Media independent RPC-like comms
28 28 */
29 29
30 30 #include <sys/types.h>
31 31 #include <sys/conf.h>
32 32 #include <sys/stat.h>
33 33 #include <sys/errno.h>
34 34 #include <sys/cmn_err.h>
35 35 #include <sys/ksynch.h>
36 36 #include <sys/kmem.h>
37 37 #include <sys/modctl.h>
38 38 #include <sys/ddi.h>
39 39 #include <sys/sunddi.h>
40 40
41 41 #include <sys/varargs.h>
42 42 #ifdef DS_DDICT
43 43 #include <sys/nsctl/contract.h>
44 44 #endif
45 45 #include "ncall.h"
46 46 #include "ncall_module.h"
47 47
48 48 #include <sys/nsctl/nsvers.h>
49 49
50 50 /*
51 51 * cb_ops functions.
52 52 */
53 53
54 54 static int ncallioctl(dev_t, int, intptr_t, int, cred_t *, int *);
55 55 static int ncallprint(dev_t, char *);
56 56
57 57
58 58 static struct cb_ops ncall_cb_ops = {
59 59 nulldev, /* open */
60 60 nulldev, /* close */
61 61 nulldev, /* strategy */
62 62 ncallprint,
63 63 nodev, /* dump */
64 64 nodev, /* read */
65 65 nodev, /* write */
66 66 ncallioctl,
67 67 nodev, /* devmap */
68 68 nodev, /* mmap */
69 69 nodev, /* segmap */
70 70 nochpoll, /* poll */
71 71 ddi_prop_op,
72 72 NULL, /* NOT a stream */
73 73 D_NEW | D_MP | D_64BIT,
74 74 CB_REV,
75 75 nodev, /* aread */
76 76 nodev, /* awrite */
77 77 };
78 78
79 79
80 80 /*
81 81 * dev_ops functions.
82 82 */
83 83
84 84 static int ncall_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
85 85 static int ncall_attach(dev_info_t *, ddi_attach_cmd_t);
86 86 static int ncall_detach(dev_info_t *, ddi_detach_cmd_t);
87 87
88 88 static struct dev_ops ncall_ops = {
89 89 DEVO_REV,
90 90 0,
91 91 ncall_getinfo,
92 92 nulldev, /* identify */
93 93 nulldev, /* probe */
94 94 ncall_attach,
95 95 ncall_detach,
96 96 nodev, /* reset */
97 97 &ncall_cb_ops,
98 98 (struct bus_ops *)0,
99 99 NULL /* power */
100 100 };
101 101
102 102 /*
103 103 * Module linkage.
104 104 */
105 105
↓ open down ↓ |
105 lines elided |
↑ open up ↑ |
106 106 extern struct mod_ops mod_driverops;
107 107
108 108 static struct modldrv modldrv = {
109 109 &mod_driverops,
110 110 "nws:Kernel Call:" ISS_VERSION_STR,
111 111 &ncall_ops
112 112 };
113 113
114 114 static struct modlinkage modlinkage = {
115 115 MODREV_1,
116 - &modldrv,
117 - 0
116 + { &modldrv, NULL }
118 117 };
119 118
120 119 typedef struct ncall_modinfo_s {
121 120 struct ncall_modinfo_s *next;
122 121 ncall_module_t *module;
123 122 } ncall_modinfo_t;
124 123
125 124 static dev_info_t *ncall_dip; /* Single DIP for driver */
126 125 static kmutex_t ncall_mutex;
127 126
128 127 static ncall_modinfo_t *ncall_modules;
129 128 static int ncall_active;
130 129
131 130 static ncall_node_t ncall_nodeinfo;
132 131
133 132 static int ncallgetnodes(intptr_t, int, int *);
134 133 extern void ncall_init_stub(void);
135 134
136 135 int
137 136 _init(void)
138 137 {
139 138 int error;
140 139
141 140 mutex_init(&ncall_mutex, NULL, MUTEX_DRIVER, NULL);
142 141
143 142 if ((error = mod_install(&modlinkage)) != 0) {
144 143 mutex_destroy(&ncall_mutex);
145 144 return (error);
146 145 }
147 146
148 147 return (0);
149 148 }
150 149
151 150
152 151 int
153 152 _fini(void)
154 153 {
155 154 int error;
156 155
157 156 if ((error = mod_remove(&modlinkage)) != 0)
158 157 return (error);
159 158
160 159 mutex_destroy(&ncall_mutex);
161 160 return (error);
162 161 }
163 162
164 163
165 164 int
166 165 _info(struct modinfo *modinfop)
167 166 {
168 167 return (mod_info(&modlinkage, modinfop));
169 168 }
170 169
171 170 static int
172 171 ncall_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
173 172 {
174 173 switch (cmd) {
175 174
176 175 case DDI_ATTACH:
177 176 ncall_dip = dip;
178 177
179 178 if (ddi_create_minor_node(dip, "c,ncall", S_IFCHR,
180 179 0, DDI_PSEUDO, 0) != DDI_SUCCESS)
181 180 goto failed;
182 181
183 182 ddi_report_dev(dip);
184 183
185 184 return (DDI_SUCCESS);
186 185
187 186 default:
188 187 return (DDI_FAILURE);
189 188 }
190 189
191 190 failed:
192 191 (void) ncall_detach(dip, DDI_DETACH);
193 192 return (DDI_FAILURE);
194 193 }
195 194
196 195
197 196 static int
198 197 ncall_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
199 198 {
200 199 switch (cmd) {
201 200
202 201 case DDI_DETACH:
203 202
204 203 /*
205 204 * If still active, then refuse to detach.
206 205 */
207 206
208 207 if (ncall_modules != NULL || ncall_active)
209 208 return (DDI_FAILURE);
210 209
211 210 /*
212 211 * Remove all minor nodes.
213 212 */
214 213
215 214 ddi_remove_minor_node(dip, NULL);
216 215 ncall_dip = NULL;
217 216
218 217 return (DDI_SUCCESS);
219 218
220 219 default:
221 220 return (DDI_FAILURE);
222 221 }
223 222 }
224 223
225 224
226 225 /* ARGSUSED */
227 226
228 227 static int
229 228 ncall_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
230 229 {
231 230 int rc = DDI_FAILURE;
232 231
233 232 switch (infocmd) {
234 233
235 234 case DDI_INFO_DEVT2DEVINFO:
236 235 *result = ncall_dip;
237 236 rc = DDI_SUCCESS;
238 237 break;
239 238
240 239 case DDI_INFO_DEVT2INSTANCE:
241 240 /*
242 241 * We only have a single instance.
243 242 */
244 243 *result = 0;
245 244 rc = DDI_SUCCESS;
246 245 break;
247 246
248 247 default:
249 248 break;
250 249 }
251 250
252 251 return (rc);
253 252 }
254 253
255 254
256 255 /* ARGSUSED */
257 256 static int
258 257 ncallprint(dev_t dev, char *str)
259 258 {
260 259 cmn_err(CE_WARN, "%s%d: %s", ddi_get_name(ncall_dip),
261 260 ddi_get_instance(ncall_dip), str);
262 261
263 262 return (0);
264 263 }
265 264
266 265
267 266 int
268 267 ncall_register_module(ncall_module_t *mp, ncall_node_t *nodep)
269 268 {
270 269 ncall_modinfo_t *new;
271 270 int rc = 0;
272 271
273 272 if (mp == NULL || mp->ncall_version != NCALL_MODULE_VER)
274 273 return (EINVAL);
275 274
276 275 new = kmem_alloc(sizeof (*new), KM_SLEEP);
277 276
278 277 if (new != NULL) {
279 278 new->module = mp;
280 279
281 280 mutex_enter(&ncall_mutex);
282 281
283 282 new->next = ncall_modules;
284 283 ncall_modules = new;
285 284
286 285 mutex_exit(&ncall_mutex);
287 286 } else {
288 287 rc = ENOMEM;
289 288 }
290 289
291 290 *nodep = ncall_nodeinfo; /* structure copy */
292 291 return (rc);
293 292 }
294 293
295 294
296 295 int
297 296 ncall_unregister_module(ncall_module_t *mod)
298 297 {
299 298 ncall_modinfo_t **mpp;
300 299 int rc = ESRCH;
301 300
302 301 mutex_enter(&ncall_mutex);
303 302
304 303 for (mpp = &ncall_modules; *mpp != NULL; mpp = &((*mpp)->next)) {
305 304 if ((*mpp)->module == mod) {
306 305 *mpp = (*mpp)->next;
307 306 rc = 0;
308 307 break;
309 308 }
310 309 }
311 310
312 311 mutex_exit(&ncall_mutex);
313 312
314 313 return (rc);
315 314 }
316 315
317 316
318 317 static int
319 318 ncall_stop(void)
320 319 {
321 320 ncall_modinfo_t *mod;
322 321 int rc = 0;
323 322
324 323 mutex_enter(&ncall_mutex);
325 324
326 325 while ((rc == 0) && ((mod = ncall_modules) != NULL)) {
327 326 mutex_exit(&ncall_mutex);
328 327
329 328 rc = (*mod->module->ncall_stop)();
330 329
331 330 mutex_enter(&ncall_mutex);
332 331 }
333 332
↓ open down ↓ |
206 lines elided |
↑ open up ↑ |
334 333 mutex_exit(&ncall_mutex);
335 334
336 335 return (rc);
337 336 }
338 337
339 338
340 339 /* ARGSUSED */
341 340 static int ncallioctl(dev_t dev, int cmd, intptr_t arg, int mode,
342 341 cred_t *crp, int *rvalp)
343 342 {
344 - ncall_node_t node = { 0, };
343 + ncall_node_t node = { .nc_nodeid = 0 };
345 344 int mirror;
346 345 int rc = 0;
347 346
348 347 *rvalp = 0;
349 348
350 349 if ((rc = drv_priv(crp)) != 0)
351 350 return (rc);
352 351
353 352 switch (cmd) {
354 353
355 354 case NC_IOC_START:
356 355 if (ncall_active) {
357 356 rc = EALREADY;
358 357 break;
359 358 }
360 359
361 360 if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0)
362 361 return (EFAULT);
363 362
364 363 bcopy(&node, &ncall_nodeinfo, sizeof (ncall_nodeinfo));
365 364 ncall_init_stub();
366 365 ncall_active = 1;
367 366 break;
368 367
369 368 case NC_IOC_STOP:
370 369 ncall_active = 0;
371 370 rc = ncall_stop();
372 371 break;
373 372
374 373 case NC_IOC_GETNODE:
375 374 if (!ncall_active) {
376 375 rc = ENONET;
377 376 break;
378 377 }
379 378 if (ddi_copyout(&ncall_nodeinfo, (void *)arg,
380 379 sizeof (ncall_nodeinfo), mode) < 0) {
381 380 rc = EFAULT;
382 381 break;
383 382 }
384 383 mirror = ncall_mirror(ncall_nodeinfo.nc_nodeid);
385 384 /*
386 385 * can't return -1, as this will mask the ioctl
387 386 * failure, so return 0.
388 387 */
389 388 if (mirror == -1)
390 389 mirror = 0;
391 390 *rvalp = mirror;
392 391 break;
393 392
394 393 case NC_IOC_GETNETNODES:
395 394 rc = ncallgetnodes(arg, mode, rvalp);
396 395 break;
397 396
398 397 case NC_IOC_PING:
399 398 if (!ncall_active) {
400 399 rc = ENONET;
401 400 break;
402 401 }
403 402
404 403 if (ddi_copyin((void *)arg, &node, sizeof (node), mode) < 0) {
405 404 rc = EFAULT;
406 405 break;
407 406 }
408 407
409 408 node.nc_nodename[sizeof (node.nc_nodename)-1] = '\0';
410 409 rc = ncall_ping(node.nc_nodename, rvalp);
411 410 break;
412 411
413 412 default:
414 413 rc = EINVAL;
415 414 break;
416 415 }
417 416
418 417 return (rc);
419 418 }
420 419
421 420
422 421 void
423 422 ncall_register_svc(int svc_id, void (*func)(ncall_t *, int *))
424 423 {
425 424 if (ncall_modules)
426 425 (*ncall_modules->module->ncall_register_svc)(svc_id, func);
427 426 }
428 427
429 428
430 429 void
431 430 ncall_unregister_svc(int svc_id)
432 431 {
433 432 if (ncall_modules)
434 433 (*ncall_modules->module->ncall_unregister_svc)(svc_id);
435 434 }
436 435
437 436
438 437 int
439 438 ncall_nodeid(char *nodename)
440 439 {
441 440 if (ncall_modules)
442 441 return ((ncall_modules->module->ncall_nodeid)(nodename));
443 442 else
444 443 return (0);
445 444 }
446 445
447 446
448 447 char *
449 448 ncall_nodename(int nodeid)
450 449 {
451 450 if (ncall_modules)
452 451 return ((*ncall_modules->module->ncall_nodename)(nodeid));
453 452 else
454 453 return ("unknown");
455 454 }
456 455
457 456
458 457 int
459 458 ncall_mirror(int nodeid)
460 459 {
461 460 if (ncall_modules)
462 461 return ((*ncall_modules->module->ncall_mirror)(nodeid));
463 462 else
464 463 return (-1);
465 464 }
466 465
467 466
468 467 int
469 468 ncall_self(void)
470 469 {
471 470 if (ncall_modules)
472 471 return ((*ncall_modules->module->ncall_self)());
473 472 else
474 473 return (-1);
475 474 }
476 475
477 476
478 477 int
479 478 ncall_alloc(int host_id, int flags, int net, ncall_t **ncall_p)
480 479 {
481 480 int rc = ENOLINK;
482 481
483 482 if (ncall_modules)
484 483 rc = (*ncall_modules->module->ncall_alloc)(host_id,
485 484 flags, net, ncall_p);
486 485
487 486 return (rc);
488 487 }
489 488
490 489
491 490 int
492 491 ncall_timedsend(ncall_t *ncall, int flags, int svc_id,
493 492 struct timeval *t, ...)
494 493 {
495 494 va_list ap;
496 495 int rc = ENOLINK;
497 496
498 497 va_start(ap, t);
499 498
500 499 if (ncall_modules)
501 500 rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags,
502 501 svc_id, t, ap);
503 502
504 503 va_end(ap);
505 504
506 505 return (rc);
507 506 }
508 507
509 508 int
510 509 ncall_timedsendnotify(ncall_t *ncall, int flags, int svc_id,
511 510 struct timeval *t, void (*ncall_callback)(ncall_t *, void *),
512 511 void *vptr, ...)
513 512 {
514 513 va_list ap;
515 514 int rc = ENOLINK;
516 515
517 516 va_start(ap, vptr);
518 517
519 518 if (ncall_modules)
520 519 rc = (*ncall_modules->module->ncall_timedsendnotify)(ncall,
521 520 flags, svc_id, t, ncall_callback, vptr, ap);
522 521 va_end(ap);
523 522
524 523 return (rc);
525 524 }
526 525
527 526 int
528 527 ncall_broadcast(ncall_t *ncall, int flags, int svc_id,
529 528 struct timeval *t, ...)
530 529 {
531 530 va_list ap;
532 531 int rc = ENOLINK;
533 532
534 533 va_start(ap, t);
535 534
536 535 if (ncall_modules)
537 536 rc = (*ncall_modules->module->ncall_broadcast)(ncall, flags,
538 537 svc_id, t, ap);
539 538 va_end(ap);
540 539
541 540 return (rc);
542 541 }
543 542
544 543
545 544 int
546 545 ncall_send(ncall_t *ncall, int flags, int svc_id, ...)
547 546 {
548 547 va_list ap;
549 548 int rc = ENOLINK;
550 549
551 550 va_start(ap, svc_id);
552 551
553 552 if (ncall_modules)
554 553 rc = (*ncall_modules->module->ncall_timedsend)(ncall, flags,
555 554 svc_id, NULL, ap);
556 555
557 556 va_end(ap);
558 557
559 558 return (rc);
560 559 }
561 560
562 561
563 562 int
564 563 ncall_read_reply(ncall_t *ncall, int n, ...)
565 564 {
566 565 va_list ap;
567 566 int rc = ENOLINK;
568 567
569 568 va_start(ap, n);
570 569
571 570 if (ncall_modules)
572 571 rc = (*ncall_modules->module->ncall_read_reply)(ncall, n, ap);
573 572
574 573 va_end(ap);
575 574
576 575 return (rc);
577 576 }
578 577
579 578
580 579 void
581 580 ncall_reset(ncall_t *ncall)
582 581 {
583 582 if (ncall_modules)
584 583 (*ncall_modules->module->ncall_reset)(ncall);
585 584 }
586 585
587 586
588 587 void
589 588 ncall_free(ncall_t *ncall)
590 589 {
591 590 if (ncall_modules)
592 591 (*ncall_modules->module->ncall_free)(ncall);
593 592 }
594 593
595 594
596 595 int
597 596 ncall_put_data(ncall_t *ncall, void *data, int len)
598 597 {
599 598 int rc = ENOLINK;
600 599
601 600 if (ncall_modules)
602 601 rc = (*ncall_modules->module->ncall_put_data)(ncall, data, len);
603 602
604 603 return (rc);
605 604 }
606 605
607 606
608 607 int
609 608 ncall_get_data(ncall_t *ncall, void *data, int len)
610 609 {
611 610 int rc = ENOLINK;
612 611
613 612 if (ncall_modules)
614 613 rc = (*ncall_modules->module->ncall_get_data)(ncall, data, len);
615 614
616 615 return (rc);
617 616 }
618 617
619 618
620 619 int
621 620 ncall_sender(ncall_t *ncall)
622 621 {
623 622 int rc = -1;
624 623
625 624 if (ncall_modules)
626 625 rc = (*ncall_modules->module->ncall_sender)(ncall);
627 626
628 627 return (rc);
629 628 }
630 629
631 630
632 631 void
633 632 ncall_reply(ncall_t *ncall, ...)
634 633 {
635 634 va_list ap;
636 635
637 636 if (ncall_modules) {
638 637 va_start(ap, ncall);
639 638
640 639 (*ncall_modules->module->ncall_reply)(ncall, ap);
641 640
642 641 va_end(ap);
643 642 }
644 643 }
645 644
646 645
647 646 void
648 647 ncall_pend(ncall_t *ncall)
649 648 {
650 649 if (ncall_modules)
651 650 (*ncall_modules->module->ncall_pend)(ncall);
652 651 }
653 652
654 653
655 654 void
656 655 ncall_done(ncall_t *ncall)
657 656 {
658 657 if (ncall_modules)
659 658 (*ncall_modules->module->ncall_done)(ncall);
660 659 }
661 660
662 661 int
663 662 ncall_ping(char *nodename, int *up)
664 663 {
665 664 int rc = ENOLINK;
666 665 if (ncall_modules)
667 666 rc = (*ncall_modules->module->ncall_ping)(nodename, up);
668 667 return (rc);
669 668 }
670 669
671 670 int
672 671 ncall_maxnodes()
673 672 {
674 673 int rc = 0;
675 674
676 675 if (ncall_modules)
677 676 rc = (*ncall_modules->module->ncall_maxnodes)();
678 677
679 678 return (rc);
680 679 }
681 680
682 681 int
683 682 ncall_nextnode(void **vptr)
684 683 {
685 684 int rc = 0;
686 685
687 686 if (ncall_modules)
688 687 rc = (*ncall_modules->module->ncall_nextnode)(vptr);
689 688
690 689 return (rc);
691 690 }
692 691
693 692 int
694 693 ncall_errcode(ncall_t *ncall, int *result)
695 694 {
696 695 int rc = ENOLINK;
697 696 if (ncall_modules)
698 697 rc = (*ncall_modules->module->ncall_errcode)(ncall, result);
699 698
700 699 return (rc);
701 700 }
702 701
703 702 static int
704 703 ncallgetnodes(intptr_t uaddr, int mode, int *rvalp)
705 704 {
706 705 ncall_node_t *nodelist;
707 706 int slot;
708 707 int rc;
709 708 int nodecnt;
710 709 int nodeid;
711 710 void *sequence;
712 711 char *nodename;
713 712
714 713 rc = 0;
715 714
716 715 nodecnt = ncall_maxnodes();
717 716 if (nodecnt <= 0) {
718 717 return (ENONET);
719 718 }
720 719
721 720 /*
722 721 * If the user passes up a null address argument, then
723 722 * he/she doesn't want the actual nodes, but the configured
724 723 * maximum, so space can be correctly allocated.
725 724 */
726 725
727 726 if (uaddr == NULL) {
728 727 *rvalp = nodecnt;
729 728 return (0);
730 729 }
731 730 nodelist = kmem_zalloc(sizeof (*nodelist) * nodecnt, KM_SLEEP);
732 731
733 732 slot = 0;
734 733 sequence = NULL;
735 734 while ((nodeid = ncall_nextnode(&sequence)) > 0) {
736 735 nodename = ncall_nodename(nodeid);
737 736 /*
738 737 * There is a small window where nextnode can
739 738 * return a valid nodeid, and it being disabled
740 739 * which will get nodename to return "".
741 740 * Discard the nodeid if this happens.
742 741 */
743 742 if (strlen(nodename) > 0) {
744 743 int size = sizeof (nodelist[slot].nc_nodename) - 1;
745 744 ASSERT(slot < nodecnt);
746 745 /*
747 746 * make sure its null terminated when it
748 747 * gets to userland.
749 748 */
750 749 nodelist[slot].nc_nodename[size] = 0;
751 750 (void) strncpy(nodelist[slot].nc_nodename, nodename,
752 751 size);
753 752 nodelist[slot].nc_nodeid = nodeid;
754 753 slot++;
755 754 }
756 755 }
757 756 if (ddi_copyout(nodelist, (void *)uaddr, sizeof (*nodelist) * slot,
758 757 mode) < 0) {
759 758 rc = EFAULT;
760 759 } else {
761 760 /*
762 761 * tell them how many have come back.
763 762 */
764 763 *rvalp = slot;
765 764 }
766 765 kmem_free(nodelist, sizeof (*nodelist) * nodecnt);
767 766 return (rc);
768 767 }
↓ open down ↓ |
414 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX