Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/sysmsg.c
+++ new/usr/src/uts/common/io/sysmsg.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 /*
28 28 * System message redirection driver for Sun.
29 29 *
30 30 * Redirects system message output to the device designated as the underlying
31 31 * "hardware" console, as given by the value of sysmvp. The implementation
32 32 * assumes that sysmvp denotes a STREAMS device; the assumption is justified
33 33 * since consoles must be capable of effecting tty semantics.
34 34 */
35 35
36 36 #include <sys/types.h>
37 37 #include <sys/kmem.h>
38 38 #include <sys/open.h>
39 39 #include <sys/param.h>
40 40 #include <sys/systm.h>
41 41 #include <sys/signal.h>
42 42 #include <sys/cred.h>
43 43 #include <sys/user.h>
44 44 #include <sys/proc.h>
45 45 #include <sys/vnode.h>
46 46 #include <sys/uio.h>
47 47 #include <sys/stat.h>
48 48 #include <sys/file.h>
49 49 #include <sys/session.h>
50 50 #include <sys/stream.h>
51 51 #include <sys/strsubr.h>
52 52 #include <sys/poll.h>
53 53 #include <sys/debug.h>
54 54 #include <sys/sysmsg_impl.h>
55 55 #include <sys/conf.h>
56 56 #include <sys/termios.h>
57 57 #include <sys/errno.h>
58 58 #include <sys/modctl.h>
59 59 #include <sys/pathname.h>
60 60 #include <sys/ddi.h>
61 61 #include <sys/sunddi.h>
62 62 #include <sys/consdev.h>
63 63 #include <sys/policy.h>
64 64
65 65 /*
66 66 * internal functions
67 67 */
68 68 static int sysmopen(dev_t *, int, int, cred_t *);
69 69 static int sysmclose(dev_t, int, int, cred_t *);
70 70 static int sysmread(dev_t, struct uio *, cred_t *);
71 71 static int sysmwrite(dev_t, struct uio *, cred_t *);
72 72 static int sysmioctl(dev_t, int, intptr_t, int, cred_t *, int *);
73 73 static int sysmpoll(dev_t, short, int, short *, struct pollhead **);
74 74 static int sysm_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
75 75 static int sysm_attach(dev_info_t *, ddi_attach_cmd_t);
76 76 static int sysm_detach(dev_info_t *, ddi_detach_cmd_t);
77 77 static void bind_consadm_conf(char *);
78 78 static int checkarg(dev_t);
79 79
80 80 static dev_info_t *sysm_dip; /* private copy of devinfo pointer */
81 81
82 82 static struct cb_ops sysm_cb_ops = {
83 83
84 84 sysmopen, /* open */
85 85 sysmclose, /* close */
86 86 nodev, /* strategy */
87 87 nodev, /* print */
88 88 nodev, /* dump */
89 89 sysmread, /* read */
90 90 sysmwrite, /* write */
91 91 sysmioctl, /* ioctl */
92 92 nodev, /* devmap */
93 93 nodev, /* mmap */
94 94 nodev, /* segmap */
95 95 sysmpoll, /* poll */
96 96 ddi_prop_op, /* cb_prop_op */
97 97 NULL, /* streamtab */
98 98 D_NEW | D_MP, /* Driver compatibility flag */
99 99 CB_REV, /* cb_rev */
100 100 nodev, /* aread */
101 101 nodev /* awrite */
102 102 };
103 103
104 104 static struct dev_ops sysm_ops = {
105 105
106 106 DEVO_REV, /* devo_rev, */
107 107 0, /* refcnt */
108 108 sysm_info, /* info */
109 109 nulldev, /* identify */
110 110 nulldev, /* probe */
111 111 sysm_attach, /* attach */
112 112 sysm_detach, /* detach */
113 113 nodev, /* reset */
114 114 &sysm_cb_ops, /* driver operations */
115 115 (struct bus_ops *)0, /* bus operations */
116 116 nulldev, /* power */
117 117 ddi_quiesce_not_needed, /* quiesce */
118 118
119 119 };
120 120
121 121 /*
122 122 * Global variables associated with the console device:
123 123 */
124 124
125 125 #define SYS_SYSMIN 0 /* sysmsg minor number */
126 126 #define SYS_MSGMIN 1 /* msglog minor number */
127 127 #define SYSPATHLEN 255 /* length of device path */
128 128
129 129 /*
130 130 * Private driver state:
131 131 */
132 132
133 133 #define MAXDEVS 5
134 134
135 135 typedef struct {
136 136 dev_t dca_devt;
137 137 int dca_flags;
138 138 vnode_t *dca_vp;
139 139 krwlock_t dca_lock;
140 140 char dca_name[SYSPATHLEN];
141 141 } devicecache_t;
142 142
143 143 /* list of dyn. + persist. config'ed dev's */
144 144 static devicecache_t sysmcache[MAXDEVS];
145 145 static kmutex_t dcvp_mutex;
146 146 static vnode_t *dcvp = NULL;
147 147 static boolean_t sysmsg_opened;
148 148 static boolean_t msglog_opened;
149 149
150 150 /* flags for device cache */
151 151 #define SYSM_DISABLED 0x0
152 152 #define SYSM_ENABLED 0x1
153 153
154 154 /*
155 155 * Module linkage information for the kernel.
↓ open down ↓ |
155 lines elided |
↑ open up ↑ |
156 156 */
157 157
158 158 static struct modldrv modldrv = {
159 159 &mod_driverops, /* Type of module. This one is a pseudo driver */
160 160 "System message redirection (fanout) driver",
161 161 &sysm_ops, /* driver ops */
162 162 };
163 163
164 164 static struct modlinkage modlinkage = {
165 165 MODREV_1,
166 - &modldrv,
167 - NULL
166 + { &modldrv, NULL }
168 167 };
169 168
170 169 int
171 170 _init(void)
172 171 {
173 172 return (mod_install(&modlinkage));
174 173 }
175 174
176 175 int
177 176 _fini(void)
178 177 {
179 178 return (mod_remove(&modlinkage));
180 179 }
181 180
182 181 int
183 182 _info(struct modinfo *modinfop)
184 183 {
185 184 return (mod_info(&modlinkage, modinfop));
186 185 }
187 186
188 187 /*
189 188 * DDI glue routines
190 189 */
191 190 static int
192 191 sysm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
193 192 {
194 193 int i;
195 194
196 195 switch (cmd) {
197 196 case DDI_ATTACH:
198 197 ASSERT(sysm_dip == NULL);
199 198
200 199 if (ddi_create_minor_node(devi, "sysmsg", S_IFCHR,
201 200 SYS_SYSMIN, DDI_PSEUDO, NULL) == DDI_FAILURE ||
202 201 ddi_create_minor_node(devi, "msglog", S_IFCHR,
203 202 SYS_MSGMIN, DDI_PSEUDO, NULL) == DDI_FAILURE) {
204 203 ddi_remove_minor_node(devi, NULL);
205 204 return (DDI_FAILURE);
206 205 }
207 206
208 207 for (i = 0; i < MAXDEVS; i++) {
209 208 rw_init(&sysmcache[i].dca_lock, NULL, RW_DRIVER, NULL);
210 209 }
211 210
212 211 sysm_dip = devi;
213 212 return (DDI_SUCCESS);
214 213 case DDI_SUSPEND:
215 214 case DDI_PM_SUSPEND:
216 215 return (DDI_SUCCESS);
217 216 default:
218 217 return (DDI_FAILURE);
219 218 }
220 219 }
221 220
222 221 static int
223 222 sysm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
224 223 {
225 224 int i;
226 225
227 226 switch (cmd) {
228 227 case DDI_DETACH:
229 228 ASSERT(sysm_dip == devi);
230 229
231 230 for (i = 0; i < MAXDEVS; i++)
232 231 rw_destroy(&sysmcache[i].dca_lock);
233 232
234 233 ddi_remove_minor_node(devi, NULL);
235 234 sysm_dip = NULL;
236 235 return (DDI_SUCCESS);
237 236
238 237 case DDI_SUSPEND:
239 238 case DDI_PM_SUSPEND:
240 239 return (DDI_SUCCESS);
241 240 default:
242 241 return (DDI_FAILURE);
243 242 }
244 243
245 244 }
246 245
247 246 /* ARGSUSED */
248 247 static int
249 248 sysm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
250 249 {
251 250 int rval = DDI_FAILURE;
252 251 minor_t instance;
253 252
254 253 instance = getminor((dev_t)arg);
255 254
256 255 switch (infocmd) {
257 256 case DDI_INFO_DEVT2DEVINFO:
258 257 if (sysm_dip != NULL &&
259 258 (instance == SYS_SYSMIN || instance == SYS_MSGMIN)) {
260 259 *result = sysm_dip;
261 260 rval = DDI_SUCCESS;
262 261 }
263 262 break;
264 263
265 264 case DDI_INFO_DEVT2INSTANCE:
266 265 if (instance == SYS_SYSMIN || instance == SYS_MSGMIN) {
267 266 *result = NULL;
268 267 rval = DDI_SUCCESS;
269 268 }
270 269 break;
271 270
272 271 default:
273 272 break;
274 273 }
275 274
276 275 return (rval);
277 276 }
278 277
279 278 /*
280 279 * Parse the contents of the buffer, and bind the named
281 280 * devices as auxiliary consoles using our own ioctl routine.
282 281 *
283 282 * Comments begin with '#' and are terminated only by a newline
284 283 * Device names begin with a '/', and are terminated by a newline,
285 284 * space, '#' or tab.
286 285 */
287 286 static void
288 287 parse_buffer(char *buf, ssize_t fsize)
289 288 {
290 289 char *ebuf = buf + fsize;
291 290 char *devname = NULL;
292 291 int eatcomments = 0;
293 292
294 293 while (buf < ebuf) {
295 294 if (eatcomments) {
296 295 if (*buf++ == '\n')
297 296 eatcomments = 0;
298 297 continue;
299 298 }
300 299 switch (*buf) {
301 300 case '/':
302 301 if (devname == NULL)
303 302 devname = buf;
304 303 break;
305 304 case '#':
306 305 eatcomments = 1;
307 306 /*FALLTHROUGH*/
308 307 case ' ':
309 308 case '\t':
310 309 case '\n':
311 310 *buf = '\0';
312 311 if (devname == NULL)
313 312 break;
314 313 (void) sysmioctl(NODEV, CIOCSETCONSOLE,
315 314 (intptr_t)devname, FNATIVE|FKIOCTL|FREAD|FWRITE,
316 315 kcred, NULL);
317 316 devname = NULL;
318 317 break;
319 318 default:
320 319 break;
321 320 }
322 321 buf++;
323 322 }
324 323 }
325 324
326 325 #define CNSADM_BYTES_MAX 2000 /* XXX nasty fixed size */
327 326
328 327 static void
329 328 bind_consadm_conf(char *path)
330 329 {
331 330 struct vattr vattr;
332 331 vnode_t *vp;
333 332 void *buf;
334 333 size_t size;
335 334 ssize_t resid;
336 335 int err = 0;
337 336
338 337 if (vn_open(path, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0) != 0)
339 338 return;
340 339 vattr.va_mask = AT_SIZE;
341 340 if ((err = VOP_GETATTR(vp, &vattr, 0, kcred, NULL)) != 0) {
342 341 cmn_err(CE_WARN, "sysmsg: getattr: '%s': error %d",
343 342 path, err);
344 343 goto closevp;
345 344 }
346 345
347 346 size = vattr.va_size > CNSADM_BYTES_MAX ?
348 347 CNSADM_BYTES_MAX : (ssize_t)vattr.va_size;
349 348 buf = kmem_alloc(size, KM_SLEEP);
350 349
351 350 if ((err = vn_rdwr(UIO_READ, vp, buf, size, (offset_t)0,
352 351 UIO_SYSSPACE, 0, (rlim64_t)0, kcred, &resid)) != 0)
353 352 cmn_err(CE_WARN, "sysmsg: vn_rdwr: '%s': error %d",
354 353 path, err);
355 354 else
356 355 parse_buffer(buf, size - resid);
357 356
358 357 kmem_free(buf, size);
359 358 closevp:
360 359 (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, kcred, NULL);
361 360 VN_RELE(vp);
362 361 }
363 362
364 363 /* ARGSUSED */
365 364 static int
366 365 sysmopen(dev_t *dev, int flag, int state, cred_t *cred)
367 366 {
368 367 int i;
369 368 vnode_t *vp;
370 369 minor_t instance;
371 370 static boolean_t initialized;
372 371
373 372 instance = getminor(*dev);
374 373
375 374 if (state != OTYP_CHR || (instance != 0 && instance != 1))
376 375 return (ENXIO);
377 376
378 377 mutex_enter(&dcvp_mutex);
379 378 if ((dcvp == NULL) && (vn_open("/dev/console",
380 379 UIO_SYSSPACE, FWRITE, 0, &dcvp, 0, 0) != 0)) {
381 380 mutex_exit(&dcvp_mutex);
382 381 return (ENXIO);
383 382 }
384 383
385 384 if (instance == SYS_SYSMIN)
386 385 sysmsg_opened = B_TRUE;
387 386 else
388 387 msglog_opened = B_TRUE;
389 388
390 389 if (!initialized) {
391 390 bind_consadm_conf("/etc/consadm.conf");
392 391 initialized = B_TRUE;
393 392 }
394 393 mutex_exit(&dcvp_mutex);
395 394
396 395 for (i = 0; i < MAXDEVS; i++) {
397 396 rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
398 397 if ((sysmcache[i].dca_flags & SYSM_ENABLED) &&
399 398 sysmcache[i].dca_vp == NULL) {
400 399 /*
401 400 * 4196476 - FTRUNC was causing E10K to return EINVAL
402 401 * on open
403 402 */
404 403 flag = flag & ~FTRUNC;
405 404 /*
406 405 * Open failures on the auxiliary consoles are
407 406 * not returned because we don't care if some
408 407 * subset get an error. We know the default console
409 408 * is okay, and preserve the semantics of the
410 409 * open for the default console.
411 410 * Set NONBLOCK|NDELAY in case there's no carrier.
412 411 */
413 412 if (vn_open(sysmcache[i].dca_name, UIO_SYSSPACE,
414 413 flag | FNONBLOCK | FNDELAY, 0, &vp, 0, 0) == 0)
415 414 sysmcache[i].dca_vp = vp;
416 415 }
417 416 rw_exit(&sysmcache[i].dca_lock);
418 417 }
419 418
420 419 return (0);
421 420 }
422 421
423 422 /* ARGSUSED */
424 423 static int
425 424 sysmclose(dev_t dev, int flag, int state, cred_t *cred)
426 425 {
427 426 int i;
428 427 minor_t instance;
429 428
430 429 ASSERT(dcvp != NULL);
431 430
432 431 if (state != OTYP_CHR)
433 432 return (ENXIO);
434 433
435 434 instance = getminor(dev);
436 435
437 436 mutex_enter(&dcvp_mutex);
438 437 if (instance == SYS_SYSMIN)
439 438 sysmsg_opened = B_FALSE;
440 439 else
441 440 msglog_opened = B_FALSE;
442 441
443 442 if (sysmsg_opened || msglog_opened) {
444 443 mutex_exit(&dcvp_mutex);
445 444 return (0);
446 445 }
447 446
448 447 (void) VOP_CLOSE(dcvp, FWRITE, 1, (offset_t)0, kcred, NULL);
449 448 VN_RELE(dcvp);
450 449 dcvp = NULL;
451 450 mutex_exit(&dcvp_mutex);
452 451
453 452 /*
454 453 * Close the auxiliary consoles, we're not concerned with
455 454 * passing up the errors.
456 455 */
457 456 for (i = 0; i < MAXDEVS; i++) {
458 457 rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
459 458 if (sysmcache[i].dca_vp != NULL) {
460 459 (void) VOP_CLOSE(sysmcache[i].dca_vp, flag,
461 460 1, (offset_t)0, cred, NULL);
462 461 VN_RELE(sysmcache[i].dca_vp);
463 462 sysmcache[i].dca_vp = NULL;
464 463 }
465 464 rw_exit(&sysmcache[i].dca_lock);
466 465 }
467 466
468 467 return (0);
469 468 }
470 469
471 470 /* Reads occur only on the default console */
472 471
473 472 /* ARGSUSED */
474 473 static int
475 474 sysmread(dev_t dev, struct uio *uio, cred_t *cred)
476 475 {
477 476 ASSERT(dcvp != NULL);
478 477 return (VOP_READ(dcvp, uio, 0, cred, NULL));
479 478 }
480 479
481 480 /* ARGSUSED */
482 481 static int
483 482 sysmwrite(dev_t dev, struct uio *uio, cred_t *cred)
484 483 {
485 484 int i = 0;
486 485 iovec_t uio_iov;
487 486 struct uio tuio;
488 487
489 488 ASSERT(dcvp != NULL);
490 489 ASSERT(uio != NULL);
491 490
492 491 for (i = 0; i < MAXDEVS; i++) {
493 492 rw_enter(&sysmcache[i].dca_lock, RW_READER);
494 493 if (sysmcache[i].dca_vp != NULL &&
495 494 (sysmcache[i].dca_flags & SYSM_ENABLED)) {
496 495 tuio = *uio;
497 496 uio_iov = *(uio->uio_iov);
498 497 tuio.uio_iov = &uio_iov;
499 498 (void) VOP_WRITE(sysmcache[i].dca_vp, &tuio, 0, cred,
500 499 NULL);
501 500 }
502 501 rw_exit(&sysmcache[i].dca_lock);
503 502 }
504 503 return (VOP_WRITE(dcvp, uio, 0, cred, NULL));
505 504 }
506 505
507 506 /* ARGSUSED */
508 507 static int
509 508 sysmioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred, int *rvalp)
510 509 {
511 510 int rval = 0;
512 511 int error = 0;
513 512 size_t size = 0;
514 513 int i;
515 514 char *infop;
516 515 char found = 0;
517 516 dev_t newdevt = (dev_t)NODEV; /* because 0 == /dev/console */
518 517 vnode_t *vp;
519 518
520 519 switch (cmd) {
521 520 case CIOCGETCONSOLE:
522 521 /* Sum over the number of enabled devices */
523 522 for (i = 0; i < MAXDEVS; i++) {
524 523 if (sysmcache[i].dca_flags & SYSM_ENABLED)
525 524 /* list is space separated, followed by NULL */
526 525 size += strlen(sysmcache[i].dca_name) + 1;
527 526 }
528 527 if (size == 0)
529 528 return (0);
530 529 break;
531 530 case CIOCSETCONSOLE:
532 531 case CIOCRMCONSOLE:
533 532 size = sizeof (sysmcache[0].dca_name);
534 533 break;
535 534 case CIOCTTYCONSOLE:
536 535 {
537 536 dev_t d;
538 537 dev32_t d32;
539 538 extern dev_t rwsconsdev, rconsdev, uconsdev;
540 539 proc_t *p;
541 540
542 541 if (drv_getparm(UPROCP, &p) != 0)
543 542 return (ENODEV);
544 543 else
545 544 d = cttydev(p);
546 545 /*
547 546 * If the controlling terminal is the real
548 547 * or workstation console device, map to what the
549 548 * user thinks is the console device.
550 549 */
551 550 if (d == rwsconsdev || d == rconsdev)
552 551 d = uconsdev;
553 552 if ((flag & FMODELS) != FNATIVE) {
554 553 if (!cmpldev(&d32, d))
555 554 return (EOVERFLOW);
556 555 if (ddi_copyout(&d32, (caddr_t)arg, sizeof (d32),
557 556 flag))
558 557 return (EFAULT);
559 558 } else {
560 559 if (ddi_copyout(&d, (caddr_t)arg, sizeof (d), flag))
561 560 return (EFAULT);
562 561 }
563 562 return (0);
564 563 }
565 564 default:
566 565 /* everything else is sent to the console device */
567 566 return (VOP_IOCTL(dcvp, cmd, arg, flag, cred, rvalp, NULL));
568 567 }
569 568
570 569 if ((rval = secpolicy_console(cred)) != 0)
571 570 return (EPERM);
572 571
573 572 infop = kmem_alloc(size, KM_SLEEP);
574 573 if (flag & FKIOCTL)
575 574 error = copystr((caddr_t)arg, infop, size, NULL);
576 575 else
577 576 error = copyinstr((caddr_t)arg, infop, size, NULL);
578 577
579 578 if (error) {
580 579 switch (cmd) {
581 580 case CIOCGETCONSOLE:
582 581 /*
583 582 * If the buffer is null, then return a byte count
584 583 * to user land.
585 584 */
586 585 *rvalp = size;
587 586 goto err_exit;
588 587 default:
589 588 rval = EFAULT;
590 589 goto err_exit;
591 590 }
592 591 }
593 592
594 593 if (infop[0] != NULL) {
595 594 if ((rval = lookupname(infop, UIO_SYSSPACE, FOLLOW,
596 595 NULLVPP, &vp)) == 0) {
597 596 if (vp->v_type != VCHR) {
598 597 VN_RELE(vp);
599 598 rval = EINVAL;
600 599 goto err_exit;
601 600 }
602 601 newdevt = vp->v_rdev;
603 602 VN_RELE(vp);
604 603 } else
605 604 goto err_exit;
606 605 }
607 606
608 607 switch (cmd) {
609 608 case CIOCGETCONSOLE:
610 609 /*
611 610 * Return the list of device names that are enabled.
612 611 */
613 612 for (i = 0; i < MAXDEVS; i++) {
614 613 rw_enter(&sysmcache[i].dca_lock, RW_READER);
615 614 if (sysmcache[i].dca_flags & SYSM_ENABLED) {
616 615 if (infop[0] != NULL)
617 616 (void) strcat(infop, " ");
618 617 (void) strcat(infop, sysmcache[i].dca_name);
619 618 }
620 619 rw_exit(&sysmcache[i].dca_lock);
621 620 }
622 621 if (rval == 0 && copyoutstr(infop, (void *)arg, size, NULL))
623 622 rval = EFAULT;
624 623 break;
625 624
626 625 case CIOCSETCONSOLE:
627 626 if ((rval = checkarg(newdevt)) != 0)
628 627 break;
629 628 /*
630 629 * The device does not have to be open or disabled to
631 630 * perform the set console.
632 631 */
633 632 for (i = 0; i < MAXDEVS; i++) {
634 633 rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
635 634 if (sysmcache[i].dca_devt == newdevt &&
636 635 (sysmcache[i].dca_flags & SYSM_ENABLED)) {
637 636 (void) strcpy(sysmcache[i].dca_name, infop);
638 637 rval = EEXIST;
639 638 rw_exit(&sysmcache[i].dca_lock);
640 639 break;
641 640 } else if (sysmcache[i].dca_devt == newdevt &&
642 641 sysmcache[i].dca_flags == SYSM_DISABLED) {
643 642 sysmcache[i].dca_flags |= SYSM_ENABLED;
644 643 (void) strcpy(sysmcache[i].dca_name, infop);
645 644 rw_exit(&sysmcache[i].dca_lock);
646 645 found = 1;
647 646 break;
648 647 } else if (sysmcache[i].dca_devt == 0) {
649 648 ASSERT(sysmcache[i].dca_vp == NULL &&
650 649 sysmcache[i].dca_flags == SYSM_DISABLED);
651 650 (void) strcpy(sysmcache[i].dca_name, infop);
652 651 sysmcache[i].dca_flags = SYSM_ENABLED;
653 652 sysmcache[i].dca_devt = newdevt;
654 653 rw_exit(&sysmcache[i].dca_lock);
655 654 found = 1;
656 655 break;
657 656 }
658 657 rw_exit(&sysmcache[i].dca_lock);
659 658 }
660 659 if (found == 0 && rval == 0)
661 660 rval = ENOENT;
662 661 break;
663 662
664 663 case CIOCRMCONSOLE:
665 664 for (i = 0; i < MAXDEVS; i++) {
666 665 rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
667 666 if (sysmcache[i].dca_devt == newdevt) {
668 667 sysmcache[i].dca_flags = SYSM_DISABLED;
669 668 sysmcache[i].dca_name[0] = '\0';
670 669 rw_exit(&sysmcache[i].dca_lock);
671 670 found = 1;
672 671 break;
673 672 }
674 673 rw_exit(&sysmcache[i].dca_lock);
675 674 }
676 675 if (found == 0)
677 676 rval = ENOENT;
678 677 break;
679 678
680 679 default:
681 680 break;
682 681 }
683 682
684 683 err_exit:
685 684 kmem_free(infop, size);
686 685 return (rval);
687 686 }
688 687
689 688 /* As with the read, we poll only the default console */
690 689
691 690 /* ARGSUSED */
692 691 static int
693 692 sysmpoll(dev_t dev, short events, int anyyet, short *reventsp,
694 693 struct pollhead **phpp)
695 694 {
696 695 return (VOP_POLL(dcvp, events, anyyet, reventsp, phpp, NULL));
697 696 }
698 697
699 698 /* Sanity check that the device is good */
700 699 static int
701 700 checkarg(dev_t devt)
702 701 {
703 702 int rval = 0;
704 703 dev_t sysmsg_dev, msglog_dev;
705 704 extern dev_t rwsconsdev, rconsdev, uconsdev;
706 705
707 706 if (devt == rconsdev || devt == rwsconsdev || devt == uconsdev) {
708 707 rval = EBUSY;
709 708 } else {
710 709 sysmsg_dev = makedevice(ddi_driver_major(sysm_dip), SYS_SYSMIN);
711 710 msglog_dev = makedevice(ddi_driver_major(sysm_dip), SYS_MSGMIN);
712 711 if (devt == sysmsg_dev || devt == msglog_dev)
713 712 rval = EINVAL;
714 713 }
715 714
716 715 return (rval);
717 716 }
↓ open down ↓ |
540 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX