Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/avs/ns/nsctl/nsctl.c
+++ new/usr/src/uts/common/avs/ns/nsctl/nsctl.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 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 * Copyright 2012 Milan Jurik. All rights reserved.
25 25 */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/ksynch.h>
29 29 #include <sys/kmem.h>
30 30 #include <sys/file.h>
31 31 #include <sys/errno.h>
32 32 #include <sys/open.h>
33 33 #include <sys/cred.h>
34 34 #include <sys/conf.h>
35 35 #include <sys/uio.h>
36 36 #include <sys/cmn_err.h>
37 37 #include <sys/modctl.h>
38 38 #include <sys/ddi.h>
39 39
40 40 #define __NSC_GEN__
41 41 #include <sys/nsctl/nsc_dev.h>
42 42 #include <sys/nsctl/nsc_gen.h>
43 43 #include <sys/nsctl/nsc_ioctl.h>
44 44 #include <sys/nsctl/nsc_power.h>
45 45 #include <sys/nsctl/nsc_mem.h>
46 46 #include "../nsctl.h"
47 47
48 48 #include <sys/nsctl/nsvers.h>
49 49
50 50 #ifdef DS_DDICT
51 51 #include "../contract.h"
52 52 #endif
53 53
54 54 extern void nscsetup();
55 55 extern int _nsc_init_raw(int);
56 56 extern void _nsc_deinit_raw();
57 57 extern void _nsc_init_start();
58 58 extern void _nsc_init_os(), _nsc_deinit_os();
59 59 extern void _nsc_init_dev(), _nsc_init_mem();
60 60 extern void _nsc_init_gen(), _nsc_init_rmlock();
61 61 extern void _nsc_init_resv(), _nsc_deinit_resv();
62 62 extern void _nsc_init_frz(), _nsc_deinit_frz();
63 63 extern void _nsc_init_ncio(), _nsc_deinit_ncio();
64 64 extern void _nsc_deinit_mem(), _nsc_deinit_rmlock();
65 65 extern void _nsc_deinit_dev();
66 66
67 67 extern int _nsc_frz_start(char *, int *);
68 68 extern int _nsc_frz_stop(char *, int *);
69 69 extern int _nsc_frz_isfrozen(char *, int *);
70 70
71 71 extern nsc_mem_t *_nsc_local_mem;
72 72 extern nsc_rmhdr_t *_nsc_rmhdr_ptr;
73 73 extern nsc_def_t _nsc_raw_def[];
74 74 extern int _nsc_raw_flags;
75 75
76 76 int nsc_devflag = D_MP;
77 77
78 78 int _nsc_init_done = 0;
79 79
80 80 kmutex_t _nsc_drv_lock;
81 81 nsc_io_t *_nsc_file_io;
82 82 nsc_io_t *_nsc_vchr_io;
83 83 nsc_io_t *_nsc_raw_io;
84 84
85 85 nsc_fd_t **_nsc_minor_fd;
86 86 kmutex_t **_nsc_minor_slp;
87 87
88 88
89 89 /* Maximum number of devices - tunable in nsctl.conf */
90 90 static int _nsc_max_devices;
91 91
92 92 /* Internal version of _nsc_max_devices */
93 93 int _nsc_maxdev;
94 94
95 95 extern void _nsc_global_setup(void);
96 96
97 97 static int nsc_load(), nsc_unload();
98 98 static void nscteardown();
99 99
100 100 /*
101 101 * Solaris specific driver module interface code.
102 102 */
103 103
104 104 extern int nscopen(dev_t *, int, int, cred_t *);
105 105 extern int nscioctl(dev_t, int, intptr_t, int, cred_t *, int *);
106 106 extern int nscclose(dev_t, int, int, cred_t *);
107 107 extern int nscread(dev_t, uio_t *, cred_t *);
108 108 extern int nscwrite(dev_t, uio_t *, cred_t *);
109 109
110 110 static dev_info_t *nsctl_dip; /* Single DIP for driver */
111 111
112 112 static int _nsctl_print(dev_t, char *);
113 113
114 114 static struct cb_ops nsctl_cb_ops = {
115 115 nscopen, /* open */
116 116 nscclose, /* close */
117 117 nodev, /* not a block driver, strategy not an entry point */
118 118 _nsctl_print, /* no print routine */
119 119 nodev, /* no dump routine */
120 120 nscread, /* read */
121 121 nscwrite, /* write */
122 122 (int (*)()) nscioctl, /* ioctl */
123 123 nodev, /* no devmap routine */
124 124 nodev, /* no mmap routine */
125 125 nodev, /* no segmap routine */
126 126 nochpoll, /* no chpoll routine */
127 127 ddi_prop_op,
128 128 0, /* not a STREAMS driver, no cb_str routine */
129 129 D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
130 130 CB_REV,
131 131 nodev, /* aread */
132 132 nodev, /* awrite */
133 133 };
134 134
135 135 static int _nsctl_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
136 136 static int _nsctl_attach(dev_info_t *, ddi_attach_cmd_t);
137 137 static int _nsctl_detach(dev_info_t *, ddi_detach_cmd_t);
138 138
139 139 static struct dev_ops nsctl_ops = {
140 140 DEVO_REV, /* Driver build version */
141 141 0, /* device reference count */
142 142 _nsctl_getinfo,
143 143 nulldev, /* Identify */
144 144 nulldev, /* Probe */
145 145 _nsctl_attach,
146 146 _nsctl_detach,
147 147 nodev, /* Reset */
148 148 &nsctl_cb_ops,
149 149 (struct bus_ops *)0
↓ open down ↓ |
149 lines elided |
↑ open up ↑ |
150 150 };
151 151
152 152 static struct modldrv nsctl_ldrv = {
153 153 &mod_driverops,
154 154 "nws:Control:" ISS_VERSION_STR,
155 155 &nsctl_ops
156 156 };
157 157
158 158 static struct modlinkage nsctl_modlinkage = {
159 159 MODREV_1,
160 - &nsctl_ldrv,
161 - NULL
160 + { &nsctl_ldrv, NULL }
162 161 };
163 162
164 163 /*
165 164 * Solaris module load time code
166 165 */
167 166
168 167 int nsc_min_nodeid;
169 168 int nsc_max_nodeid;
170 169
171 170 int
172 171 _init(void)
173 172 {
174 173 int err;
175 174
176 175 err = nsc_load();
177 176
178 177 if (!err)
179 178 err = mod_install(&nsctl_modlinkage);
180 179
181 180 if (err) {
182 181 (void) nsc_unload();
183 182 cmn_err(CE_NOTE, "!nsctl_init: err %d", err);
184 183 }
185 184
186 185 return (err);
187 186
188 187 }
189 188
190 189 /*
191 190 * Solaris module unload time code
192 191 */
193 192
194 193 int
195 194 _fini(void)
196 195 {
197 196 int err;
198 197
199 198 if ((err = mod_remove(&nsctl_modlinkage)) == 0) {
200 199 err = nsc_unload();
201 200 }
202 201 return (err);
203 202 }
204 203
205 204 /*
206 205 * Solaris module info code
207 206 */
208 207 int
209 208 _info(struct modinfo *modinfop)
210 209 {
211 210 return (mod_info(&nsctl_modlinkage, modinfop));
212 211 }
213 212
214 213 /*
215 214 * Attach an instance of the device. This happens before an open
216 215 * can succeed.
217 216 */
218 217 static int
219 218 _nsctl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
220 219 {
221 220 int rc;
222 221
223 222 if (cmd == DDI_ATTACH) {
224 223 nsctl_dip = dip;
225 224
226 225 /* Announce presence of the device */
227 226 ddi_report_dev(dip);
228 227
229 228 /*
230 229 * Get the node parameters now that we can look up.
231 230 */
232 231 nsc_min_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
233 232 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
234 233 "nsc_min_nodeid", 0);
235 234
236 235 nsc_max_nodeid = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
237 236 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
238 237 "nsc_max_nodeid", 5);
239 238
240 239 _nsc_max_devices = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
241 240 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
242 241 "nsc_max_devices", 128);
243 242
244 243 _nsc_maxdev = _nsc_max_devices;
245 244 nscsetup();
246 245
247 246 /*
248 247 * Init raw requires the _nsc_max_devices value and so
249 248 * cannot be done before the nsc_max_devices property has
250 249 * been read which can only be done after the module is
251 250 * attached and we have a dip.
252 251 */
253 252
254 253 if ((rc = _nsc_init_raw(_nsc_max_devices)) != 0) {
255 254 cmn_err(CE_WARN,
256 255 "!nsctl: unable to initialize raw io provider: %d",
257 256 rc);
258 257 return (DDI_FAILURE);
259 258 }
260 259
261 260 /*
262 261 * Init rest of soft state structure
263 262 */
264 263
265 264 rc = ddi_create_minor_node(dip, "c,nsctl", S_IFCHR, 0,
266 265 DDI_PSEUDO, 0);
267 266 if (rc != DDI_SUCCESS) {
268 267 /* free anything we allocated here */
269 268 cmn_err(CE_WARN,
270 269 "!_nsctl_attach: ddi_create_minor_node failed %d",
271 270 rc);
272 271 return (DDI_FAILURE);
273 272 }
274 273
275 274 /* Announce presence of the device */
276 275 ddi_report_dev(dip);
277 276
278 277 /* mark the device as attached, opens may proceed */
279 278 return (DDI_SUCCESS);
280 279 } else
281 280 return (DDI_FAILURE);
282 281 }
283 282
284 283 static int
285 284 _nsctl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
286 285 {
287 286 if (cmd == DDI_DETACH) {
288 287 nscteardown();
289 288 _nsc_deinit_raw();
290 289
291 290 ddi_remove_minor_node(dip, NULL);
292 291 nsctl_dip = NULL;
293 292
294 293 return (DDI_SUCCESS);
295 294 }
296 295 else
297 296 return (DDI_FAILURE);
298 297 }
299 298
300 299
301 300 /* ARGSUSED */
302 301 static int
303 302 _nsctl_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
304 303 {
305 304 dev_t dev;
306 305 int rc;
307 306
308 307 switch (cmd) {
309 308 case DDI_INFO_DEVT2INSTANCE:
310 309 /* The "instance" number is the minor number */
311 310 dev = (dev_t)arg;
312 311 *result = (void *)(unsigned long)getminor(dev);
313 312 rc = DDI_SUCCESS;
314 313 break;
315 314
316 315 case DDI_INFO_DEVT2DEVINFO:
317 316 *result = nsctl_dip;
318 317 rc = DDI_SUCCESS;
319 318 break;
320 319
321 320 default:
322 321 rc = DDI_FAILURE;
323 322 break;
324 323 }
325 324
326 325 return (rc);
327 326 }
328 327
329 328
330 329 /* ARGSUSED */
331 330 static int
332 331 _nsctl_print(dev_t dev, char *s)
333 332 {
334 333 cmn_err(CE_WARN, "!nsctl:%s", s);
335 334 return (0);
336 335 }
337 336
338 337
339 338 void
340 339 nsc_init()
341 340 {
342 341 if (_nsc_init_done)
343 342 return;
344 343
345 344 _nsc_init_start();
346 345 _nsc_init_gen();
347 346 _nsc_init_svc();
348 347 _nsc_init_mem();
349 348 _nsc_init_dev();
350 349 _nsc_init_rmlock();
351 350 _nsc_init_resv();
352 351 _nsc_init_os();
353 352 (void) _nsc_init_power();
354 353
355 354 /*
356 355 * When using mc, nscsetup is done through mc callback to global_init.
357 356 */
358 357 nscsetup();
359 358
360 359 mutex_init(&_nsc_drv_lock, NULL, MUTEX_DRIVER, NULL);
361 360
362 361 _nsc_raw_io = nsc_register_io("raw",
363 362 NSC_RAW_ID | _nsc_raw_flags, _nsc_raw_def);
364 363
365 364 if (!_nsc_raw_io)
366 365 cmn_err(CE_WARN, "!_nsc_init: register io failed - raw");
367 366
368 367 _nsc_init_ncio();
369 368 _nsc_init_frz();
370 369
371 370 _nsc_init_done = 1;
372 371 }
373 372
374 373
375 374 /*
376 375 * Called after the mc refresh is complete (SEG_INIT callbacks have
377 376 * been received) and module _attach() is done. Only does any real
378 377 * work when all of the above conditions have been met.
379 378 */
380 379 void
381 380 nscsetup()
382 381 {
383 382 if (nsc_max_devices() == 0 || _nsc_minor_fd != NULL)
384 383 return;
385 384
386 385 _nsc_minor_fd = nsc_kmem_zalloc(sizeof (nsc_fd_t *)*_nsc_maxdev,
387 386 0, _nsc_local_mem);
388 387
389 388 if (!_nsc_minor_fd) {
390 389 cmn_err(CE_WARN, "!nscsetup - alloc failed");
391 390 return;
392 391 }
393 392
394 393 _nsc_minor_slp = nsc_kmem_zalloc(sizeof (kmutex_t *)*_nsc_maxdev,
395 394 0, _nsc_local_mem);
396 395
397 396 if (!_nsc_minor_slp) {
398 397 cmn_err(CE_WARN, "!nscsetup - alloc failed");
399 398 nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
400 399 _nsc_minor_fd = (nsc_fd_t **)NULL;
401 400 }
402 401 }
403 402
404 403 static void
405 404 nscteardown()
406 405 {
407 406 int i;
408 407
409 408 if (_nsc_minor_fd == NULL)
410 409 return;
411 410
412 411 #ifdef DEBUG
413 412 /* Check all devices were closed. Index 0 is the prototype dev. */
414 413 for (i = 1; i < _nsc_maxdev; i++) {
415 414 ASSERT(_nsc_minor_slp[i] == NULL);
416 415 ASSERT(_nsc_minor_fd[i] == NULL);
417 416 }
418 417 #endif /* DEBUG */
419 418
420 419 nsc_kmem_free(_nsc_minor_fd, sizeof (nsc_fd_t *) * _nsc_maxdev);
421 420 nsc_kmem_free(_nsc_minor_slp, sizeof (kmutex_t *) * _nsc_maxdev);
422 421
423 422 _nsc_minor_fd = (nsc_fd_t **)NULL;
424 423 _nsc_minor_slp = (kmutex_t **)NULL;
425 424 }
426 425
427 426 int
428 427 nsc_load()
429 428 {
430 429 nsc_init();
431 430 return (0);
432 431 }
433 432
434 433
435 434 int
436 435 nsc_unload()
437 436 {
438 437 if (!_nsc_init_done) {
439 438 return (0);
440 439 }
441 440
442 441 nscteardown();
443 442
444 443 (void) _nsc_deinit_power();
445 444 _nsc_deinit_resv();
446 445 _nsc_deinit_mem();
447 446 _nsc_deinit_rmlock();
448 447 _nsc_deinit_svc();
449 448 _nsc_deinit_frz();
450 449 _nsc_deinit_ncio();
451 450
452 451 if (_nsc_vchr_io)
453 452 (void) nsc_unregister_io(_nsc_vchr_io, 0);
454 453
455 454 if (_nsc_file_io)
456 455 (void) nsc_unregister_io(_nsc_file_io, 0);
457 456
458 457 _nsc_vchr_io = NULL;
459 458 _nsc_file_io = NULL;
460 459
461 460 if (_nsc_raw_io)
462 461 (void) nsc_unregister_io(_nsc_raw_io, 0);
463 462
464 463 _nsc_raw_io = NULL;
465 464
466 465 _nsc_deinit_dev();
467 466 _nsc_deinit_os();
468 467
469 468 _nsc_init_done = 0;
470 469 return (0);
471 470 }
472 471
473 472
474 473 /* ARGSUSED */
475 474
476 475 int
477 476 nscopen(dev_t *devp, int flag, int otyp, cred_t *crp)
478 477 {
479 478 kmutex_t *slp;
480 479 int i, error;
481 480
482 481 if (error = drv_priv(crp))
483 482 return (error);
484 483
485 484 if (!_nsc_minor_fd || !_nsc_minor_slp)
486 485 return (ENXIO);
487 486
488 487 if (getminor(*devp) != 0)
489 488 return (ENXIO);
490 489
491 490 slp = nsc_kmem_alloc(sizeof (kmutex_t), 0, _nsc_local_mem);
492 491 mutex_init(slp, NULL, MUTEX_DRIVER, NULL);
493 492
494 493 mutex_enter(&_nsc_drv_lock);
495 494
496 495 for (i = 1; i < _nsc_maxdev; i++) {
497 496 if (_nsc_minor_slp[i] == NULL) {
498 497 _nsc_minor_slp[i] = slp;
499 498 break;
500 499 }
501 500 }
502 501
503 502 mutex_exit(&_nsc_drv_lock);
504 503
505 504 if (i >= _nsc_maxdev) {
506 505 mutex_destroy(slp);
507 506 nsc_kmem_free(slp, sizeof (kmutex_t));
508 507 return (EAGAIN);
509 508 }
510 509
511 510 *devp = makedevice(getmajor(*devp), i);
512 511
513 512 return (0);
514 513 }
515 514
516 515
517 516 int
518 517 _nscopen(dev_t dev, intptr_t arg, int mode, int *rvp)
519 518 {
520 519 minor_t mindev = getminor(dev);
521 520 struct nscioc_open *op;
522 521 nsc_fd_t *fd;
523 522 int rc;
524 523
525 524 op = nsc_kmem_alloc(sizeof (*op), KM_SLEEP, _nsc_local_mem);
526 525 if (op == NULL) {
527 526 return (ENOMEM);
528 527 }
529 528
530 529 if (ddi_copyin((void *)arg, op, sizeof (*op), mode) < 0) {
531 530 nsc_kmem_free(op, sizeof (*op));
532 531 return (EFAULT);
533 532 }
534 533
535 534 mutex_enter(_nsc_minor_slp[mindev]);
536 535
537 536 if (_nsc_minor_fd[mindev]) {
538 537 mutex_exit(_nsc_minor_slp[mindev]);
539 538 nsc_kmem_free(op, sizeof (*op));
540 539 return (EBUSY);
541 540 }
542 541
543 542 op->path[sizeof (op->path)-1] = 0;
544 543
545 544 fd = nsc_open(op->path, (op->flag & NSC_TYPES), 0, 0, &rc);
546 545
547 546 if (fd == NULL) {
548 547 mutex_exit(_nsc_minor_slp[mindev]);
549 548 nsc_kmem_free(op, sizeof (*op));
550 549 return (rc);
551 550 }
552 551
553 552 mode |= (op->mode - FOPEN);
554 553
555 554 if (mode & (FWRITE|FEXCL)) {
556 555 if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
557 556 mutex_exit(_nsc_minor_slp[mindev]);
558 557 (void) nsc_close(fd);
559 558 nsc_kmem_free(op, sizeof (*op));
560 559 return (rc);
561 560 }
562 561 }
563 562
564 563 *rvp = 0;
565 564 _nsc_minor_fd[mindev] = fd;
566 565
567 566 mutex_exit(_nsc_minor_slp[mindev]);
568 567 nsc_kmem_free(op, sizeof (*op));
569 568 return (0);
570 569 }
571 570
572 571
573 572 /* ARGSUSED */
574 573
575 574 int
576 575 nscclose(dev_t dev, int flag, int otyp, cred_t *crp)
577 576 {
578 577 minor_t mindev = getminor(dev);
579 578 kmutex_t *slp;
580 579 nsc_fd_t *fd;
581 580
582 581 if (!_nsc_minor_fd || !_nsc_minor_slp)
583 582 return (0);
584 583
585 584 if ((slp = _nsc_minor_slp[mindev]) == 0)
586 585 return (0);
587 586
588 587 if ((fd = _nsc_minor_fd[mindev]) != NULL)
589 588 (void) nsc_close(fd);
590 589
591 590 _nsc_minor_fd[mindev] = NULL;
592 591 _nsc_minor_slp[mindev] = NULL;
593 592
594 593 mutex_destroy(slp);
595 594 nsc_kmem_free(slp, sizeof (kmutex_t));
596 595 return (0);
597 596 }
598 597
599 598
600 599 /* ARGSUSED */
601 600
602 601 int
603 602 nscread(dev_t dev, uio_t *uiop, cred_t *crp)
604 603 {
605 604 minor_t mindev = getminor(dev);
606 605 int rc, resv;
607 606 nsc_fd_t *fd;
608 607
609 608 if ((fd = _nsc_minor_fd[mindev]) == 0)
610 609 return (EIO);
611 610
612 611 mutex_enter(_nsc_minor_slp[mindev]);
613 612
614 613 resv = (nsc_held(fd) == 0);
615 614
616 615 if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
617 616 mutex_exit(_nsc_minor_slp[mindev]);
618 617 return (rc);
619 618 }
620 619
621 620 rc = nsc_uread(fd, uiop, crp);
622 621
623 622 if (resv)
624 623 nsc_release(fd);
625 624
626 625 mutex_exit(_nsc_minor_slp[mindev]);
627 626 return (rc);
628 627 }
629 628
630 629
631 630 /* ARGSUSED */
632 631
633 632 int
634 633 nscwrite(dev_t dev, uio_t *uiop, cred_t *crp)
635 634 {
636 635 minor_t mindev = getminor(dev);
637 636 int rc, resv;
638 637 nsc_fd_t *fd;
639 638
640 639 if ((fd = _nsc_minor_fd[mindev]) == 0)
641 640 return (EIO);
642 641
643 642 mutex_enter(_nsc_minor_slp[mindev]);
644 643
645 644 resv = (nsc_held(fd) == 0);
646 645
647 646 if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
648 647 mutex_exit(_nsc_minor_slp[mindev]);
649 648 return (rc);
650 649 }
651 650
652 651 rc = nsc_uwrite(fd, uiop, crp);
653 652
654 653 if (resv)
655 654 nsc_release(fd);
656 655
657 656 mutex_exit(_nsc_minor_slp[mindev]);
658 657 return (rc);
659 658 }
660 659
661 660
662 661 int
663 662 _nscreserve(dev_t dev, int *rvp)
664 663 {
665 664 minor_t mindev = getminor(dev);
666 665 nsc_fd_t *fd;
667 666 int rc;
668 667
669 668 if ((fd = _nsc_minor_fd[mindev]) == 0)
670 669 return (EIO);
671 670
672 671 mutex_enter(_nsc_minor_slp[mindev]);
673 672
674 673 if (nsc_held(fd)) {
675 674 mutex_exit(_nsc_minor_slp[mindev]);
676 675 return (EBUSY);
677 676 }
678 677
679 678 if ((rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
680 679 mutex_exit(_nsc_minor_slp[mindev]);
681 680 return (rc);
682 681 }
683 682
684 683 *rvp = 0;
685 684
686 685 mutex_exit(_nsc_minor_slp[mindev]);
687 686 return (0);
688 687 }
689 688
690 689
691 690 int
692 691 _nscrelease(dev_t dev, int *rvp)
693 692 {
694 693 minor_t mindev = getminor(dev);
695 694 nsc_fd_t *fd;
696 695
697 696 if ((fd = _nsc_minor_fd[mindev]) == 0)
698 697 return (EIO);
699 698
700 699 mutex_enter(_nsc_minor_slp[mindev]);
701 700
702 701 if (!nsc_held(fd)) {
703 702 mutex_exit(_nsc_minor_slp[mindev]);
704 703 return (EINVAL);
705 704 }
706 705
707 706 nsc_release(fd);
708 707
709 708 *rvp = 0;
710 709
711 710 mutex_exit(_nsc_minor_slp[mindev]);
712 711 return (0);
713 712 }
714 713
715 714
716 715 int
717 716 _nscpartsize(dev_t dev, intptr_t arg, int mode)
718 717 {
719 718 struct nscioc_partsize partsize;
720 719 minor_t mindev = getminor(dev);
721 720 nsc_size_t size;
722 721 int rc, resv;
723 722 nsc_fd_t *fd;
724 723
725 724 if ((fd = _nsc_minor_fd[mindev]) == 0)
726 725 return (EIO);
727 726
728 727 mutex_enter(_nsc_minor_slp[mindev]);
729 728
730 729 resv = (nsc_held(fd) == 0);
731 730
732 731 if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
733 732 mutex_exit(_nsc_minor_slp[mindev]);
734 733 return (rc);
735 734 }
736 735
737 736 rc = nsc_partsize(fd, &size);
738 737 partsize.partsize = (uint64_t)size;
739 738
740 739 if (resv)
741 740 nsc_release(fd);
742 741
743 742 mutex_exit(_nsc_minor_slp[mindev]);
744 743
745 744 if (ddi_copyout((void *)&partsize, (void *)arg,
746 745 sizeof (partsize), mode) < 0) {
747 746 return (EFAULT);
748 747 }
749 748
750 749 return (rc);
751 750 }
752 751
753 752
754 753 /* ARGSUSED */
755 754
756 755 int
757 756 nscioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
758 757 {
759 758 struct nscioc_bsize *bsize = NULL;
760 759 char *path = NULL;
761 760 int rc = 0;
762 761
763 762 *rvp = 0;
764 763
765 764 switch (cmd) {
766 765 case NSCIOC_OPEN:
767 766 rc = _nscopen(dev, arg, mode, rvp);
768 767 break;
769 768
770 769 case NSCIOC_RESERVE:
771 770 rc = _nscreserve(dev, rvp);
772 771 break;
773 772
774 773 case NSCIOC_RELEASE:
775 774 rc = _nscrelease(dev, rvp);
776 775 break;
777 776
778 777 case NSCIOC_PARTSIZE:
779 778 rc = _nscpartsize(dev, arg, mode);
780 779 break;
781 780
782 781 case NSCIOC_FREEZE:
783 782 path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
784 783 if (path == NULL) {
785 784 rc = ENOMEM;
786 785 break;
787 786 }
788 787 if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
789 788 rc = EFAULT;
790 789 else {
791 790 path[NSC_MAXPATH-1] = 0;
792 791 rc = _nsc_frz_start(path, rvp);
793 792 }
794 793 break;
795 794
796 795 case NSCIOC_UNFREEZE:
797 796 path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
798 797 if (path == NULL) {
799 798 rc = ENOMEM;
800 799 break;
801 800 }
802 801 if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
803 802 rc = EFAULT;
804 803 else {
805 804 path[NSC_MAXPATH-1] = 0;
806 805 rc = _nsc_frz_stop(path, rvp);
807 806 }
808 807 break;
809 808
810 809 case NSCIOC_ISFROZEN:
811 810 path = nsc_kmem_alloc(NSC_MAXPATH, KM_SLEEP, _nsc_local_mem);
812 811 if (path == NULL) {
813 812 rc = ENOMEM;
814 813 break;
815 814 }
816 815 if (ddi_copyin((void *)arg, path, NSC_MAXPATH, mode) < 0)
817 816 rc = EFAULT;
818 817 else {
819 818 path[NSC_MAXPATH-1] = 0;
820 819 rc = _nsc_frz_isfrozen(path, rvp);
821 820 }
822 821 break;
823 822
824 823 #ifdef ENABLE_POWER_MSG
825 824 case NSCIOC_POWERMSG:
826 825 rc = _nsc_power((void *)arg, rvp);
827 826 break;
828 827 #endif
829 828
830 829 case NSCIOC_NSKERND:
831 830 rc = nskernd_command(arg, mode, rvp);
832 831 break;
833 832
834 833 /* return sizes of global memory segments */
835 834 case NSCIOC_GLOBAL_SIZES:
836 835 if (!_nsc_init_done) {
837 836 rc = EINVAL;
838 837 break;
839 838 }
840 839
841 840 rc = _nsc_get_global_sizes((void *)arg, rvp);
842 841
843 842 break;
844 843
845 844 /* return contents of global segments */
846 845 case NSCIOC_GLOBAL_DATA:
847 846 if (!_nsc_init_done) {
848 847 rc = EINVAL;
849 848 break;
850 849 }
851 850
852 851 rc = _nsc_get_global_data((void *)arg, rvp);
853 852 break;
854 853
855 854 /*
856 855 * nvmem systems:
857 856 * clear the hdr dirty bit to prevent loading from nvme on reboot
858 857 */
859 858 case NSCIOC_NVMEM_CLEANF:
860 859 rc = _nsc_clear_dirty(1); /* dont be nice about it */
861 860 break;
862 861 case NSCIOC_NVMEM_CLEAN:
863 862 rc = _nsc_clear_dirty(0);
864 863 break;
865 864
866 865 case NSCIOC_BSIZE:
867 866 bsize = nsc_kmem_alloc(sizeof (*bsize), KM_SLEEP,
868 867 _nsc_local_mem);
869 868 if (bsize == NULL) {
870 869 rc = ENOMEM;
871 870 break;
872 871 }
873 872
874 873 if (ddi_copyin((void *)arg, bsize, sizeof (*bsize), mode) < 0) {
875 874 rc = EFAULT;
876 875 break;
877 876 }
878 877
879 878 rc = nskern_bsize(bsize, rvp);
880 879 if (rc == 0) {
881 880 if (ddi_copyout(bsize, (void *)arg,
882 881 sizeof (*bsize), mode) < 0) {
883 882 rc = EFAULT;
884 883 break;
885 884 }
886 885 }
887 886
888 887 break;
889 888
890 889 default:
891 890 return (ENOTTY);
892 891 }
893 892
894 893 if (bsize != NULL) {
895 894 nsc_kmem_free(bsize, sizeof (*bsize));
896 895 bsize = NULL;
897 896 }
898 897 if (path != NULL) {
899 898 nsc_kmem_free(path, NSC_MAXPATH);
900 899 path = NULL;
901 900 }
902 901 return (rc);
903 902 }
904 903
905 904
906 905 int
907 906 nsc_max_devices(void)
908 907 {
909 908 return (_nsc_max_devices);
910 909 }
911 910
912 911
913 912 /*
914 913 * Used by _nsc_global_setup() in case nvram is dirty and has saved a different
915 914 * value for nsc_max_devices. We need to use the saved value, not the new
916 915 * one configured by the user.
917 916 */
918 917 void
919 918 _nsc_set_max_devices(int maxdev)
920 919 {
921 920 _nsc_max_devices = maxdev;
922 921 _nsc_maxdev = _nsc_max_devices;
923 922 }
↓ open down ↓ |
752 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX